Skip to content

EVE SDE Schema

Documentation for third-party developers

blueprints.jsonl

Schema

  • _key (required): integer
    Range: 681 .. 88734
  • activities (required): object

    • copying: object

      • materials: array of object

        • quantity (required): integer
          Range: 1 .. 600
        • typeID (required): integer
          Range: 3812 .. 30386
      • skills: array of object

        • level (required): integer
          Range: 1 .. 5
        • typeID (required): integer
          Range: 3365 .. 81050
      • time (required): integer
        Range: 0 .. 7200000

    • invention: object

      • materials: array of object

        • quantity (required): integer
          Range: 1 .. 85
        • typeID (required): integer
          Range: 11496 .. 81051
      • products: array of object

        • probability: number
          Range: 0.14 .. 0.34
        • quantity (required): integer
          Range: 1 .. 20
        • typeID (required): integer
          Range: 784 .. 88003
      • skills: array of object

        • level (required): integer
          Range: 0 .. 1
        • typeID (required): integer
          Range: 3400 .. 81050
      • time (required): integer
        Range: 0 .. 1980000

    • manufacturing: object

      • materials: array of object

        • quantity (required): integer
          Range: 1 .. 80000000
        • typeID (required): integer
          Range: 18 .. 88087
      • products: array of object

        • quantity (required): integer
          Range: 1 .. 5000
        • typeID (required): integer
          Range: 165 .. 88721
      • skills: array of object

        • level (required): integer
          Range: 0 .. 5
        • typeID (required): integer
          Range: 3364 .. 81896
      • time (required): integer
        Range: 0 .. 10800000

    • reaction: object

      • materials (required): array of object

        • quantity (required): integer
          Range: 1 .. 10000
        • typeID (required): integer
          Range: 34 .. 57462
      • products (required): array of object

        • quantity (required): integer
          Range: 1 .. 10000
        • typeID (required): integer
          Range: 16654 .. 57469
      • skills (required): array of object

        • level (required): integer
          Range: 1 .. 5
        • typeID (required): integer
          Range: 45746 .. 45746
      • time (required): integer
        Range: 360 .. 21600

    • research_material: object

      • materials: array of object

        • quantity (required): integer
          Range: 1 .. 140
        • typeID (required): integer
          Range: 3814 .. 30386
      • skills: array of object

        • level (required): integer
          Range: 1 .. 5
        • typeID (required): integer
          Range: 3365 .. 81050
      • time (required): integer
        Range: 0 .. 420000

    • research_time: object

      • materials: array of object

        • quantity (required): integer
          Range: 1 .. 120
        • typeID (required): integer
          Range: 3814 .. 30386
      • skills: array of object

        • level (required): integer
          Range: 1 .. 5
        • typeID (required): integer
          Range: 3365 .. 81050
      • time (required): integer
        Range: 0 .. 420000

  • blueprintTypeID (required): integer
    Range: 681 .. 88734

  • maxProductionLimit (required): integer
    Range: 1 .. 1000000

Code snippets

// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
//    using QuickType;
//
//    var blueprint = Blueprint.FromJson(jsonString);

namespace QuickType
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class Blueprint
    {
        [JsonProperty("_key")]
        public long Key { get; set; }

        [JsonProperty("activities")]
        public Activities Activities { get; set; }

        [JsonProperty("blueprintTypeID")]
        public long BlueprintTypeId { get; set; }

        [JsonProperty("maxProductionLimit")]
        public long MaxProductionLimit { get; set; }
    }

    public partial class Activities
    {
        [JsonProperty("copying", NullValueHandling = NullValueHandling.Ignore)]
        public Copying Copying { get; set; }

        [JsonProperty("invention", NullValueHandling = NullValueHandling.Ignore)]
        public Invention Invention { get; set; }

        [JsonProperty("manufacturing", NullValueHandling = NullValueHandling.Ignore)]
        public Manufacturing Manufacturing { get; set; }

        [JsonProperty("reaction", NullValueHandling = NullValueHandling.Ignore)]
        public Reaction Reaction { get; set; }

        [JsonProperty("research_material", NullValueHandling = NullValueHandling.Ignore)]
        public ResearchMaterial ResearchMaterial { get; set; }

        [JsonProperty("research_time", NullValueHandling = NullValueHandling.Ignore)]
        public ResearchTime ResearchTime { get; set; }
    }

    public partial class Copying
    {
        [JsonProperty("materials", NullValueHandling = NullValueHandling.Ignore)]
        public CopyingMaterial[] Materials { get; set; }

        [JsonProperty("skills", NullValueHandling = NullValueHandling.Ignore)]
        public CopyingSkill[] Skills { get; set; }

        [JsonProperty("time")]
        public long Time { get; set; }
    }

    public partial class CopyingMaterial
    {
        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class CopyingSkill
    {
        [JsonProperty("level")]
        public long Level { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class Invention
    {
        [JsonProperty("materials", NullValueHandling = NullValueHandling.Ignore)]
        public InventionMaterial[] Materials { get; set; }

        [JsonProperty("products", NullValueHandling = NullValueHandling.Ignore)]
        public InventionProduct[] Products { get; set; }

        [JsonProperty("skills", NullValueHandling = NullValueHandling.Ignore)]
        public InventionSkill[] Skills { get; set; }

        [JsonProperty("time")]
        public long Time { get; set; }
    }

    public partial class InventionMaterial
    {
        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class InventionProduct
    {
        [JsonProperty("probability", NullValueHandling = NullValueHandling.Ignore)]
        [JsonConverter(typeof(MinMaxValueCheckConverter))]
        public double? Probability { get; set; }

        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class InventionSkill
    {
        [JsonProperty("level")]
        public long Level { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class Manufacturing
    {
        [JsonProperty("materials", NullValueHandling = NullValueHandling.Ignore)]
        public ManufacturingMaterial[] Materials { get; set; }

        [JsonProperty("products", NullValueHandling = NullValueHandling.Ignore)]
        public ManufacturingProduct[] Products { get; set; }

        [JsonProperty("skills", NullValueHandling = NullValueHandling.Ignore)]
        public ManufacturingSkill[] Skills { get; set; }

        [JsonProperty("time")]
        public long Time { get; set; }
    }

    public partial class ManufacturingMaterial
    {
        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class ManufacturingProduct
    {
        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class ManufacturingSkill
    {
        [JsonProperty("level")]
        public long Level { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class Reaction
    {
        [JsonProperty("materials")]
        public ReactionMaterial[] Materials { get; set; }

        [JsonProperty("products")]
        public ReactionProduct[] Products { get; set; }

        [JsonProperty("skills")]
        public ReactionSkill[] Skills { get; set; }

        [JsonProperty("time")]
        public long Time { get; set; }
    }

    public partial class ReactionMaterial
    {
        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class ReactionProduct
    {
        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class ReactionSkill
    {
        [JsonProperty("level")]
        public long Level { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class ResearchMaterial
    {
        [JsonProperty("materials", NullValueHandling = NullValueHandling.Ignore)]
        public ResearchMaterialMaterial[] Materials { get; set; }

        [JsonProperty("skills", NullValueHandling = NullValueHandling.Ignore)]
        public ResearchMaterialSkill[] Skills { get; set; }

        [JsonProperty("time")]
        public long Time { get; set; }
    }

    public partial class ResearchMaterialMaterial
    {
        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class ResearchMaterialSkill
    {
        [JsonProperty("level")]
        public long Level { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class ResearchTime
    {
        [JsonProperty("materials", NullValueHandling = NullValueHandling.Ignore)]
        public ResearchTimeMaterial[] Materials { get; set; }

        [JsonProperty("skills", NullValueHandling = NullValueHandling.Ignore)]
        public ResearchTimeSkill[] Skills { get; set; }

        [JsonProperty("time")]
        public long Time { get; set; }
    }

    public partial class ResearchTimeMaterial
    {
        [JsonProperty("quantity")]
        public long Quantity { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class ResearchTimeSkill
    {
        [JsonProperty("level")]
        public long Level { get; set; }

        [JsonProperty("typeID")]
        public long TypeId { get; set; }
    }

    public partial class Blueprint
    {
        public static Blueprint FromJson(string json) => JsonConvert.DeserializeObject<Blueprint>(json, QuickType.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this Blueprint self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }

    internal class MinMaxValueCheckConverter : JsonConverter
    {
        public override bool CanConvert(Type t) => t == typeof(double) || t == typeof(double?);

        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return null;
            var value = serializer.Deserialize<double>(reader);
            if (value >= 0.14 && value <= 0.34)
            {
                return value;
            }
            throw new Exception("Cannot unmarshal type double");
        }

        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
        {
            if (untypedValue == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
            var value = (double)untypedValue;
            if (value >= 0.14 && value <= 0.34)
            {
                serializer.Serialize(writer, value);
                return;
            }
            throw new Exception("Cannot marshal type double");
        }

        public static readonly MinMaxValueCheckConverter Singleton = new MinMaxValueCheckConverter();
    }
}
// Code generated from JSON Schema using quicktype. DO NOT EDIT.
// To parse and unparse this JSON data, add this code to your project and do:
//
//    blueprint, err := UnmarshalBlueprint(bytes)
//    bytes, err = blueprint.Marshal()

package model

import "encoding/json"

func UnmarshalBlueprint(data []byte) (Blueprint, error) {
    var r Blueprint
    err := json.Unmarshal(data, &r)
    return r, err
}

func (r *Blueprint) Marshal() ([]byte, error) {
    return json.Marshal(r)
}

type Blueprint struct {
    Key                int64      `json:"_key"`
    Activities         Activities `json:"activities"`
    BlueprintTypeID    int64      `json:"blueprintTypeID"`
    MaxProductionLimit int64      `json:"maxProductionLimit"`
}

type Activities struct {
    Copying          *Copying          `json:"copying,omitempty"`
    Invention        *Invention        `json:"invention,omitempty"`
    Manufacturing    *Manufacturing    `json:"manufacturing,omitempty"`
    Reaction         *Reaction         `json:"reaction,omitempty"`
    ResearchMaterial *ResearchMaterial `json:"research_material,omitempty"`
    ResearchTime     *ResearchTime     `json:"research_time,omitempty"`
}

type Copying struct {
    Materials []CopyingMaterial `json:"materials,omitempty"`
    Skills    []CopyingSkill    `json:"skills,omitempty"`
    Time      int64             `json:"time"`
}

type CopyingMaterial struct {
    Quantity int64 `json:"quantity"`
    TypeID   int64 `json:"typeID"`
}

type CopyingSkill struct {
    Level  int64 `json:"level"`
    TypeID int64 `json:"typeID"`
}

type Invention struct {
    Materials []InventionMaterial `json:"materials,omitempty"`
    Products  []InventionProduct  `json:"products,omitempty"`
    Skills    []InventionSkill    `json:"skills,omitempty"`
    Time      int64               `json:"time"`
}

type InventionMaterial struct {
    Quantity int64 `json:"quantity"`
    TypeID   int64 `json:"typeID"`
}

type InventionProduct struct {
    Probability *float64 `json:"probability,omitempty"`
    Quantity    int64    `json:"quantity"`
    TypeID      int64    `json:"typeID"`
}

type InventionSkill struct {
    Level  int64 `json:"level"`
    TypeID int64 `json:"typeID"`
}

type Manufacturing struct {
    Materials []ManufacturingMaterial `json:"materials,omitempty"`
    Products  []ManufacturingProduct  `json:"products,omitempty"`
    Skills    []ManufacturingSkill    `json:"skills,omitempty"`
    Time      int64                   `json:"time"`
}

type ManufacturingMaterial struct {
    Quantity int64 `json:"quantity"`
    TypeID   int64 `json:"typeID"`
}

type ManufacturingProduct struct {
    Quantity int64 `json:"quantity"`
    TypeID   int64 `json:"typeID"`
}

type ManufacturingSkill struct {
    Level  int64 `json:"level"`
    TypeID int64 `json:"typeID"`
}

type Reaction struct {
    Materials []ReactionMaterial `json:"materials"`
    Products  []ReactionProduct  `json:"products"`
    Skills    []ReactionSkill    `json:"skills"`
    Time      int64              `json:"time"`
}

type ReactionMaterial struct {
    Quantity int64 `json:"quantity"`
    TypeID   int64 `json:"typeID"`
}

type ReactionProduct struct {
    Quantity int64 `json:"quantity"`
    TypeID   int64 `json:"typeID"`
}

type ReactionSkill struct {
    Level  int64 `json:"level"`
    TypeID int64 `json:"typeID"`
}

type ResearchMaterial struct {
    Materials []ResearchMaterialMaterial `json:"materials,omitempty"`
    Skills    []ResearchMaterialSkill    `json:"skills,omitempty"`
    Time      int64                      `json:"time"`
}

type ResearchMaterialMaterial struct {
    Quantity int64 `json:"quantity"`
    TypeID   int64 `json:"typeID"`
}

type ResearchMaterialSkill struct {
    Level  int64 `json:"level"`
    TypeID int64 `json:"typeID"`
}

type ResearchTime struct {
    Materials []ResearchTimeMaterial `json:"materials,omitempty"`
    Skills    []ResearchTimeSkill    `json:"skills,omitempty"`
    Time      int64                  `json:"time"`
}

type ResearchTimeMaterial struct {
    Quantity int64 `json:"quantity"`
    TypeID   int64 `json:"typeID"`
}

type ResearchTimeSkill struct {
    Level  int64 `json:"level"`
    TypeID int64 `json:"typeID"`
}
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
        "_key": {
            "type": "integer",
            "minimum": 681,
            "maximum": 88734
        },
        "activities": {
            "type": "object",
            "properties": {
                "copying": {
                    "type": "object",
                    "properties": {
                        "materials": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 600
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 3812,
                                        "maximum": 30386
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 5
                        },
                        "skills": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "level": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 5
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 3365,
                                        "maximum": 81050
                                    }
                                },
                                "required": [
                                    "level",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 7
                        },
                        "time": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 7200000
                        }
                    },
                    "required": [
                        "time"
                    ]
                },
                "invention": {
                    "type": "object",
                    "properties": {
                        "materials": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 85
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 11496,
                                        "maximum": 81051
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 2,
                            "maxItems": 2
                        },
                        "products": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "probability": {
                                        "type": "number",
                                        "minimum": 0.14,
                                        "maximum": 0.34
                                    },
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 20
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 784,
                                        "maximum": 88003
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 16
                        },
                        "skills": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "level": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "maximum": 1
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 3400,
                                        "maximum": 81050
                                    }
                                },
                                "required": [
                                    "level",
                                    "typeID"
                                ]
                            },
                            "minItems": 2,
                            "maxItems": 4
                        },
                        "time": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 1980000
                        }
                    },
                    "required": [
                        "time"
                    ]
                },
                "manufacturing": {
                    "type": "object",
                    "properties": {
                        "materials": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 80000000
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 18,
                                        "maximum": 88087
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 24
                        },
                        "products": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 5000
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 165,
                                        "maximum": 88721
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 1
                        },
                        "skills": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "level": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "maximum": 5
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 3364,
                                        "maximum": 81896
                                    }
                                },
                                "required": [
                                    "level",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 5
                        },
                        "time": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 10800000
                        }
                    },
                    "required": [
                        "time"
                    ]
                },
                "reaction": {
                    "type": "object",
                    "properties": {
                        "materials": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 10000
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 34,
                                        "maximum": 57462
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 2,
                            "maxItems": 6
                        },
                        "products": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 10000
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 16654,
                                        "maximum": 57469
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 1
                        },
                        "skills": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "level": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 5
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 45746,
                                        "maximum": 45746
                                    }
                                },
                                "required": [
                                    "level",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 1
                        },
                        "time": {
                            "type": "integer",
                            "minimum": 360,
                            "maximum": 21600
                        }
                    },
                    "required": [
                        "materials",
                        "products",
                        "skills",
                        "time"
                    ]
                },
                "research_material": {
                    "type": "object",
                    "properties": {
                        "materials": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 140
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 3814,
                                        "maximum": 30386
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 4
                        },
                        "skills": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "level": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 5
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 3365,
                                        "maximum": 81050
                                    }
                                },
                                "required": [
                                    "level",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 4
                        },
                        "time": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 420000
                        }
                    },
                    "required": [
                        "time"
                    ]
                },
                "research_time": {
                    "type": "object",
                    "properties": {
                        "materials": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 120
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 3814,
                                        "maximum": 30386
                                    }
                                },
                                "required": [
                                    "quantity",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 4
                        },
                        "skills": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "level": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 5
                                    },
                                    "typeID": {
                                        "type": "integer",
                                        "minimum": 3365,
                                        "maximum": 81050
                                    }
                                },
                                "required": [
                                    "level",
                                    "typeID"
                                ]
                            },
                            "minItems": 1,
                            "maxItems": 4
                        },
                        "time": {
                            "type": "integer",
                            "minimum": 0,
                            "maximum": 420000
                        }
                    },
                    "required": [
                        "time"
                    ]
                }
            }
        },
        "blueprintTypeID": {
            "type": "integer",
            "minimum": 681,
            "maximum": 88734
        },
        "maxProductionLimit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000
        }
    },
    "required": [
        "_key",
        "activities",
        "blueprintTypeID",
        "maxProductionLimit"
    ]
}
// To parse the JSON, install kotlin's serialization plugin and do:
//
// val json      = Json { allowStructuredMapKeys = true }
// val blueprint = json.parse(Blueprint.serializer(), jsonString)

package model

import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*

@Serializable
data class Blueprint (
    @SerialName("_key")
    val key: Long,

    val activities: Activities,

    @SerialName("blueprintTypeID")
    val blueprintTypeId: Long,

    val maxProductionLimit: Long
)

@Serializable
data class Activities (
    val copying: Copying? = null,
    val invention: Invention? = null,
    val manufacturing: Manufacturing? = null,
    val reaction: Reaction? = null,

    @SerialName("research_material")
    val researchMaterial: ResearchMaterial? = null,

    @SerialName("research_time")
    val researchTime: ResearchTime? = null
)

@Serializable
data class Copying (
    val materials: List<CopyingMaterial>? = null,
    val skills: List<CopyingSkill>? = null,
    val time: Long
)

@Serializable
data class CopyingMaterial (
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class CopyingSkill (
    val level: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class Invention (
    val materials: List<InventionMaterial>? = null,
    val products: List<InventionProduct>? = null,
    val skills: List<InventionSkill>? = null,
    val time: Long
)

@Serializable
data class InventionMaterial (
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class InventionProduct (
    val probability: Double? = null,
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class InventionSkill (
    val level: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class Manufacturing (
    val materials: List<ManufacturingMaterial>? = null,
    val products: List<ManufacturingProduct>? = null,
    val skills: List<ManufacturingSkill>? = null,
    val time: Long
)

@Serializable
data class ManufacturingMaterial (
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class ManufacturingProduct (
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class ManufacturingSkill (
    val level: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class Reaction (
    val materials: List<ReactionMaterial>,
    val products: List<ReactionProduct>,
    val skills: List<ReactionSkill>,
    val time: Long
)

@Serializable
data class ReactionMaterial (
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class ReactionProduct (
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class ReactionSkill (
    val level: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class ResearchMaterial (
    val materials: List<ResearchMaterialMaterial>? = null,
    val skills: List<ResearchMaterialSkill>? = null,
    val time: Long
)

@Serializable
data class ResearchMaterialMaterial (
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class ResearchMaterialSkill (
    val level: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class ResearchTime (
    val materials: List<ResearchTimeMaterial>? = null,
    val skills: List<ResearchTimeSkill>? = null,
    val time: Long
)

@Serializable
data class ResearchTimeMaterial (
    val quantity: Long,

    @SerialName("typeID")
    val typeId: Long
)

@Serializable
data class ResearchTimeSkill (
    val level: Long,

    @SerialName("typeID")
    val typeId: Long
)
<?php

// This is a autogenerated file:Blueprint

class Blueprint {
    private int $key; // json:_key Required
    private Activities $activities; // json:activities Required
    private int $blueprintTypeId; // json:blueprintTypeID Required
    private int $maxProductionLimit; // json:maxProductionLimit Required

    /**
     * @param int $key
     * @param Activities $activities
     * @param int $blueprintTypeId
     * @param int $maxProductionLimit
     */
    public function __construct(int $key, Activities $activities, int $blueprintTypeId, int $maxProductionLimit) {
        $this->key = $key;
        $this->activities = $activities;
        $this->blueprintTypeId = $blueprintTypeId;
        $this->maxProductionLimit = $maxProductionLimit;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromKey(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toKey(): int {
        if (Blueprint::validateKey($this->key))  {
            return $this->key; /*int*/
        }
        throw new Exception('never get to this Blueprint::key');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateKey(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:Blueprint::key");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getKey(): int {
        if (Blueprint::validateKey($this->key))  {
            return $this->key;
        }
        throw new Exception('never get to getKey Blueprint::key');
    }

    /**
     * @return int
     */
    public static function sampleKey(): int {
        return 31; /*31:key*/
    }

    /**
     * @param stdClass $value
     * @throws Exception
     * @return Activities
     */
    public static function fromActivities(stdClass $value): Activities {
        return Activities::from($value); /*class*/
    }

    /**
     * @throws Exception
     * @return stdClass
     */
    public function toActivities(): stdClass {
        if (Blueprint::validateActivities($this->activities))  {
            return $this->activities->to(); /*class*/
        }
        throw new Exception('never get to this Blueprint::activities');
    }

    /**
     * @param Activities
     * @return bool
     * @throws Exception
     */
    public static function validateActivities(Activities $value): bool {
        $value->validate();
        return true;
    }

    /**
     * @throws Exception
     * @return Activities
     */
    public function getActivities(): Activities {
        if (Blueprint::validateActivities($this->activities))  {
            return $this->activities;
        }
        throw new Exception('never get to getActivities Blueprint::activities');
    }

    /**
     * @return Activities
     */
    public static function sampleActivities(): Activities {
        return Activities::sample(); /*32:activities*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromBlueprintTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toBlueprintTypeId(): int {
        if (Blueprint::validateBlueprintTypeId($this->blueprintTypeId))  {
            return $this->blueprintTypeId; /*int*/
        }
        throw new Exception('never get to this Blueprint::blueprintTypeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateBlueprintTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:Blueprint::blueprintTypeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getBlueprintTypeId(): int {
        if (Blueprint::validateBlueprintTypeId($this->blueprintTypeId))  {
            return $this->blueprintTypeId;
        }
        throw new Exception('never get to getBlueprintTypeId Blueprint::blueprintTypeId');
    }

    /**
     * @return int
     */
    public static function sampleBlueprintTypeId(): int {
        return 33; /*33:blueprintTypeId*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromMaxProductionLimit(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toMaxProductionLimit(): int {
        if (Blueprint::validateMaxProductionLimit($this->maxProductionLimit))  {
            return $this->maxProductionLimit; /*int*/
        }
        throw new Exception('never get to this Blueprint::maxProductionLimit');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateMaxProductionLimit(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:Blueprint::maxProductionLimit");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getMaxProductionLimit(): int {
        if (Blueprint::validateMaxProductionLimit($this->maxProductionLimit))  {
            return $this->maxProductionLimit;
        }
        throw new Exception('never get to getMaxProductionLimit Blueprint::maxProductionLimit');
    }

    /**
     * @return int
     */
    public static function sampleMaxProductionLimit(): int {
        return 34; /*34:maxProductionLimit*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return Blueprint::validateKey($this->key)
        || Blueprint::validateActivities($this->activities)
        || Blueprint::validateBlueprintTypeId($this->blueprintTypeId)
        || Blueprint::validateMaxProductionLimit($this->maxProductionLimit);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'_key'} = $this->toKey();
        $out->{'activities'} = $this->toActivities();
        $out->{'blueprintTypeID'} = $this->toBlueprintTypeId();
        $out->{'maxProductionLimit'} = $this->toMaxProductionLimit();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return Blueprint
     * @throws Exception
     */
    public static function from(stdClass $obj): Blueprint {
        return new Blueprint(
         Blueprint::fromKey($obj->{'_key'})
        ,Blueprint::fromActivities($obj->{'activities'})
        ,Blueprint::fromBlueprintTypeId($obj->{'blueprintTypeID'})
        ,Blueprint::fromMaxProductionLimit($obj->{'maxProductionLimit'})
        );
    }

    /**
     * @return Blueprint
     */
    public static function sample(): Blueprint {
        return new Blueprint(
         Blueprint::sampleKey()
        ,Blueprint::sampleActivities()
        ,Blueprint::sampleBlueprintTypeId()
        ,Blueprint::sampleMaxProductionLimit()
        );
    }
}

// This is a autogenerated file:Activities

class Activities {
    private ?Copying $copying; // json:copying Optional
    private ?Invention $invention; // json:invention Optional
    private ?Manufacturing $manufacturing; // json:manufacturing Optional
    private ?Reaction $reaction; // json:reaction Optional
    private ?ResearchMaterial $researchMaterial; // json:research_material Optional
    private ?ResearchTime $researchTime; // json:research_time Optional

    /**
     * @param Copying|null $copying
     * @param Invention|null $invention
     * @param Manufacturing|null $manufacturing
     * @param Reaction|null $reaction
     * @param ResearchMaterial|null $researchMaterial
     * @param ResearchTime|null $researchTime
     */
    public function __construct(?Copying $copying, ?Invention $invention, ?Manufacturing $manufacturing, ?Reaction $reaction, ?ResearchMaterial $researchMaterial, ?ResearchTime $researchTime) {
        $this->copying = $copying;
        $this->invention = $invention;
        $this->manufacturing = $manufacturing;
        $this->reaction = $reaction;
        $this->researchMaterial = $researchMaterial;
        $this->researchTime = $researchTime;
    }

    /**
     * @param ?stdClass $value
     * @throws Exception
     * @return ?Copying
     */
    public static function fromCopying(?stdClass $value): ?Copying {
        if (!is_null($value)) {
            return Copying::from($value); /*class*/
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?stdClass
     */
    public function toCopying(): ?stdClass {
        if (Activities::validateCopying($this->copying))  {
            if (!is_null($this->copying)) {
                return $this->copying->to(); /*class*/
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Activities::copying');
    }

    /**
     * @param Copying|null
     * @return bool
     * @throws Exception
     */
    public static function validateCopying(?Copying $value): bool {
        if (!is_null($value)) {
            $value->validate();
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?Copying
     */
    public function getCopying(): ?Copying {
        if (Activities::validateCopying($this->copying))  {
            return $this->copying;
        }
        throw new Exception('never get to getCopying Activities::copying');
    }

    /**
     * @return ?Copying
     */
    public static function sampleCopying(): ?Copying {
        return Copying::sample(); /*31:copying*/
    }

    /**
     * @param ?stdClass $value
     * @throws Exception
     * @return ?Invention
     */
    public static function fromInvention(?stdClass $value): ?Invention {
        if (!is_null($value)) {
            return Invention::from($value); /*class*/
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?stdClass
     */
    public function toInvention(): ?stdClass {
        if (Activities::validateInvention($this->invention))  {
            if (!is_null($this->invention)) {
                return $this->invention->to(); /*class*/
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Activities::invention');
    }

    /**
     * @param Invention|null
     * @return bool
     * @throws Exception
     */
    public static function validateInvention(?Invention $value): bool {
        if (!is_null($value)) {
            $value->validate();
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?Invention
     */
    public function getInvention(): ?Invention {
        if (Activities::validateInvention($this->invention))  {
            return $this->invention;
        }
        throw new Exception('never get to getInvention Activities::invention');
    }

    /**
     * @return ?Invention
     */
    public static function sampleInvention(): ?Invention {
        return Invention::sample(); /*32:invention*/
    }

    /**
     * @param ?stdClass $value
     * @throws Exception
     * @return ?Manufacturing
     */
    public static function fromManufacturing(?stdClass $value): ?Manufacturing {
        if (!is_null($value)) {
            return Manufacturing::from($value); /*class*/
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?stdClass
     */
    public function toManufacturing(): ?stdClass {
        if (Activities::validateManufacturing($this->manufacturing))  {
            if (!is_null($this->manufacturing)) {
                return $this->manufacturing->to(); /*class*/
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Activities::manufacturing');
    }

    /**
     * @param Manufacturing|null
     * @return bool
     * @throws Exception
     */
    public static function validateManufacturing(?Manufacturing $value): bool {
        if (!is_null($value)) {
            $value->validate();
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?Manufacturing
     */
    public function getManufacturing(): ?Manufacturing {
        if (Activities::validateManufacturing($this->manufacturing))  {
            return $this->manufacturing;
        }
        throw new Exception('never get to getManufacturing Activities::manufacturing');
    }

    /**
     * @return ?Manufacturing
     */
    public static function sampleManufacturing(): ?Manufacturing {
        return Manufacturing::sample(); /*33:manufacturing*/
    }

    /**
     * @param ?stdClass $value
     * @throws Exception
     * @return ?Reaction
     */
    public static function fromReaction(?stdClass $value): ?Reaction {
        if (!is_null($value)) {
            return Reaction::from($value); /*class*/
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?stdClass
     */
    public function toReaction(): ?stdClass {
        if (Activities::validateReaction($this->reaction))  {
            if (!is_null($this->reaction)) {
                return $this->reaction->to(); /*class*/
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Activities::reaction');
    }

    /**
     * @param Reaction|null
     * @return bool
     * @throws Exception
     */
    public static function validateReaction(?Reaction $value): bool {
        if (!is_null($value)) {
            $value->validate();
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?Reaction
     */
    public function getReaction(): ?Reaction {
        if (Activities::validateReaction($this->reaction))  {
            return $this->reaction;
        }
        throw new Exception('never get to getReaction Activities::reaction');
    }

    /**
     * @return ?Reaction
     */
    public static function sampleReaction(): ?Reaction {
        return Reaction::sample(); /*34:reaction*/
    }

    /**
     * @param ?stdClass $value
     * @throws Exception
     * @return ?ResearchMaterial
     */
    public static function fromResearchMaterial(?stdClass $value): ?ResearchMaterial {
        if (!is_null($value)) {
            return ResearchMaterial::from($value); /*class*/
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?stdClass
     */
    public function toResearchMaterial(): ?stdClass {
        if (Activities::validateResearchMaterial($this->researchMaterial))  {
            if (!is_null($this->researchMaterial)) {
                return $this->researchMaterial->to(); /*class*/
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Activities::researchMaterial');
    }

    /**
     * @param ResearchMaterial|null
     * @return bool
     * @throws Exception
     */
    public static function validateResearchMaterial(?ResearchMaterial $value): bool {
        if (!is_null($value)) {
            $value->validate();
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?ResearchMaterial
     */
    public function getResearchMaterial(): ?ResearchMaterial {
        if (Activities::validateResearchMaterial($this->researchMaterial))  {
            return $this->researchMaterial;
        }
        throw new Exception('never get to getResearchMaterial Activities::researchMaterial');
    }

    /**
     * @return ?ResearchMaterial
     */
    public static function sampleResearchMaterial(): ?ResearchMaterial {
        return ResearchMaterial::sample(); /*35:researchMaterial*/
    }

    /**
     * @param ?stdClass $value
     * @throws Exception
     * @return ?ResearchTime
     */
    public static function fromResearchTime(?stdClass $value): ?ResearchTime {
        if (!is_null($value)) {
            return ResearchTime::from($value); /*class*/
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?stdClass
     */
    public function toResearchTime(): ?stdClass {
        if (Activities::validateResearchTime($this->researchTime))  {
            if (!is_null($this->researchTime)) {
                return $this->researchTime->to(); /*class*/
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Activities::researchTime');
    }

    /**
     * @param ResearchTime|null
     * @return bool
     * @throws Exception
     */
    public static function validateResearchTime(?ResearchTime $value): bool {
        if (!is_null($value)) {
            $value->validate();
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?ResearchTime
     */
    public function getResearchTime(): ?ResearchTime {
        if (Activities::validateResearchTime($this->researchTime))  {
            return $this->researchTime;
        }
        throw new Exception('never get to getResearchTime Activities::researchTime');
    }

    /**
     * @return ?ResearchTime
     */
    public static function sampleResearchTime(): ?ResearchTime {
        return ResearchTime::sample(); /*36:researchTime*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return Activities::validateCopying($this->copying)
        || Activities::validateInvention($this->invention)
        || Activities::validateManufacturing($this->manufacturing)
        || Activities::validateReaction($this->reaction)
        || Activities::validateResearchMaterial($this->researchMaterial)
        || Activities::validateResearchTime($this->researchTime);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'copying'} = $this->toCopying();
        $out->{'invention'} = $this->toInvention();
        $out->{'manufacturing'} = $this->toManufacturing();
        $out->{'reaction'} = $this->toReaction();
        $out->{'research_material'} = $this->toResearchMaterial();
        $out->{'research_time'} = $this->toResearchTime();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return Activities
     * @throws Exception
     */
    public static function from(stdClass $obj): Activities {
        return new Activities(
         Activities::fromCopying($obj->{'copying'})
        ,Activities::fromInvention($obj->{'invention'})
        ,Activities::fromManufacturing($obj->{'manufacturing'})
        ,Activities::fromReaction($obj->{'reaction'})
        ,Activities::fromResearchMaterial($obj->{'research_material'})
        ,Activities::fromResearchTime($obj->{'research_time'})
        );
    }

    /**
     * @return Activities
     */
    public static function sample(): Activities {
        return new Activities(
         Activities::sampleCopying()
        ,Activities::sampleInvention()
        ,Activities::sampleManufacturing()
        ,Activities::sampleReaction()
        ,Activities::sampleResearchMaterial()
        ,Activities::sampleResearchTime()
        );
    }
}

// This is a autogenerated file:Copying

class Copying {
    private ?array $materials; // json:materials Optional
    private ?array $skills; // json:skills Optional
    private int $time; // json:time Required

    /**
     * @param array|null $materials
     * @param array|null $skills
     * @param int $time
     */
    public function __construct(?array $materials, ?array $skills, int $time) {
        $this->materials = $materials;
        $this->skills = $skills;
        $this->time = $time;
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromMaterials(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return CopyingMaterial::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toMaterials(): ?array {
        if (Copying::validateMaterials($this->materials))  {
            if (!is_null($this->materials)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->materials);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Copying::materials');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateMaterials(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:Copying::materials");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getMaterials(): ?array {
        if (Copying::validateMaterials($this->materials))  {
            return $this->materials;
        }
        throw new Exception('never get to getMaterials Copying::materials');
    }

    /**
     * @return ?array
     */
    public static function sampleMaterials(): ?array {
        return  array(
            CopyingMaterial::sample() /*31:*/
        ); /* 31:materials*/
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromSkills(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return CopyingSkill::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toSkills(): ?array {
        if (Copying::validateSkills($this->skills))  {
            if (!is_null($this->skills)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->skills);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Copying::skills');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateSkills(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:Copying::skills");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getSkills(): ?array {
        if (Copying::validateSkills($this->skills))  {
            return $this->skills;
        }
        throw new Exception('never get to getSkills Copying::skills');
    }

    /**
     * @return ?array
     */
    public static function sampleSkills(): ?array {
        return  array(
            CopyingSkill::sample() /*32:*/
        ); /* 32:skills*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTime(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTime(): int {
        if (Copying::validateTime($this->time))  {
            return $this->time; /*int*/
        }
        throw new Exception('never get to this Copying::time');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTime(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:Copying::time");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTime(): int {
        if (Copying::validateTime($this->time))  {
            return $this->time;
        }
        throw new Exception('never get to getTime Copying::time');
    }

    /**
     * @return int
     */
    public static function sampleTime(): int {
        return 33; /*33:time*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return Copying::validateMaterials($this->materials)
        || Copying::validateSkills($this->skills)
        || Copying::validateTime($this->time);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'materials'} = $this->toMaterials();
        $out->{'skills'} = $this->toSkills();
        $out->{'time'} = $this->toTime();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return Copying
     * @throws Exception
     */
    public static function from(stdClass $obj): Copying {
        return new Copying(
         Copying::fromMaterials($obj->{'materials'})
        ,Copying::fromSkills($obj->{'skills'})
        ,Copying::fromTime($obj->{'time'})
        );
    }

    /**
     * @return Copying
     */
    public static function sample(): Copying {
        return new Copying(
         Copying::sampleMaterials()
        ,Copying::sampleSkills()
        ,Copying::sampleTime()
        );
    }
}

// This is a autogenerated file:CopyingMaterial

class CopyingMaterial {
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(int $quantity, int $typeId) {
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (CopyingMaterial::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this CopyingMaterial::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:CopyingMaterial::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (CopyingMaterial::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity CopyingMaterial::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 31; /*31:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (CopyingMaterial::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this CopyingMaterial::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:CopyingMaterial::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (CopyingMaterial::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId CopyingMaterial::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return CopyingMaterial::validateQuantity($this->quantity)
        || CopyingMaterial::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return CopyingMaterial
     * @throws Exception
     */
    public static function from(stdClass $obj): CopyingMaterial {
        return new CopyingMaterial(
         CopyingMaterial::fromQuantity($obj->{'quantity'})
        ,CopyingMaterial::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return CopyingMaterial
     */
    public static function sample(): CopyingMaterial {
        return new CopyingMaterial(
         CopyingMaterial::sampleQuantity()
        ,CopyingMaterial::sampleTypeId()
        );
    }
}

// This is a autogenerated file:CopyingSkill

class CopyingSkill {
    private int $level; // json:level Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $level
     * @param int $typeId
     */
    public function __construct(int $level, int $typeId) {
        $this->level = $level;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromLevel(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toLevel(): int {
        if (CopyingSkill::validateLevel($this->level))  {
            return $this->level; /*int*/
        }
        throw new Exception('never get to this CopyingSkill::level');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateLevel(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:CopyingSkill::level");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getLevel(): int {
        if (CopyingSkill::validateLevel($this->level))  {
            return $this->level;
        }
        throw new Exception('never get to getLevel CopyingSkill::level');
    }

    /**
     * @return int
     */
    public static function sampleLevel(): int {
        return 31; /*31:level*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (CopyingSkill::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this CopyingSkill::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:CopyingSkill::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (CopyingSkill::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId CopyingSkill::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return CopyingSkill::validateLevel($this->level)
        || CopyingSkill::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'level'} = $this->toLevel();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return CopyingSkill
     * @throws Exception
     */
    public static function from(stdClass $obj): CopyingSkill {
        return new CopyingSkill(
         CopyingSkill::fromLevel($obj->{'level'})
        ,CopyingSkill::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return CopyingSkill
     */
    public static function sample(): CopyingSkill {
        return new CopyingSkill(
         CopyingSkill::sampleLevel()
        ,CopyingSkill::sampleTypeId()
        );
    }
}

// This is a autogenerated file:Invention

class Invention {
    private ?array $materials; // json:materials Optional
    private ?array $products; // json:products Optional
    private ?array $skills; // json:skills Optional
    private int $time; // json:time Required

    /**
     * @param array|null $materials
     * @param array|null $products
     * @param array|null $skills
     * @param int $time
     */
    public function __construct(?array $materials, ?array $products, ?array $skills, int $time) {
        $this->materials = $materials;
        $this->products = $products;
        $this->skills = $skills;
        $this->time = $time;
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromMaterials(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return InventionMaterial::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toMaterials(): ?array {
        if (Invention::validateMaterials($this->materials))  {
            if (!is_null($this->materials)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->materials);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Invention::materials');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateMaterials(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:Invention::materials");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getMaterials(): ?array {
        if (Invention::validateMaterials($this->materials))  {
            return $this->materials;
        }
        throw new Exception('never get to getMaterials Invention::materials');
    }

    /**
     * @return ?array
     */
    public static function sampleMaterials(): ?array {
        return  array(
            InventionMaterial::sample() /*31:*/
        ); /* 31:materials*/
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromProducts(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return InventionProduct::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toProducts(): ?array {
        if (Invention::validateProducts($this->products))  {
            if (!is_null($this->products)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->products);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Invention::products');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateProducts(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:Invention::products");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getProducts(): ?array {
        if (Invention::validateProducts($this->products))  {
            return $this->products;
        }
        throw new Exception('never get to getProducts Invention::products');
    }

    /**
     * @return ?array
     */
    public static function sampleProducts(): ?array {
        return  array(
            InventionProduct::sample() /*32:*/
        ); /* 32:products*/
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromSkills(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return InventionSkill::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toSkills(): ?array {
        if (Invention::validateSkills($this->skills))  {
            if (!is_null($this->skills)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->skills);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Invention::skills');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateSkills(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:Invention::skills");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getSkills(): ?array {
        if (Invention::validateSkills($this->skills))  {
            return $this->skills;
        }
        throw new Exception('never get to getSkills Invention::skills');
    }

    /**
     * @return ?array
     */
    public static function sampleSkills(): ?array {
        return  array(
            InventionSkill::sample() /*33:*/
        ); /* 33:skills*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTime(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTime(): int {
        if (Invention::validateTime($this->time))  {
            return $this->time; /*int*/
        }
        throw new Exception('never get to this Invention::time');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTime(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:Invention::time");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTime(): int {
        if (Invention::validateTime($this->time))  {
            return $this->time;
        }
        throw new Exception('never get to getTime Invention::time');
    }

    /**
     * @return int
     */
    public static function sampleTime(): int {
        return 34; /*34:time*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return Invention::validateMaterials($this->materials)
        || Invention::validateProducts($this->products)
        || Invention::validateSkills($this->skills)
        || Invention::validateTime($this->time);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'materials'} = $this->toMaterials();
        $out->{'products'} = $this->toProducts();
        $out->{'skills'} = $this->toSkills();
        $out->{'time'} = $this->toTime();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return Invention
     * @throws Exception
     */
    public static function from(stdClass $obj): Invention {
        return new Invention(
         Invention::fromMaterials($obj->{'materials'})
        ,Invention::fromProducts($obj->{'products'})
        ,Invention::fromSkills($obj->{'skills'})
        ,Invention::fromTime($obj->{'time'})
        );
    }

    /**
     * @return Invention
     */
    public static function sample(): Invention {
        return new Invention(
         Invention::sampleMaterials()
        ,Invention::sampleProducts()
        ,Invention::sampleSkills()
        ,Invention::sampleTime()
        );
    }
}

// This is a autogenerated file:InventionMaterial

class InventionMaterial {
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(int $quantity, int $typeId) {
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (InventionMaterial::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this InventionMaterial::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:InventionMaterial::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (InventionMaterial::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity InventionMaterial::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 31; /*31:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (InventionMaterial::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this InventionMaterial::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:InventionMaterial::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (InventionMaterial::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId InventionMaterial::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return InventionMaterial::validateQuantity($this->quantity)
        || InventionMaterial::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return InventionMaterial
     * @throws Exception
     */
    public static function from(stdClass $obj): InventionMaterial {
        return new InventionMaterial(
         InventionMaterial::fromQuantity($obj->{'quantity'})
        ,InventionMaterial::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return InventionMaterial
     */
    public static function sample(): InventionMaterial {
        return new InventionMaterial(
         InventionMaterial::sampleQuantity()
        ,InventionMaterial::sampleTypeId()
        );
    }
}

// This is a autogenerated file:InventionProduct

class InventionProduct {
    private ?float $probability; // json:probability Optional
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param float|null $probability
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(?float $probability, int $quantity, int $typeId) {
        $this->probability = $probability;
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param ?float $value
     * @throws Exception
     * @return ?float
     */
    public static function fromProbability(?float $value): ?float {
        if (!is_null($value)) {
            return $value; /*float*/
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?float
     */
    public function toProbability(): ?float {
        if (InventionProduct::validateProbability($this->probability))  {
            if (!is_null($this->probability)) {
                return $this->probability; /*float*/
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this InventionProduct::probability');
    }

    /**
     * @param float|null
     * @return bool
     * @throws Exception
     */
    public static function validateProbability(?float $value): bool {
        if (!is_null($value)) {
            if (!is_float($value)) {
                throw new Exception("Attribute Error:InventionProduct::probability");
            }
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?float
     */
    public function getProbability(): ?float {
        if (InventionProduct::validateProbability($this->probability))  {
            return $this->probability;
        }
        throw new Exception('never get to getProbability InventionProduct::probability');
    }

    /**
     * @return ?float
     */
    public static function sampleProbability(): ?float {
        return 31.031; /*31:probability*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (InventionProduct::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this InventionProduct::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:InventionProduct::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (InventionProduct::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity InventionProduct::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 32; /*32:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (InventionProduct::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this InventionProduct::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:InventionProduct::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (InventionProduct::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId InventionProduct::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 33; /*33:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return InventionProduct::validateProbability($this->probability)
        || InventionProduct::validateQuantity($this->quantity)
        || InventionProduct::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'probability'} = $this->toProbability();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return InventionProduct
     * @throws Exception
     */
    public static function from(stdClass $obj): InventionProduct {
        return new InventionProduct(
         InventionProduct::fromProbability($obj->{'probability'})
        ,InventionProduct::fromQuantity($obj->{'quantity'})
        ,InventionProduct::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return InventionProduct
     */
    public static function sample(): InventionProduct {
        return new InventionProduct(
         InventionProduct::sampleProbability()
        ,InventionProduct::sampleQuantity()
        ,InventionProduct::sampleTypeId()
        );
    }
}

// This is a autogenerated file:InventionSkill

class InventionSkill {
    private int $level; // json:level Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $level
     * @param int $typeId
     */
    public function __construct(int $level, int $typeId) {
        $this->level = $level;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromLevel(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toLevel(): int {
        if (InventionSkill::validateLevel($this->level))  {
            return $this->level; /*int*/
        }
        throw new Exception('never get to this InventionSkill::level');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateLevel(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:InventionSkill::level");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getLevel(): int {
        if (InventionSkill::validateLevel($this->level))  {
            return $this->level;
        }
        throw new Exception('never get to getLevel InventionSkill::level');
    }

    /**
     * @return int
     */
    public static function sampleLevel(): int {
        return 31; /*31:level*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (InventionSkill::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this InventionSkill::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:InventionSkill::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (InventionSkill::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId InventionSkill::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return InventionSkill::validateLevel($this->level)
        || InventionSkill::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'level'} = $this->toLevel();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return InventionSkill
     * @throws Exception
     */
    public static function from(stdClass $obj): InventionSkill {
        return new InventionSkill(
         InventionSkill::fromLevel($obj->{'level'})
        ,InventionSkill::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return InventionSkill
     */
    public static function sample(): InventionSkill {
        return new InventionSkill(
         InventionSkill::sampleLevel()
        ,InventionSkill::sampleTypeId()
        );
    }
}

// This is a autogenerated file:Manufacturing

class Manufacturing {
    private ?array $materials; // json:materials Optional
    private ?array $products; // json:products Optional
    private ?array $skills; // json:skills Optional
    private int $time; // json:time Required

    /**
     * @param array|null $materials
     * @param array|null $products
     * @param array|null $skills
     * @param int $time
     */
    public function __construct(?array $materials, ?array $products, ?array $skills, int $time) {
        $this->materials = $materials;
        $this->products = $products;
        $this->skills = $skills;
        $this->time = $time;
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromMaterials(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return ManufacturingMaterial::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toMaterials(): ?array {
        if (Manufacturing::validateMaterials($this->materials))  {
            if (!is_null($this->materials)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->materials);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Manufacturing::materials');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateMaterials(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:Manufacturing::materials");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getMaterials(): ?array {
        if (Manufacturing::validateMaterials($this->materials))  {
            return $this->materials;
        }
        throw new Exception('never get to getMaterials Manufacturing::materials');
    }

    /**
     * @return ?array
     */
    public static function sampleMaterials(): ?array {
        return  array(
            ManufacturingMaterial::sample() /*31:*/
        ); /* 31:materials*/
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromProducts(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return ManufacturingProduct::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toProducts(): ?array {
        if (Manufacturing::validateProducts($this->products))  {
            if (!is_null($this->products)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->products);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Manufacturing::products');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateProducts(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:Manufacturing::products");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getProducts(): ?array {
        if (Manufacturing::validateProducts($this->products))  {
            return $this->products;
        }
        throw new Exception('never get to getProducts Manufacturing::products');
    }

    /**
     * @return ?array
     */
    public static function sampleProducts(): ?array {
        return  array(
            ManufacturingProduct::sample() /*32:*/
        ); /* 32:products*/
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromSkills(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return ManufacturingSkill::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toSkills(): ?array {
        if (Manufacturing::validateSkills($this->skills))  {
            if (!is_null($this->skills)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->skills);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this Manufacturing::skills');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateSkills(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:Manufacturing::skills");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getSkills(): ?array {
        if (Manufacturing::validateSkills($this->skills))  {
            return $this->skills;
        }
        throw new Exception('never get to getSkills Manufacturing::skills');
    }

    /**
     * @return ?array
     */
    public static function sampleSkills(): ?array {
        return  array(
            ManufacturingSkill::sample() /*33:*/
        ); /* 33:skills*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTime(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTime(): int {
        if (Manufacturing::validateTime($this->time))  {
            return $this->time; /*int*/
        }
        throw new Exception('never get to this Manufacturing::time');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTime(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:Manufacturing::time");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTime(): int {
        if (Manufacturing::validateTime($this->time))  {
            return $this->time;
        }
        throw new Exception('never get to getTime Manufacturing::time');
    }

    /**
     * @return int
     */
    public static function sampleTime(): int {
        return 34; /*34:time*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return Manufacturing::validateMaterials($this->materials)
        || Manufacturing::validateProducts($this->products)
        || Manufacturing::validateSkills($this->skills)
        || Manufacturing::validateTime($this->time);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'materials'} = $this->toMaterials();
        $out->{'products'} = $this->toProducts();
        $out->{'skills'} = $this->toSkills();
        $out->{'time'} = $this->toTime();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return Manufacturing
     * @throws Exception
     */
    public static function from(stdClass $obj): Manufacturing {
        return new Manufacturing(
         Manufacturing::fromMaterials($obj->{'materials'})
        ,Manufacturing::fromProducts($obj->{'products'})
        ,Manufacturing::fromSkills($obj->{'skills'})
        ,Manufacturing::fromTime($obj->{'time'})
        );
    }

    /**
     * @return Manufacturing
     */
    public static function sample(): Manufacturing {
        return new Manufacturing(
         Manufacturing::sampleMaterials()
        ,Manufacturing::sampleProducts()
        ,Manufacturing::sampleSkills()
        ,Manufacturing::sampleTime()
        );
    }
}

// This is a autogenerated file:ManufacturingMaterial

class ManufacturingMaterial {
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(int $quantity, int $typeId) {
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (ManufacturingMaterial::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this ManufacturingMaterial::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ManufacturingMaterial::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (ManufacturingMaterial::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity ManufacturingMaterial::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 31; /*31:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ManufacturingMaterial::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ManufacturingMaterial::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ManufacturingMaterial::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ManufacturingMaterial::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ManufacturingMaterial::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ManufacturingMaterial::validateQuantity($this->quantity)
        || ManufacturingMaterial::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ManufacturingMaterial
     * @throws Exception
     */
    public static function from(stdClass $obj): ManufacturingMaterial {
        return new ManufacturingMaterial(
         ManufacturingMaterial::fromQuantity($obj->{'quantity'})
        ,ManufacturingMaterial::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ManufacturingMaterial
     */
    public static function sample(): ManufacturingMaterial {
        return new ManufacturingMaterial(
         ManufacturingMaterial::sampleQuantity()
        ,ManufacturingMaterial::sampleTypeId()
        );
    }
}

// This is a autogenerated file:ManufacturingProduct

class ManufacturingProduct {
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(int $quantity, int $typeId) {
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (ManufacturingProduct::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this ManufacturingProduct::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ManufacturingProduct::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (ManufacturingProduct::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity ManufacturingProduct::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 31; /*31:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ManufacturingProduct::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ManufacturingProduct::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ManufacturingProduct::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ManufacturingProduct::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ManufacturingProduct::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ManufacturingProduct::validateQuantity($this->quantity)
        || ManufacturingProduct::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ManufacturingProduct
     * @throws Exception
     */
    public static function from(stdClass $obj): ManufacturingProduct {
        return new ManufacturingProduct(
         ManufacturingProduct::fromQuantity($obj->{'quantity'})
        ,ManufacturingProduct::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ManufacturingProduct
     */
    public static function sample(): ManufacturingProduct {
        return new ManufacturingProduct(
         ManufacturingProduct::sampleQuantity()
        ,ManufacturingProduct::sampleTypeId()
        );
    }
}

// This is a autogenerated file:ManufacturingSkill

class ManufacturingSkill {
    private int $level; // json:level Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $level
     * @param int $typeId
     */
    public function __construct(int $level, int $typeId) {
        $this->level = $level;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromLevel(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toLevel(): int {
        if (ManufacturingSkill::validateLevel($this->level))  {
            return $this->level; /*int*/
        }
        throw new Exception('never get to this ManufacturingSkill::level');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateLevel(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ManufacturingSkill::level");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getLevel(): int {
        if (ManufacturingSkill::validateLevel($this->level))  {
            return $this->level;
        }
        throw new Exception('never get to getLevel ManufacturingSkill::level');
    }

    /**
     * @return int
     */
    public static function sampleLevel(): int {
        return 31; /*31:level*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ManufacturingSkill::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ManufacturingSkill::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ManufacturingSkill::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ManufacturingSkill::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ManufacturingSkill::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ManufacturingSkill::validateLevel($this->level)
        || ManufacturingSkill::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'level'} = $this->toLevel();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ManufacturingSkill
     * @throws Exception
     */
    public static function from(stdClass $obj): ManufacturingSkill {
        return new ManufacturingSkill(
         ManufacturingSkill::fromLevel($obj->{'level'})
        ,ManufacturingSkill::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ManufacturingSkill
     */
    public static function sample(): ManufacturingSkill {
        return new ManufacturingSkill(
         ManufacturingSkill::sampleLevel()
        ,ManufacturingSkill::sampleTypeId()
        );
    }
}

// This is a autogenerated file:Reaction

class Reaction {
    private array $materials; // json:materials Required
    private array $products; // json:products Required
    private array $skills; // json:skills Required
    private int $time; // json:time Required

    /**
     * @param array $materials
     * @param array $products
     * @param array $skills
     * @param int $time
     */
    public function __construct(array $materials, array $products, array $skills, int $time) {
        $this->materials = $materials;
        $this->products = $products;
        $this->skills = $skills;
        $this->time = $time;
    }

    /**
     * @param array $value
     * @throws Exception
     * @return array
     */
    public static function fromMaterials(array $value): array {
        return  array_map(function ($value) {
            return ReactionMaterial::from($value); /*class*/
        }, $value);
    }

    /**
     * @throws Exception
     * @return array
     */
    public function toMaterials(): array {
        if (Reaction::validateMaterials($this->materials))  {
            return array_map(function ($value) {
                return $value->to(); /*class*/
            }, $this->materials);
        }
        throw new Exception('never get to this Reaction::materials');
    }

    /**
     * @param array
     * @return bool
     * @throws Exception
     */
    public static function validateMaterials(array $value): bool {
        if (!is_array($value)) {
            throw new Exception("Attribute Error:Reaction::materials");
        }
        array_walk($value, function($value_v) {
            $value_v->validate();
        });
        return true;
    }

    /**
     * @throws Exception
     * @return array
     */
    public function getMaterials(): array {
        if (Reaction::validateMaterials($this->materials))  {
            return $this->materials;
        }
        throw new Exception('never get to getMaterials Reaction::materials');
    }

    /**
     * @return array
     */
    public static function sampleMaterials(): array {
        return  array(
            ReactionMaterial::sample() /*31:*/
        ); /* 31:materials*/
    }

    /**
     * @param array $value
     * @throws Exception
     * @return array
     */
    public static function fromProducts(array $value): array {
        return  array_map(function ($value) {
            return ReactionProduct::from($value); /*class*/
        }, $value);
    }

    /**
     * @throws Exception
     * @return array
     */
    public function toProducts(): array {
        if (Reaction::validateProducts($this->products))  {
            return array_map(function ($value) {
                return $value->to(); /*class*/
            }, $this->products);
        }
        throw new Exception('never get to this Reaction::products');
    }

    /**
     * @param array
     * @return bool
     * @throws Exception
     */
    public static function validateProducts(array $value): bool {
        if (!is_array($value)) {
            throw new Exception("Attribute Error:Reaction::products");
        }
        array_walk($value, function($value_v) {
            $value_v->validate();
        });
        return true;
    }

    /**
     * @throws Exception
     * @return array
     */
    public function getProducts(): array {
        if (Reaction::validateProducts($this->products))  {
            return $this->products;
        }
        throw new Exception('never get to getProducts Reaction::products');
    }

    /**
     * @return array
     */
    public static function sampleProducts(): array {
        return  array(
            ReactionProduct::sample() /*32:*/
        ); /* 32:products*/
    }

    /**
     * @param array $value
     * @throws Exception
     * @return array
     */
    public static function fromSkills(array $value): array {
        return  array_map(function ($value) {
            return ReactionSkill::from($value); /*class*/
        }, $value);
    }

    /**
     * @throws Exception
     * @return array
     */
    public function toSkills(): array {
        if (Reaction::validateSkills($this->skills))  {
            return array_map(function ($value) {
                return $value->to(); /*class*/
            }, $this->skills);
        }
        throw new Exception('never get to this Reaction::skills');
    }

    /**
     * @param array
     * @return bool
     * @throws Exception
     */
    public static function validateSkills(array $value): bool {
        if (!is_array($value)) {
            throw new Exception("Attribute Error:Reaction::skills");
        }
        array_walk($value, function($value_v) {
            $value_v->validate();
        });
        return true;
    }

    /**
     * @throws Exception
     * @return array
     */
    public function getSkills(): array {
        if (Reaction::validateSkills($this->skills))  {
            return $this->skills;
        }
        throw new Exception('never get to getSkills Reaction::skills');
    }

    /**
     * @return array
     */
    public static function sampleSkills(): array {
        return  array(
            ReactionSkill::sample() /*33:*/
        ); /* 33:skills*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTime(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTime(): int {
        if (Reaction::validateTime($this->time))  {
            return $this->time; /*int*/
        }
        throw new Exception('never get to this Reaction::time');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTime(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:Reaction::time");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTime(): int {
        if (Reaction::validateTime($this->time))  {
            return $this->time;
        }
        throw new Exception('never get to getTime Reaction::time');
    }

    /**
     * @return int
     */
    public static function sampleTime(): int {
        return 34; /*34:time*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return Reaction::validateMaterials($this->materials)
        || Reaction::validateProducts($this->products)
        || Reaction::validateSkills($this->skills)
        || Reaction::validateTime($this->time);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'materials'} = $this->toMaterials();
        $out->{'products'} = $this->toProducts();
        $out->{'skills'} = $this->toSkills();
        $out->{'time'} = $this->toTime();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return Reaction
     * @throws Exception
     */
    public static function from(stdClass $obj): Reaction {
        return new Reaction(
         Reaction::fromMaterials($obj->{'materials'})
        ,Reaction::fromProducts($obj->{'products'})
        ,Reaction::fromSkills($obj->{'skills'})
        ,Reaction::fromTime($obj->{'time'})
        );
    }

    /**
     * @return Reaction
     */
    public static function sample(): Reaction {
        return new Reaction(
         Reaction::sampleMaterials()
        ,Reaction::sampleProducts()
        ,Reaction::sampleSkills()
        ,Reaction::sampleTime()
        );
    }
}

// This is a autogenerated file:ReactionMaterial

class ReactionMaterial {
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(int $quantity, int $typeId) {
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (ReactionMaterial::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this ReactionMaterial::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ReactionMaterial::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (ReactionMaterial::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity ReactionMaterial::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 31; /*31:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ReactionMaterial::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ReactionMaterial::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ReactionMaterial::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ReactionMaterial::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ReactionMaterial::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ReactionMaterial::validateQuantity($this->quantity)
        || ReactionMaterial::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ReactionMaterial
     * @throws Exception
     */
    public static function from(stdClass $obj): ReactionMaterial {
        return new ReactionMaterial(
         ReactionMaterial::fromQuantity($obj->{'quantity'})
        ,ReactionMaterial::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ReactionMaterial
     */
    public static function sample(): ReactionMaterial {
        return new ReactionMaterial(
         ReactionMaterial::sampleQuantity()
        ,ReactionMaterial::sampleTypeId()
        );
    }
}

// This is a autogenerated file:ReactionProduct

class ReactionProduct {
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(int $quantity, int $typeId) {
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (ReactionProduct::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this ReactionProduct::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ReactionProduct::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (ReactionProduct::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity ReactionProduct::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 31; /*31:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ReactionProduct::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ReactionProduct::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ReactionProduct::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ReactionProduct::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ReactionProduct::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ReactionProduct::validateQuantity($this->quantity)
        || ReactionProduct::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ReactionProduct
     * @throws Exception
     */
    public static function from(stdClass $obj): ReactionProduct {
        return new ReactionProduct(
         ReactionProduct::fromQuantity($obj->{'quantity'})
        ,ReactionProduct::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ReactionProduct
     */
    public static function sample(): ReactionProduct {
        return new ReactionProduct(
         ReactionProduct::sampleQuantity()
        ,ReactionProduct::sampleTypeId()
        );
    }
}

// This is a autogenerated file:ReactionSkill

class ReactionSkill {
    private int $level; // json:level Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $level
     * @param int $typeId
     */
    public function __construct(int $level, int $typeId) {
        $this->level = $level;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromLevel(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toLevel(): int {
        if (ReactionSkill::validateLevel($this->level))  {
            return $this->level; /*int*/
        }
        throw new Exception('never get to this ReactionSkill::level');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateLevel(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ReactionSkill::level");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getLevel(): int {
        if (ReactionSkill::validateLevel($this->level))  {
            return $this->level;
        }
        throw new Exception('never get to getLevel ReactionSkill::level');
    }

    /**
     * @return int
     */
    public static function sampleLevel(): int {
        return 31; /*31:level*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ReactionSkill::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ReactionSkill::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ReactionSkill::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ReactionSkill::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ReactionSkill::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ReactionSkill::validateLevel($this->level)
        || ReactionSkill::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'level'} = $this->toLevel();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ReactionSkill
     * @throws Exception
     */
    public static function from(stdClass $obj): ReactionSkill {
        return new ReactionSkill(
         ReactionSkill::fromLevel($obj->{'level'})
        ,ReactionSkill::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ReactionSkill
     */
    public static function sample(): ReactionSkill {
        return new ReactionSkill(
         ReactionSkill::sampleLevel()
        ,ReactionSkill::sampleTypeId()
        );
    }
}

// This is a autogenerated file:ResearchMaterial

class ResearchMaterial {
    private ?array $materials; // json:materials Optional
    private ?array $skills; // json:skills Optional
    private int $time; // json:time Required

    /**
     * @param array|null $materials
     * @param array|null $skills
     * @param int $time
     */
    public function __construct(?array $materials, ?array $skills, int $time) {
        $this->materials = $materials;
        $this->skills = $skills;
        $this->time = $time;
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromMaterials(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return ResearchMaterialMaterial::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toMaterials(): ?array {
        if (ResearchMaterial::validateMaterials($this->materials))  {
            if (!is_null($this->materials)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->materials);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this ResearchMaterial::materials');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateMaterials(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:ResearchMaterial::materials");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getMaterials(): ?array {
        if (ResearchMaterial::validateMaterials($this->materials))  {
            return $this->materials;
        }
        throw new Exception('never get to getMaterials ResearchMaterial::materials');
    }

    /**
     * @return ?array
     */
    public static function sampleMaterials(): ?array {
        return  array(
            ResearchMaterialMaterial::sample() /*31:*/
        ); /* 31:materials*/
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromSkills(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return ResearchMaterialSkill::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toSkills(): ?array {
        if (ResearchMaterial::validateSkills($this->skills))  {
            if (!is_null($this->skills)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->skills);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this ResearchMaterial::skills');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateSkills(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:ResearchMaterial::skills");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getSkills(): ?array {
        if (ResearchMaterial::validateSkills($this->skills))  {
            return $this->skills;
        }
        throw new Exception('never get to getSkills ResearchMaterial::skills');
    }

    /**
     * @return ?array
     */
    public static function sampleSkills(): ?array {
        return  array(
            ResearchMaterialSkill::sample() /*32:*/
        ); /* 32:skills*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTime(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTime(): int {
        if (ResearchMaterial::validateTime($this->time))  {
            return $this->time; /*int*/
        }
        throw new Exception('never get to this ResearchMaterial::time');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTime(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchMaterial::time");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTime(): int {
        if (ResearchMaterial::validateTime($this->time))  {
            return $this->time;
        }
        throw new Exception('never get to getTime ResearchMaterial::time');
    }

    /**
     * @return int
     */
    public static function sampleTime(): int {
        return 33; /*33:time*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ResearchMaterial::validateMaterials($this->materials)
        || ResearchMaterial::validateSkills($this->skills)
        || ResearchMaterial::validateTime($this->time);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'materials'} = $this->toMaterials();
        $out->{'skills'} = $this->toSkills();
        $out->{'time'} = $this->toTime();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ResearchMaterial
     * @throws Exception
     */
    public static function from(stdClass $obj): ResearchMaterial {
        return new ResearchMaterial(
         ResearchMaterial::fromMaterials($obj->{'materials'})
        ,ResearchMaterial::fromSkills($obj->{'skills'})
        ,ResearchMaterial::fromTime($obj->{'time'})
        );
    }

    /**
     * @return ResearchMaterial
     */
    public static function sample(): ResearchMaterial {
        return new ResearchMaterial(
         ResearchMaterial::sampleMaterials()
        ,ResearchMaterial::sampleSkills()
        ,ResearchMaterial::sampleTime()
        );
    }
}

// This is a autogenerated file:ResearchMaterialMaterial

class ResearchMaterialMaterial {
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(int $quantity, int $typeId) {
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (ResearchMaterialMaterial::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this ResearchMaterialMaterial::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchMaterialMaterial::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (ResearchMaterialMaterial::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity ResearchMaterialMaterial::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 31; /*31:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ResearchMaterialMaterial::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ResearchMaterialMaterial::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchMaterialMaterial::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ResearchMaterialMaterial::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ResearchMaterialMaterial::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ResearchMaterialMaterial::validateQuantity($this->quantity)
        || ResearchMaterialMaterial::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ResearchMaterialMaterial
     * @throws Exception
     */
    public static function from(stdClass $obj): ResearchMaterialMaterial {
        return new ResearchMaterialMaterial(
         ResearchMaterialMaterial::fromQuantity($obj->{'quantity'})
        ,ResearchMaterialMaterial::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ResearchMaterialMaterial
     */
    public static function sample(): ResearchMaterialMaterial {
        return new ResearchMaterialMaterial(
         ResearchMaterialMaterial::sampleQuantity()
        ,ResearchMaterialMaterial::sampleTypeId()
        );
    }
}

// This is a autogenerated file:ResearchMaterialSkill

class ResearchMaterialSkill {
    private int $level; // json:level Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $level
     * @param int $typeId
     */
    public function __construct(int $level, int $typeId) {
        $this->level = $level;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromLevel(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toLevel(): int {
        if (ResearchMaterialSkill::validateLevel($this->level))  {
            return $this->level; /*int*/
        }
        throw new Exception('never get to this ResearchMaterialSkill::level');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateLevel(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchMaterialSkill::level");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getLevel(): int {
        if (ResearchMaterialSkill::validateLevel($this->level))  {
            return $this->level;
        }
        throw new Exception('never get to getLevel ResearchMaterialSkill::level');
    }

    /**
     * @return int
     */
    public static function sampleLevel(): int {
        return 31; /*31:level*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ResearchMaterialSkill::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ResearchMaterialSkill::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchMaterialSkill::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ResearchMaterialSkill::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ResearchMaterialSkill::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ResearchMaterialSkill::validateLevel($this->level)
        || ResearchMaterialSkill::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'level'} = $this->toLevel();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ResearchMaterialSkill
     * @throws Exception
     */
    public static function from(stdClass $obj): ResearchMaterialSkill {
        return new ResearchMaterialSkill(
         ResearchMaterialSkill::fromLevel($obj->{'level'})
        ,ResearchMaterialSkill::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ResearchMaterialSkill
     */
    public static function sample(): ResearchMaterialSkill {
        return new ResearchMaterialSkill(
         ResearchMaterialSkill::sampleLevel()
        ,ResearchMaterialSkill::sampleTypeId()
        );
    }
}

// This is a autogenerated file:ResearchTime

class ResearchTime {
    private ?array $materials; // json:materials Optional
    private ?array $skills; // json:skills Optional
    private int $time; // json:time Required

    /**
     * @param array|null $materials
     * @param array|null $skills
     * @param int $time
     */
    public function __construct(?array $materials, ?array $skills, int $time) {
        $this->materials = $materials;
        $this->skills = $skills;
        $this->time = $time;
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromMaterials(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return ResearchTimeMaterial::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toMaterials(): ?array {
        if (ResearchTime::validateMaterials($this->materials))  {
            if (!is_null($this->materials)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->materials);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this ResearchTime::materials');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateMaterials(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:ResearchTime::materials");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getMaterials(): ?array {
        if (ResearchTime::validateMaterials($this->materials))  {
            return $this->materials;
        }
        throw new Exception('never get to getMaterials ResearchTime::materials');
    }

    /**
     * @return ?array
     */
    public static function sampleMaterials(): ?array {
        return  array(
            ResearchTimeMaterial::sample() /*31:*/
        ); /* 31:materials*/
    }

    /**
     * @param ?array $value
     * @throws Exception
     * @return ?array
     */
    public static function fromSkills(?array $value): ?array {
        if (!is_null($value)) {
            return  array_map(function ($value) {
                return ResearchTimeSkill::from($value); /*class*/
            }, $value);
        } else {
            return null;
        }
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function toSkills(): ?array {
        if (ResearchTime::validateSkills($this->skills))  {
            if (!is_null($this->skills)) {
                return array_map(function ($value) {
                    return $value->to(); /*class*/
                }, $this->skills);
            } else {
                return  null;
            }
        }
        throw new Exception('never get to this ResearchTime::skills');
    }

    /**
     * @param array|null
     * @return bool
     * @throws Exception
     */
    public static function validateSkills(?array $value): bool {
        if (!is_null($value)) {
            if (!is_array($value)) {
                throw new Exception("Attribute Error:ResearchTime::skills");
            }
            array_walk($value, function($value_v) {
                $value_v->validate();
            });
        }
        return true;
    }

    /**
     * @throws Exception
     * @return ?array
     */
    public function getSkills(): ?array {
        if (ResearchTime::validateSkills($this->skills))  {
            return $this->skills;
        }
        throw new Exception('never get to getSkills ResearchTime::skills');
    }

    /**
     * @return ?array
     */
    public static function sampleSkills(): ?array {
        return  array(
            ResearchTimeSkill::sample() /*32:*/
        ); /* 32:skills*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTime(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTime(): int {
        if (ResearchTime::validateTime($this->time))  {
            return $this->time; /*int*/
        }
        throw new Exception('never get to this ResearchTime::time');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTime(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchTime::time");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTime(): int {
        if (ResearchTime::validateTime($this->time))  {
            return $this->time;
        }
        throw new Exception('never get to getTime ResearchTime::time');
    }

    /**
     * @return int
     */
    public static function sampleTime(): int {
        return 33; /*33:time*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ResearchTime::validateMaterials($this->materials)
        || ResearchTime::validateSkills($this->skills)
        || ResearchTime::validateTime($this->time);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'materials'} = $this->toMaterials();
        $out->{'skills'} = $this->toSkills();
        $out->{'time'} = $this->toTime();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ResearchTime
     * @throws Exception
     */
    public static function from(stdClass $obj): ResearchTime {
        return new ResearchTime(
         ResearchTime::fromMaterials($obj->{'materials'})
        ,ResearchTime::fromSkills($obj->{'skills'})
        ,ResearchTime::fromTime($obj->{'time'})
        );
    }

    /**
     * @return ResearchTime
     */
    public static function sample(): ResearchTime {
        return new ResearchTime(
         ResearchTime::sampleMaterials()
        ,ResearchTime::sampleSkills()
        ,ResearchTime::sampleTime()
        );
    }
}

// This is a autogenerated file:ResearchTimeMaterial

class ResearchTimeMaterial {
    private int $quantity; // json:quantity Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $quantity
     * @param int $typeId
     */
    public function __construct(int $quantity, int $typeId) {
        $this->quantity = $quantity;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromQuantity(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toQuantity(): int {
        if (ResearchTimeMaterial::validateQuantity($this->quantity))  {
            return $this->quantity; /*int*/
        }
        throw new Exception('never get to this ResearchTimeMaterial::quantity');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateQuantity(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchTimeMaterial::quantity");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getQuantity(): int {
        if (ResearchTimeMaterial::validateQuantity($this->quantity))  {
            return $this->quantity;
        }
        throw new Exception('never get to getQuantity ResearchTimeMaterial::quantity');
    }

    /**
     * @return int
     */
    public static function sampleQuantity(): int {
        return 31; /*31:quantity*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ResearchTimeMaterial::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ResearchTimeMaterial::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchTimeMaterial::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ResearchTimeMaterial::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ResearchTimeMaterial::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ResearchTimeMaterial::validateQuantity($this->quantity)
        || ResearchTimeMaterial::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'quantity'} = $this->toQuantity();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ResearchTimeMaterial
     * @throws Exception
     */
    public static function from(stdClass $obj): ResearchTimeMaterial {
        return new ResearchTimeMaterial(
         ResearchTimeMaterial::fromQuantity($obj->{'quantity'})
        ,ResearchTimeMaterial::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ResearchTimeMaterial
     */
    public static function sample(): ResearchTimeMaterial {
        return new ResearchTimeMaterial(
         ResearchTimeMaterial::sampleQuantity()
        ,ResearchTimeMaterial::sampleTypeId()
        );
    }
}

// This is a autogenerated file:ResearchTimeSkill

class ResearchTimeSkill {
    private int $level; // json:level Required
    private int $typeId; // json:typeID Required

    /**
     * @param int $level
     * @param int $typeId
     */
    public function __construct(int $level, int $typeId) {
        $this->level = $level;
        $this->typeId = $typeId;
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromLevel(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toLevel(): int {
        if (ResearchTimeSkill::validateLevel($this->level))  {
            return $this->level; /*int*/
        }
        throw new Exception('never get to this ResearchTimeSkill::level');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateLevel(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchTimeSkill::level");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getLevel(): int {
        if (ResearchTimeSkill::validateLevel($this->level))  {
            return $this->level;
        }
        throw new Exception('never get to getLevel ResearchTimeSkill::level');
    }

    /**
     * @return int
     */
    public static function sampleLevel(): int {
        return 31; /*31:level*/
    }

    /**
     * @param int $value
     * @throws Exception
     * @return int
     */
    public static function fromTypeId(int $value): int {
        return $value; /*int*/
    }

    /**
     * @throws Exception
     * @return int
     */
    public function toTypeId(): int {
        if (ResearchTimeSkill::validateTypeId($this->typeId))  {
            return $this->typeId; /*int*/
        }
        throw new Exception('never get to this ResearchTimeSkill::typeId');
    }

    /**
     * @param int
     * @return bool
     * @throws Exception
     */
    public static function validateTypeId(int $value): bool {
        if (!is_integer($value)) {
            throw new Exception("Attribute Error:ResearchTimeSkill::typeId");
        }
        return true;
    }

    /**
     * @throws Exception
     * @return int
     */
    public function getTypeId(): int {
        if (ResearchTimeSkill::validateTypeId($this->typeId))  {
            return $this->typeId;
        }
        throw new Exception('never get to getTypeId ResearchTimeSkill::typeId');
    }

    /**
     * @return int
     */
    public static function sampleTypeId(): int {
        return 32; /*32:typeId*/
    }

    /**
     * @throws Exception
     * @return bool
     */
    public function validate(): bool {
        return ResearchTimeSkill::validateLevel($this->level)
        || ResearchTimeSkill::validateTypeId($this->typeId);
    }

    /**
     * @return stdClass
     * @throws Exception
     */
    public function to(): stdClass  {
        $out = new stdClass();
        $out->{'level'} = $this->toLevel();
        $out->{'typeID'} = $this->toTypeId();
        return $out;
    }

    /**
     * @param stdClass $obj
     * @return ResearchTimeSkill
     * @throws Exception
     */
    public static function from(stdClass $obj): ResearchTimeSkill {
        return new ResearchTimeSkill(
         ResearchTimeSkill::fromLevel($obj->{'level'})
        ,ResearchTimeSkill::fromTypeId($obj->{'typeID'})
        );
    }

    /**
     * @return ResearchTimeSkill
     */
    public static function sample(): ResearchTimeSkill {
        return new ResearchTimeSkill(
         ResearchTimeSkill::sampleLevel()
        ,ResearchTimeSkill::sampleTypeId()
        );
    }
}
from typing import Any, List, Optional, TypeVar, Callable, Type, cast


T = TypeVar("T")


def from_int(x: Any) -> int:
    assert isinstance(x, int) and not isinstance(x, bool)
    return x


def from_list(f: Callable[[Any], T], x: Any) -> List[T]:
    assert isinstance(x, list)
    return [f(y) for y in x]


def from_none(x: Any) -> Any:
    assert x is None
    return x


def from_union(fs, x):
    for f in fs:
        try:
            return f(x)
        except:
            pass
    assert False


def to_class(c: Type[T], x: Any) -> dict:
    assert isinstance(x, c)
    return cast(Any, x).to_dict()


def from_float(x: Any) -> float:
    assert isinstance(x, (float, int)) and not isinstance(x, bool)
    return float(x)


def to_float(x: Any) -> float:
    assert isinstance(x, (int, float))
    return x


class CopyingMaterial:
    quantity: int
    type_id: int

    def __init__(self, quantity: int, type_id: int) -> None:
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'CopyingMaterial':
        assert isinstance(obj, dict)
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return CopyingMaterial(quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class CopyingSkill:
    level: int
    type_id: int

    def __init__(self, level: int, type_id: int) -> None:
        self.level = level
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'CopyingSkill':
        assert isinstance(obj, dict)
        level = from_int(obj.get("level"))
        type_id = from_int(obj.get("typeID"))
        return CopyingSkill(level, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["level"] = from_int(self.level)
        result["typeID"] = from_int(self.type_id)
        return result


class Copying:
    materials: Optional[List[CopyingMaterial]]
    skills: Optional[List[CopyingSkill]]
    time: int

    def __init__(self, materials: Optional[List[CopyingMaterial]], skills: Optional[List[CopyingSkill]], time: int) -> None:
        self.materials = materials
        self.skills = skills
        self.time = time

    @staticmethod
    def from_dict(obj: Any) -> 'Copying':
        assert isinstance(obj, dict)
        materials = from_union([lambda x: from_list(CopyingMaterial.from_dict, x), from_none], obj.get("materials"))
        skills = from_union([lambda x: from_list(CopyingSkill.from_dict, x), from_none], obj.get("skills"))
        time = from_int(obj.get("time"))
        return Copying(materials, skills, time)

    def to_dict(self) -> dict:
        result: dict = {}
        if self.materials is not None:
            result["materials"] = from_union([lambda x: from_list(lambda x: to_class(CopyingMaterial, x), x), from_none], self.materials)
        if self.skills is not None:
            result["skills"] = from_union([lambda x: from_list(lambda x: to_class(CopyingSkill, x), x), from_none], self.skills)
        result["time"] = from_int(self.time)
        return result


class InventionMaterial:
    quantity: int
    type_id: int

    def __init__(self, quantity: int, type_id: int) -> None:
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'InventionMaterial':
        assert isinstance(obj, dict)
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return InventionMaterial(quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class InventionProduct:
    probability: Optional[float]
    quantity: int
    type_id: int

    def __init__(self, probability: Optional[float], quantity: int, type_id: int) -> None:
        self.probability = probability
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'InventionProduct':
        assert isinstance(obj, dict)
        probability = from_union([from_float, from_none], obj.get("probability"))
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return InventionProduct(probability, quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        if self.probability is not None:
            result["probability"] = from_union([to_float, from_none], self.probability)
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class InventionSkill:
    level: int
    type_id: int

    def __init__(self, level: int, type_id: int) -> None:
        self.level = level
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'InventionSkill':
        assert isinstance(obj, dict)
        level = from_int(obj.get("level"))
        type_id = from_int(obj.get("typeID"))
        return InventionSkill(level, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["level"] = from_int(self.level)
        result["typeID"] = from_int(self.type_id)
        return result


class Invention:
    materials: Optional[List[InventionMaterial]]
    products: Optional[List[InventionProduct]]
    skills: Optional[List[InventionSkill]]
    time: int

    def __init__(self, materials: Optional[List[InventionMaterial]], products: Optional[List[InventionProduct]], skills: Optional[List[InventionSkill]], time: int) -> None:
        self.materials = materials
        self.products = products
        self.skills = skills
        self.time = time

    @staticmethod
    def from_dict(obj: Any) -> 'Invention':
        assert isinstance(obj, dict)
        materials = from_union([lambda x: from_list(InventionMaterial.from_dict, x), from_none], obj.get("materials"))
        products = from_union([lambda x: from_list(InventionProduct.from_dict, x), from_none], obj.get("products"))
        skills = from_union([lambda x: from_list(InventionSkill.from_dict, x), from_none], obj.get("skills"))
        time = from_int(obj.get("time"))
        return Invention(materials, products, skills, time)

    def to_dict(self) -> dict:
        result: dict = {}
        if self.materials is not None:
            result["materials"] = from_union([lambda x: from_list(lambda x: to_class(InventionMaterial, x), x), from_none], self.materials)
        if self.products is not None:
            result["products"] = from_union([lambda x: from_list(lambda x: to_class(InventionProduct, x), x), from_none], self.products)
        if self.skills is not None:
            result["skills"] = from_union([lambda x: from_list(lambda x: to_class(InventionSkill, x), x), from_none], self.skills)
        result["time"] = from_int(self.time)
        return result


class ManufacturingMaterial:
    quantity: int
    type_id: int

    def __init__(self, quantity: int, type_id: int) -> None:
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ManufacturingMaterial':
        assert isinstance(obj, dict)
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return ManufacturingMaterial(quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class ManufacturingProduct:
    quantity: int
    type_id: int

    def __init__(self, quantity: int, type_id: int) -> None:
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ManufacturingProduct':
        assert isinstance(obj, dict)
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return ManufacturingProduct(quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class ManufacturingSkill:
    level: int
    type_id: int

    def __init__(self, level: int, type_id: int) -> None:
        self.level = level
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ManufacturingSkill':
        assert isinstance(obj, dict)
        level = from_int(obj.get("level"))
        type_id = from_int(obj.get("typeID"))
        return ManufacturingSkill(level, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["level"] = from_int(self.level)
        result["typeID"] = from_int(self.type_id)
        return result


class Manufacturing:
    materials: Optional[List[ManufacturingMaterial]]
    products: Optional[List[ManufacturingProduct]]
    skills: Optional[List[ManufacturingSkill]]
    time: int

    def __init__(self, materials: Optional[List[ManufacturingMaterial]], products: Optional[List[ManufacturingProduct]], skills: Optional[List[ManufacturingSkill]], time: int) -> None:
        self.materials = materials
        self.products = products
        self.skills = skills
        self.time = time

    @staticmethod
    def from_dict(obj: Any) -> 'Manufacturing':
        assert isinstance(obj, dict)
        materials = from_union([lambda x: from_list(ManufacturingMaterial.from_dict, x), from_none], obj.get("materials"))
        products = from_union([lambda x: from_list(ManufacturingProduct.from_dict, x), from_none], obj.get("products"))
        skills = from_union([lambda x: from_list(ManufacturingSkill.from_dict, x), from_none], obj.get("skills"))
        time = from_int(obj.get("time"))
        return Manufacturing(materials, products, skills, time)

    def to_dict(self) -> dict:
        result: dict = {}
        if self.materials is not None:
            result["materials"] = from_union([lambda x: from_list(lambda x: to_class(ManufacturingMaterial, x), x), from_none], self.materials)
        if self.products is not None:
            result["products"] = from_union([lambda x: from_list(lambda x: to_class(ManufacturingProduct, x), x), from_none], self.products)
        if self.skills is not None:
            result["skills"] = from_union([lambda x: from_list(lambda x: to_class(ManufacturingSkill, x), x), from_none], self.skills)
        result["time"] = from_int(self.time)
        return result


class ReactionMaterial:
    quantity: int
    type_id: int

    def __init__(self, quantity: int, type_id: int) -> None:
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ReactionMaterial':
        assert isinstance(obj, dict)
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return ReactionMaterial(quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class ReactionProduct:
    quantity: int
    type_id: int

    def __init__(self, quantity: int, type_id: int) -> None:
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ReactionProduct':
        assert isinstance(obj, dict)
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return ReactionProduct(quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class ReactionSkill:
    level: int
    type_id: int

    def __init__(self, level: int, type_id: int) -> None:
        self.level = level
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ReactionSkill':
        assert isinstance(obj, dict)
        level = from_int(obj.get("level"))
        type_id = from_int(obj.get("typeID"))
        return ReactionSkill(level, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["level"] = from_int(self.level)
        result["typeID"] = from_int(self.type_id)
        return result


class Reaction:
    materials: List[ReactionMaterial]
    products: List[ReactionProduct]
    skills: List[ReactionSkill]
    time: int

    def __init__(self, materials: List[ReactionMaterial], products: List[ReactionProduct], skills: List[ReactionSkill], time: int) -> None:
        self.materials = materials
        self.products = products
        self.skills = skills
        self.time = time

    @staticmethod
    def from_dict(obj: Any) -> 'Reaction':
        assert isinstance(obj, dict)
        materials = from_list(ReactionMaterial.from_dict, obj.get("materials"))
        products = from_list(ReactionProduct.from_dict, obj.get("products"))
        skills = from_list(ReactionSkill.from_dict, obj.get("skills"))
        time = from_int(obj.get("time"))
        return Reaction(materials, products, skills, time)

    def to_dict(self) -> dict:
        result: dict = {}
        result["materials"] = from_list(lambda x: to_class(ReactionMaterial, x), self.materials)
        result["products"] = from_list(lambda x: to_class(ReactionProduct, x), self.products)
        result["skills"] = from_list(lambda x: to_class(ReactionSkill, x), self.skills)
        result["time"] = from_int(self.time)
        return result


class ResearchMaterialMaterial:
    quantity: int
    type_id: int

    def __init__(self, quantity: int, type_id: int) -> None:
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ResearchMaterialMaterial':
        assert isinstance(obj, dict)
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return ResearchMaterialMaterial(quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class ResearchMaterialSkill:
    level: int
    type_id: int

    def __init__(self, level: int, type_id: int) -> None:
        self.level = level
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ResearchMaterialSkill':
        assert isinstance(obj, dict)
        level = from_int(obj.get("level"))
        type_id = from_int(obj.get("typeID"))
        return ResearchMaterialSkill(level, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["level"] = from_int(self.level)
        result["typeID"] = from_int(self.type_id)
        return result


class ResearchMaterial:
    materials: Optional[List[ResearchMaterialMaterial]]
    skills: Optional[List[ResearchMaterialSkill]]
    time: int

    def __init__(self, materials: Optional[List[ResearchMaterialMaterial]], skills: Optional[List[ResearchMaterialSkill]], time: int) -> None:
        self.materials = materials
        self.skills = skills
        self.time = time

    @staticmethod
    def from_dict(obj: Any) -> 'ResearchMaterial':
        assert isinstance(obj, dict)
        materials = from_union([lambda x: from_list(ResearchMaterialMaterial.from_dict, x), from_none], obj.get("materials"))
        skills = from_union([lambda x: from_list(ResearchMaterialSkill.from_dict, x), from_none], obj.get("skills"))
        time = from_int(obj.get("time"))
        return ResearchMaterial(materials, skills, time)

    def to_dict(self) -> dict:
        result: dict = {}
        if self.materials is not None:
            result["materials"] = from_union([lambda x: from_list(lambda x: to_class(ResearchMaterialMaterial, x), x), from_none], self.materials)
        if self.skills is not None:
            result["skills"] = from_union([lambda x: from_list(lambda x: to_class(ResearchMaterialSkill, x), x), from_none], self.skills)
        result["time"] = from_int(self.time)
        return result


class ResearchTimeMaterial:
    quantity: int
    type_id: int

    def __init__(self, quantity: int, type_id: int) -> None:
        self.quantity = quantity
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ResearchTimeMaterial':
        assert isinstance(obj, dict)
        quantity = from_int(obj.get("quantity"))
        type_id = from_int(obj.get("typeID"))
        return ResearchTimeMaterial(quantity, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["quantity"] = from_int(self.quantity)
        result["typeID"] = from_int(self.type_id)
        return result


class ResearchTimeSkill:
    level: int
    type_id: int

    def __init__(self, level: int, type_id: int) -> None:
        self.level = level
        self.type_id = type_id

    @staticmethod
    def from_dict(obj: Any) -> 'ResearchTimeSkill':
        assert isinstance(obj, dict)
        level = from_int(obj.get("level"))
        type_id = from_int(obj.get("typeID"))
        return ResearchTimeSkill(level, type_id)

    def to_dict(self) -> dict:
        result: dict = {}
        result["level"] = from_int(self.level)
        result["typeID"] = from_int(self.type_id)
        return result


class ResearchTime:
    materials: Optional[List[ResearchTimeMaterial]]
    skills: Optional[List[ResearchTimeSkill]]
    time: int

    def __init__(self, materials: Optional[List[ResearchTimeMaterial]], skills: Optional[List[ResearchTimeSkill]], time: int) -> None:
        self.materials = materials
        self.skills = skills
        self.time = time

    @staticmethod
    def from_dict(obj: Any) -> 'ResearchTime':
        assert isinstance(obj, dict)
        materials = from_union([lambda x: from_list(ResearchTimeMaterial.from_dict, x), from_none], obj.get("materials"))
        skills = from_union([lambda x: from_list(ResearchTimeSkill.from_dict, x), from_none], obj.get("skills"))
        time = from_int(obj.get("time"))
        return ResearchTime(materials, skills, time)

    def to_dict(self) -> dict:
        result: dict = {}
        if self.materials is not None:
            result["materials"] = from_union([lambda x: from_list(lambda x: to_class(ResearchTimeMaterial, x), x), from_none], self.materials)
        if self.skills is not None:
            result["skills"] = from_union([lambda x: from_list(lambda x: to_class(ResearchTimeSkill, x), x), from_none], self.skills)
        result["time"] = from_int(self.time)
        return result


class Activities:
    copying: Optional[Copying]
    invention: Optional[Invention]
    manufacturing: Optional[Manufacturing]
    reaction: Optional[Reaction]
    research_material: Optional[ResearchMaterial]
    research_time: Optional[ResearchTime]

    def __init__(self, copying: Optional[Copying], invention: Optional[Invention], manufacturing: Optional[Manufacturing], reaction: Optional[Reaction], research_material: Optional[ResearchMaterial], research_time: Optional[ResearchTime]) -> None:
        self.copying = copying
        self.invention = invention
        self.manufacturing = manufacturing
        self.reaction = reaction
        self.research_material = research_material
        self.research_time = research_time

    @staticmethod
    def from_dict(obj: Any) -> 'Activities':
        assert isinstance(obj, dict)
        copying = from_union([Copying.from_dict, from_none], obj.get("copying"))
        invention = from_union([Invention.from_dict, from_none], obj.get("invention"))
        manufacturing = from_union([Manufacturing.from_dict, from_none], obj.get("manufacturing"))
        reaction = from_union([Reaction.from_dict, from_none], obj.get("reaction"))
        research_material = from_union([ResearchMaterial.from_dict, from_none], obj.get("research_material"))
        research_time = from_union([ResearchTime.from_dict, from_none], obj.get("research_time"))
        return Activities(copying, invention, manufacturing, reaction, research_material, research_time)

    def to_dict(self) -> dict:
        result: dict = {}
        if self.copying is not None:
            result["copying"] = from_union([lambda x: to_class(Copying, x), from_none], self.copying)
        if self.invention is not None:
            result["invention"] = from_union([lambda x: to_class(Invention, x), from_none], self.invention)
        if self.manufacturing is not None:
            result["manufacturing"] = from_union([lambda x: to_class(Manufacturing, x), from_none], self.manufacturing)
        if self.reaction is not None:
            result["reaction"] = from_union([lambda x: to_class(Reaction, x), from_none], self.reaction)
        if self.research_material is not None:
            result["research_material"] = from_union([lambda x: to_class(ResearchMaterial, x), from_none], self.research_material)
        if self.research_time is not None:
            result["research_time"] = from_union([lambda x: to_class(ResearchTime, x), from_none], self.research_time)
        return result


class Blueprint:
    key: int
    activities: Activities
    blueprint_type_id: int
    max_production_limit: int

    def __init__(self, key: int, activities: Activities, blueprint_type_id: int, max_production_limit: int) -> None:
        self.key = key
        self.activities = activities
        self.blueprint_type_id = blueprint_type_id
        self.max_production_limit = max_production_limit

    @staticmethod
    def from_dict(obj: Any) -> 'Blueprint':
        assert isinstance(obj, dict)
        key = from_int(obj.get("_key"))
        activities = Activities.from_dict(obj.get("activities"))
        blueprint_type_id = from_int(obj.get("blueprintTypeID"))
        max_production_limit = from_int(obj.get("maxProductionLimit"))
        return Blueprint(key, activities, blueprint_type_id, max_production_limit)

    def to_dict(self) -> dict:
        result: dict = {}
        result["_key"] = from_int(self.key)
        result["activities"] = to_class(Activities, self.activities)
        result["blueprintTypeID"] = from_int(self.blueprint_type_id)
        result["maxProductionLimit"] = from_int(self.max_production_limit)
        return result


def blueprint_from_dict(s: Any) -> Blueprint:
    return Blueprint.from_dict(s)


def blueprint_to_dict(x: Blueprint) -> Any:
    return to_class(Blueprint, x)
// To parse this data:
//
//   import { Convert, Blueprint } from "./file";
//
//   const blueprint = Convert.toBlueprint(json);
//
// These functions will throw an error if the JSON doesn't
// match the expected interface, even if the JSON is valid.

export interface Blueprint {
    _key:               number;
    activities:         Activities;
    blueprintTypeID:    number;
    maxProductionLimit: number;
    [property: string]: any;
}

export interface Activities {
    copying?:           Copying;
    invention?:         Invention;
    manufacturing?:     Manufacturing;
    reaction?:          Reaction;
    research_material?: ResearchMaterial;
    research_time?:     ResearchTime;
    [property: string]: any;
}

export interface Copying {
    materials?: CopyingMaterial[];
    skills?:    CopyingSkill[];
    time:       number;
    [property: string]: any;
}

export interface CopyingMaterial {
    quantity: number;
    typeID:   number;
    [property: string]: any;
}

export interface CopyingSkill {
    level:  number;
    typeID: number;
    [property: string]: any;
}

export interface Invention {
    materials?: InventionMaterial[];
    products?:  InventionProduct[];
    skills?:    InventionSkill[];
    time:       number;
    [property: string]: any;
}

export interface InventionMaterial {
    quantity: number;
    typeID:   number;
    [property: string]: any;
}

export interface InventionProduct {
    probability?: number;
    quantity:     number;
    typeID:       number;
    [property: string]: any;
}

export interface InventionSkill {
    level:  number;
    typeID: number;
    [property: string]: any;
}

export interface Manufacturing {
    materials?: ManufacturingMaterial[];
    products?:  ManufacturingProduct[];
    skills?:    ManufacturingSkill[];
    time:       number;
    [property: string]: any;
}

export interface ManufacturingMaterial {
    quantity: number;
    typeID:   number;
    [property: string]: any;
}

export interface ManufacturingProduct {
    quantity: number;
    typeID:   number;
    [property: string]: any;
}

export interface ManufacturingSkill {
    level:  number;
    typeID: number;
    [property: string]: any;
}

export interface Reaction {
    materials: ReactionMaterial[];
    products:  ReactionProduct[];
    skills:    ReactionSkill[];
    time:      number;
    [property: string]: any;
}

export interface ReactionMaterial {
    quantity: number;
    typeID:   number;
    [property: string]: any;
}

export interface ReactionProduct {
    quantity: number;
    typeID:   number;
    [property: string]: any;
}

export interface ReactionSkill {
    level:  number;
    typeID: number;
    [property: string]: any;
}

export interface ResearchMaterial {
    materials?: ResearchMaterialMaterial[];
    skills?:    ResearchMaterialSkill[];
    time:       number;
    [property: string]: any;
}

export interface ResearchMaterialMaterial {
    quantity: number;
    typeID:   number;
    [property: string]: any;
}

export interface ResearchMaterialSkill {
    level:  number;
    typeID: number;
    [property: string]: any;
}

export interface ResearchTime {
    materials?: ResearchTimeMaterial[];
    skills?:    ResearchTimeSkill[];
    time:       number;
    [property: string]: any;
}

export interface ResearchTimeMaterial {
    quantity: number;
    typeID:   number;
    [property: string]: any;
}

export interface ResearchTimeSkill {
    level:  number;
    typeID: number;
    [property: string]: any;
}

// Converts JSON strings to/from your types
// and asserts the results of JSON.parse at runtime
export class Convert {
    public static toBlueprint(json: string): Blueprint {
        return cast(JSON.parse(json), r("Blueprint"));
    }

    public static blueprintToJson(value: Blueprint): string {
        return JSON.stringify(uncast(value, r("Blueprint")), null, 2);
    }
}

function invalidValue(typ: any, val: any, key: any, parent: any = ''): never {
    const prettyTyp = prettyTypeName(typ);
    const parentText = parent ? ` on ${parent}` : '';
    const keyText = key ? ` for key "${key}"` : '';
    throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
}

function prettyTypeName(typ: any): string {
    if (Array.isArray(typ)) {
        if (typ.length === 2 && typ[0] === undefined) {
            return `an optional ${prettyTypeName(typ[1])}`;
        } else {
            return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
        }
    } else if (typeof typ === "object" && typ.literal !== undefined) {
        return typ.literal;
    } else {
        return typeof typ;
    }
}

function jsonToJSProps(typ: any): any {
    if (typ.jsonToJS === undefined) {
        const map: any = {};
        typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ });
        typ.jsonToJS = map;
    }
    return typ.jsonToJS;
}

function jsToJSONProps(typ: any): any {
    if (typ.jsToJSON === undefined) {
        const map: any = {};
        typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ });
        typ.jsToJSON = map;
    }
    return typ.jsToJSON;
}

function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any {
    function transformPrimitive(typ: string, val: any): any {
        if (typeof typ === typeof val) return val;
        return invalidValue(typ, val, key, parent);
    }

    function transformUnion(typs: any[], val: any): any {
        // val must validate against one typ in typs
        const l = typs.length;
        for (let i = 0; i < l; i++) {
            const typ = typs[i];
            try {
                return transform(val, typ, getProps);
            } catch (_) {}
        }
        return invalidValue(typs, val, key, parent);
    }

    function transformEnum(cases: string[], val: any): any {
        if (cases.indexOf(val) !== -1) return val;
        return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
    }

    function transformArray(typ: any, val: any): any {
        // val must be an array with no invalid elements
        if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
        return val.map(el => transform(el, typ, getProps));
    }

    function transformDate(val: any): any {
        if (val === null) {
            return null;
        }
        const d = new Date(val);
        if (isNaN(d.valueOf())) {
            return invalidValue(l("Date"), val, key, parent);
        }
        return d;
    }

    function transformObject(props: { [k: string]: any }, additional: any, val: any): any {
        if (val === null || typeof val !== "object" || Array.isArray(val)) {
            return invalidValue(l(ref || "object"), val, key, parent);
        }
        const result: any = {};
        Object.getOwnPropertyNames(props).forEach(key => {
            const prop = props[key];
            const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
            result[prop.key] = transform(v, prop.typ, getProps, key, ref);
        });
        Object.getOwnPropertyNames(val).forEach(key => {
            if (!Object.prototype.hasOwnProperty.call(props, key)) {
                result[key] = transform(val[key], additional, getProps, key, ref);
            }
        });
        return result;
    }

    if (typ === "any") return val;
    if (typ === null) {
        if (val === null) return val;
        return invalidValue(typ, val, key, parent);
    }
    if (typ === false) return invalidValue(typ, val, key, parent);
    let ref: any = undefined;
    while (typeof typ === "object" && typ.ref !== undefined) {
        ref = typ.ref;
        typ = typeMap[typ.ref];
    }
    if (Array.isArray(typ)) return transformEnum(typ, val);
    if (typeof typ === "object") {
        return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
            : typ.hasOwnProperty("arrayItems")    ? transformArray(typ.arrayItems, val)
            : typ.hasOwnProperty("props")         ? transformObject(getProps(typ), typ.additional, val)
            : invalidValue(typ, val, key, parent);
    }
    // Numbers can be parsed by Date but shouldn't be.
    if (typ === Date && typeof val !== "number") return transformDate(val);
    return transformPrimitive(typ, val);
}

function cast<T>(val: any, typ: any): T {
    return transform(val, typ, jsonToJSProps);
}

function uncast<T>(val: T, typ: any): any {
    return transform(val, typ, jsToJSONProps);
}

function l(typ: any) {
    return { literal: typ };
}

function a(typ: any) {
    return { arrayItems: typ };
}

function u(...typs: any[]) {
    return { unionMembers: typs };
}

function o(props: any[], additional: any) {
    return { props, additional };
}

function m(additional: any) {
    return { props: [], additional };
}

function r(name: string) {
    return { ref: name };
}

const typeMap: any = {
    "Blueprint": o([
        { json: "_key", js: "_key", typ: 0 },
        { json: "activities", js: "activities", typ: r("Activities") },
        { json: "blueprintTypeID", js: "blueprintTypeID", typ: 0 },
        { json: "maxProductionLimit", js: "maxProductionLimit", typ: 0 },
    ], "any"),
    "Activities": o([
        { json: "copying", js: "copying", typ: u(undefined, r("Copying")) },
        { json: "invention", js: "invention", typ: u(undefined, r("Invention")) },
        { json: "manufacturing", js: "manufacturing", typ: u(undefined, r("Manufacturing")) },
        { json: "reaction", js: "reaction", typ: u(undefined, r("Reaction")) },
        { json: "research_material", js: "research_material", typ: u(undefined, r("ResearchMaterial")) },
        { json: "research_time", js: "research_time", typ: u(undefined, r("ResearchTime")) },
    ], "any"),
    "Copying": o([
        { json: "materials", js: "materials", typ: u(undefined, a(r("CopyingMaterial"))) },
        { json: "skills", js: "skills", typ: u(undefined, a(r("CopyingSkill"))) },
        { json: "time", js: "time", typ: 0 },
    ], "any"),
    "CopyingMaterial": o([
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "CopyingSkill": o([
        { json: "level", js: "level", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "Invention": o([
        { json: "materials", js: "materials", typ: u(undefined, a(r("InventionMaterial"))) },
        { json: "products", js: "products", typ: u(undefined, a(r("InventionProduct"))) },
        { json: "skills", js: "skills", typ: u(undefined, a(r("InventionSkill"))) },
        { json: "time", js: "time", typ: 0 },
    ], "any"),
    "InventionMaterial": o([
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "InventionProduct": o([
        { json: "probability", js: "probability", typ: u(undefined, 3.14) },
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "InventionSkill": o([
        { json: "level", js: "level", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "Manufacturing": o([
        { json: "materials", js: "materials", typ: u(undefined, a(r("ManufacturingMaterial"))) },
        { json: "products", js: "products", typ: u(undefined, a(r("ManufacturingProduct"))) },
        { json: "skills", js: "skills", typ: u(undefined, a(r("ManufacturingSkill"))) },
        { json: "time", js: "time", typ: 0 },
    ], "any"),
    "ManufacturingMaterial": o([
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "ManufacturingProduct": o([
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "ManufacturingSkill": o([
        { json: "level", js: "level", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "Reaction": o([
        { json: "materials", js: "materials", typ: a(r("ReactionMaterial")) },
        { json: "products", js: "products", typ: a(r("ReactionProduct")) },
        { json: "skills", js: "skills", typ: a(r("ReactionSkill")) },
        { json: "time", js: "time", typ: 0 },
    ], "any"),
    "ReactionMaterial": o([
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "ReactionProduct": o([
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "ReactionSkill": o([
        { json: "level", js: "level", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "ResearchMaterial": o([
        { json: "materials", js: "materials", typ: u(undefined, a(r("ResearchMaterialMaterial"))) },
        { json: "skills", js: "skills", typ: u(undefined, a(r("ResearchMaterialSkill"))) },
        { json: "time", js: "time", typ: 0 },
    ], "any"),
    "ResearchMaterialMaterial": o([
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "ResearchMaterialSkill": o([
        { json: "level", js: "level", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "ResearchTime": o([
        { json: "materials", js: "materials", typ: u(undefined, a(r("ResearchTimeMaterial"))) },
        { json: "skills", js: "skills", typ: u(undefined, a(r("ResearchTimeSkill"))) },
        { json: "time", js: "time", typ: 0 },
    ], "any"),
    "ResearchTimeMaterial": o([
        { json: "quantity", js: "quantity", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
    "ResearchTimeSkill": o([
        { json: "level", js: "level", typ: 0 },
        { json: "typeID", js: "typeID", typ: 0 },
    ], "any"),
};