func getRegionID(s []byte) (regionID, error) {
	if len(s) == 3 {
		if isAlpha(s[0]) {
			return getRegionISO3(s)
		}
		if i, err := strconv.ParseUint(string(s), 10, 10); err == nil {
			return getRegionM49(int(i))
		}
	}
	return getRegionISO2(s)
}
getRegionID returns the region id for s if s is a valid 2-letter region code
or unknownRegion.
package language
import (
	"bytes"
	"fmt"
	"sort"
	"strconv"
	"golang.org/x/text/internal/tag"
)
func findIndex(idx tag.Index, key []byte, form string) (index int, err error) {
	if !tag.FixCase(form, key) {
		return 0, errSyntax
	}
	i := idx.Index(key)
	if i == -1 {
		return 0, mkErrInvalid(key)
	}
	return i, nil
}
func searchUint(imap []uint16, key uint16) int {
	return sort.Search(len(imap), func(i int) bool {
		return imap[i] >= key
	})
}
type langID uint16
func getLangID(s []byte) (langID, error) {
	if len(s) == 2 {
		return getLangISO2(s)
	}
	return getLangISO3(s)
}
func normLang(id langID) (langID, langAliasType) {
	k := sort.Search(len(langAliasMap), func(i int) bool {
		return langAliasMap[i].from >= uint16(id)
	})
	if k < len(langAliasMap) && langAliasMap[k].from == uint16(id) {
		return langID(langAliasMap[k].to), langAliasTypes[k]
	}
	return id, langAliasTypeUnknown
}
func getLangISO2(s []byte) (langID, error) {
	if !tag.FixCase("zz", s) {
		return 0, errSyntax
	}
	if i := lang.Index(s); i != -1 && lang.Elem(i)[3] != 0 {
		return langID(i), nil
	}
	return 0, mkErrInvalid(s)
}
const base = 'z' - 'a' + 1
func strToInt(s []byte) uint {
	v := uint(0)
	for i := 0; i < len(s); i++ {
		v *= base
		v += uint(s[i] - 'a')
	}
	return v
}
func intToStr(v uint, s []byte) {
	for i := len(s) - 1; i >= 0; i-- {
		s[i] = byte(v%base) + 'a'
		v /= base
	}
}
func getLangISO3(s []byte) (langID, error) {
	if tag.FixCase("und", s) {
		for i := lang.Index(s[:2]); i != -1; i = lang.Next(s[:2], i) {
			if e := lang.Elem(i); e[3] == 0 && e[2] == s[2] {
				id := langID(i)
				if id == nonCanonicalUnd {
					return 0, nil
				}
				return id, nil
			}
		}
		if i := altLangISO3.Index(s); i != -1 {
			return langID(altLangIndex[altLangISO3.Elem(i)[3]]), nil
		}
		n := strToInt(s)
		if langNoIndex[n/8]&(1<<(n%8)) != 0 {
			return langID(n) + langNoIndexOffset, nil
		}
		for i := lang.Index(s[:1]); i != -1; i = lang.Next(s[:1], i) {
			if e := lang.Elem(i); e[2] == s[1] && e[3] == s[2] {
				return langID(i), nil
			}
		}
		return 0, mkErrInvalid(s)
	}
	return 0, errSyntax
}
func (id langID) stringToBuf(b []byte) int {
	if id >= langNoIndexOffset {
		intToStr(uint(id)-langNoIndexOffset, b[:3])
		return 3
	} else if id == 0 {
		return copy(b, "und")
	}
	l := lang[id<<2:]
	if l[3] == 0 {
		return copy(b, l[:3])
	}
	return copy(b, l[:2])
}
func (b langID) String() string {
	if b == 0 {
		return "und"
	} else if b >= langNoIndexOffset {
		b -= langNoIndexOffset
		buf := [3]byte{}
		intToStr(uint(b), buf[:])
		return string(buf[:])
	}
	l := lang.Elem(int(b))
	if l[3] == 0 {
		return l[:3]
	}
	return l[:2]
}
func (b langID) ISO3() string {
	if b == 0 || b >= langNoIndexOffset {
		return b.String()
	}
	l := lang.Elem(int(b))
	if l[3] == 0 {
		return l[:3]
	} else if l[2] == 0 {
		return altLangISO3.Elem(int(l[3]))[:3]
	}
	return l[0:1] + l[2:4]
}
func (b langID) IsPrivateUse() bool {
	return langPrivateStart <= b && b <= langPrivateEnd
}
type regionID uint16