// This file was automatically generated by "compat-table.js"

package compat

type Engine uint8

const (
	Chrome Engine = iota
	Edge
	ES
	Firefox
	IOS
	Node
	Safari
)

type Feature uint64

const (
	ArraySpread Feature = 1 << iota
	Arrow
	AsyncAwait
	AsyncGenerator
	BigInt
	Class
	ClassField
	ClassPrivateAccessor
	ClassPrivateField
	ClassPrivateMethod
	ClassPrivateStaticAccessor
	ClassPrivateStaticField
	ClassPrivateStaticMethod
	ClassStaticField
	Const
	DefaultArgument
	Destructuring
	ExponentOperator
	ForAwait
	ForOf
	Generator
	Hashbang
	ImportMeta
	Let
	LogicalAssignment
	NestedRestBinding
	NewTarget
	NullishCoalescing
	ObjectExtensions
	ObjectRestSpread
	OptionalCatchBinding
	OptionalChain
	RestArgument
	TemplateLiteral
)

func (features Feature) Has(feature Feature) bool {
	return (features & feature) != 0
}

var Table = map[Feature]map[Engine][]int{
	ArraySpread: {
		Chrome:  {46},
		Edge:    {12},
		ES:      {2015},
		Firefox: {27},
		IOS:     {8},
		Node:    {5},
		Safari:  {7, 1},
	},
	Arrow: {
		Chrome:  {45},
		Edge:    {12},
		ES:      {2015},
		Firefox: {22},
		IOS:     {10},
		Node:    {4},
		Safari:  {10},
	},
	AsyncAwait: {
		Chrome:  {55},
		Edge:    {15},
		ES:      {2017},
		Firefox: {52},
		IOS:     {10, 3},
		Node:    {7, 6},
		Safari:  {10, 1},
	},
	AsyncGenerator: {
		Chrome:  {63},
		Edge:    {79},
		ES:      {2018},
		Firefox: {57},
		IOS:     {12},
		Node:    {10, 0},
		Safari:  {12},
	},
	BigInt: {
		Chrome:  {67},
		Edge:    {79},
		ES:      {2020},
		Firefox: {68},
		Node:    {10, 4},
		Safari:  {14},
	},
	Class: {
		Chrome:  {49},
		Edge:    {13},
		ES:      {2015},
		Firefox: {45},
		IOS:     {9},
		Node:    {6},
		Safari:  {9},
	},
	ClassField: {
		Chrome:  {72},
		Edge:    {79},
		Firefox: {69},
		Node:    {12, 0},
		Safari:  {14},
	},
	ClassPrivateAccessor: {
		Chrome: {84},
	},
	ClassPrivateField: {
		Chrome: {74},
		Edge:   {79},
		Node:   {12, 0},
	},
	ClassPrivateMethod: {
		Chrome: {84},
	},
	ClassPrivateStaticAccessor: {
		Chrome: {84},
	},
	ClassPrivateStaticField: {
		Chrome: {74},
		Edge:   {79},
		Node:   {12, 0},
	},
	ClassPrivateStaticMethod: {
		Chrome: {84},
	},
	ClassStaticField: {
		Chrome:  {72},
		Edge:    {79},
		Firefox: {75},
		Node:    {12, 0},
	},
	Const: {
		Chrome:  {5},
		Edge:    {12},
		ES:      {2015},
		Firefox: {3},
		IOS:     {6},
		Node:    {0, 12},
		Safari:  {3, 1},
	},
	DefaultArgument: {
		Chrome:  {49},
		Edge:    {14},
		ES:      {2015},
		Firefox: {15},
		IOS:     {10},
		Node:    {6},
		Safari:  {10},
	},
	Destructuring: {
		Chrome:  {49},
		Edge:    {14},
		ES:      {2015},
		Firefox: {2},
		IOS:     {8},
		Node:    {6},
		Safari:  {7, 1},
	},
	ExponentOperator: {
		Chrome:  {52},
		Edge:    {14},
		ES:      {2016},
		Firefox: {52},
		IOS:     {10, 3},
		Node:    {7},
		Safari:  {10, 1},
	},
	ForAwait: {
		Chrome:  {63},
		Edge:    {79},
		ES:      {2018},
		Firefox: {57},
		IOS:     {12},
		Node:    {10, 0},
		Safari:  {12},
	},
	ForOf: {
		Chrome:  {38},
		Edge:    {12},
		ES:      {2015},
		Firefox: {13},
		IOS:     {8},
		Node:    {0, 12},
		Safari:  {7, 1},
	},
	Generator: {
		Chrome:  {39},
		Edge:    {13},
		ES:      {2015},
		Firefox: {27},
		IOS:     {10},
		Node:    {4},
		Safari:  {10},
	},
	Hashbang: {
		Chrome:  {74},
		Edge:    {79},
		Firefox: {67},
		IOS:     {13, 4},
		Node:    {12, 0},
		Safari:  {13, 1},
	},
	ImportMeta: {
		Chrome:  {64},
		Edge:    {79},
		ES:      {2020},
		Firefox: {62},
		IOS:     {12},
		Safari:  {11, 1},
	},
	Let: {
		Chrome:  {49},
		Edge:    {12},
		ES:      {2015},
		Firefox: {44},
		IOS:     {10},
		Node:    {6},
		Safari:  {10},
	},
	LogicalAssignment: {
		Chrome:  {85},
		Firefox: {79},
		Safari:  {14},
	},
	NestedRestBinding: {
		Chrome:  {49},
		Edge:    {14},
		ES:      {2016},
		Firefox: {47},
		IOS:     {10, 3},
		Node:    {6},
		Safari:  {10, 1},
	},
	NewTarget: {
		Chrome:  {46},
		Edge:    {13},
		ES:      {2015},
		Firefox: {41},
		IOS:     {10},
		Node:    {5},
		Safari:  {10},
	},
	NullishCoalescing: {
		Chrome:  {80},
		Edge:    {80},
		ES:      {2020},
		Firefox: {72},
		IOS:     {13, 4},
		Node:    {14, 0},
		Safari:  {13, 1},
	},
	ObjectExtensions: {
		Chrome:  {44},
		Edge:    {12},
		ES:      {2015},
		Firefox: {34},
		IOS:     {8},
		Node:    {4},
		Safari:  {7, 1},
	},
	ObjectRestSpread: {
		Chrome:  {60},
		Edge:    {79},
		ES:      {2018},
		Firefox: {55},
		IOS:     {11, 3},
		Node:    {8, 3},
		Safari:  {11, 1},
	},
	OptionalCatchBinding: {
		Chrome:  {66},
		Edge:    {79},
		ES:      {2019},
		Firefox: {58},
		IOS:     {11, 3},
		Node:    {10, 0},
		Safari:  {11, 1},
	},
	OptionalChain: {
		Chrome:  {80},
		Edge:    {80},
		ES:      {2020},
		Firefox: {74},
		IOS:     {13, 4},
		Node:    {14, 0},
		Safari:  {13, 1},
	},
	RestArgument: {
		Chrome:  {47},
		Edge:    {12},
		ES:      {2015},
		Firefox: {15},
		IOS:     {10},
		Node:    {6},
		Safari:  {10},
	},
	TemplateLiteral: {
		Chrome:  {41},
		Edge:    {12},
		ES:      {2015},
		Firefox: {34},
		IOS:     {9},
		Node:    {4},
		Safari:  {9},
	},
}

func isVersionLessThan(a []int, b []int) bool {
	for i := 0; i < len(a) && i < len(b); i++ {
		if a[i] > b[i] {
			return false
		}
		if a[i] < b[i] {
			return true
		}
	}
	return len(a) < len(b)
}

// Return all features that are not available in at least one environment
func UnsupportedFeatures(constraints map[Engine][]int) (unsupported Feature) {
	for feature, engines := range Table {
		for engine, version := range constraints {
			if minVersion, ok := engines[engine]; !ok || isVersionLessThan(version, minVersion) {
				unsupported |= feature
			}
		}
	}
	return
}
