// looksLikeSafari returns true if info looks like a handshake
// from a modern version of MS Safari.
329395
func (info rawHelloInfo) looksLikeSafari() bool {
	// "One unique aspect of Secure Transport is that it includes
	// the TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0xff) cipher first,
	// whereas the other libraries we investigated include the
	// cipher last. Similar to Microsoft, Apple has changed
	// TLS behavior in minor OS updates, which are not indicated
	// in the HTTP User-Agent header. We allow for any of the
	// updates when validating handshakes, and we check for the
	// presence and ordering of ciphers, extensions, elliptic
	// curves, and compression methods." (early 2016)

	// Note that any C lib (e.g. curl) compiled on macOS
	// will probably use Secure Transport which will also
	// share the TLS handshake characteristics of Safari.

	// We check for the presence and order of the extensions.
	requiredExtensionsOrder := []uint16{10, 11, 13, 13172, 16, 5, 18, 23}
	if !assertPresenceAndOrdering(requiredExtensionsOrder, info.Extensions, true) {
		// Safari on iOS 11 (beta) uses different set/ordering of extensions
		requiredExtensionsOrderiOS11 := []uint16{65281, 0, 23, 13, 5, 13172, 18, 16, 11, 10}
		if !assertPresenceAndOrdering(requiredExtensionsOrderiOS11, info.Extensions, true) {
			return false
		}
	} else {
		// For these versions of Safari, expect TLS_EMPTY_RENEGOTIATION_INFO_SCSV first.
		if len(info.CipherSuites) < 1 {
			return false
		}
		if info.CipherSuites[0] != scsvRenegotiation {
			return false
		}
	}

	if hasGreaseCiphers(info.CipherSuites) {
		return false
	}

	// We check for order and presence of cipher suites
	expectedCipherSuiteOrder := []uint16{
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, // 0xc02c
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, // 0xc02b
		TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,     // 0xc024
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // 0xc023
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,    // 0xc00a
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,    // 0xc009
		tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,   // 0xc030
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,   // 0xc02f
		TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,       // 0xc028
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,   // 0xc027
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,      // 0xc014
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,      // 0xc013
		tls.TLS_RSA_WITH_AES_256_GCM_SHA384,         // 0x9d
		tls.TLS_RSA_WITH_AES_128_GCM_SHA256,         // 0x9c
		TLS_RSA_WITH_AES_256_CBC_SHA256,             // 0x3d
		tls.TLS_RSA_WITH_AES_128_CBC_SHA256,         // 0x3c
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,            // 0x35
		tls.TLS_RSA_WITH_AES_128_CBC_SHA,            // 0x2f
	}
	return assertPresenceAndOrdering(expectedCipherSuiteOrder, info.CipherSuites, true)
}
686509
func similar(str string, candidates []string) string {
	for _, candidate := range candidates {
		if strings.EqualFold(str, candidate) {
			return candidate
		}
	}
	return ""
}
197027
func checkCairoFeatures(features ...string) []string {
	supported := []string{}
	for _, feature := range features {
		cmd := exec.Command("pkg-config", "--exists", feature)
		cmd.Stderr = os.Stderr
		err := cmd.Run()
		if err == nil {
			supported = append(supported, feature)
		}
	}
	return supported
}
448777
func lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
	authStyleCache.Lock()
	defer authStyleCache.Unlock()
	style, ok = authStyleCache.m[tokenURL]
	return
}
398596
func looksLikeDemangledCPlusPlus(demangled string) bool {
	if strings.Contains(demangled, ".<") { // Skip java names of the form "class.<init>"
		return false
	}
	return strings.ContainsAny(demangled, "<>[]") || strings.Contains(demangled, "::")
}
555084
func (surface *Surface) HasShowTextGlyphs() bool {
	ret := C.cairo_surface_has_show_text_glyphs(surface.Ptr) != 0
	if err := surface.status(); err != nil {
		panic(err)
	}
	return ret
}
1031188
func IsSVGImage(buf []byte) bool {
	return !isBinary(buf) && svgRegex.Match(htmlCommentRegex.ReplaceAll(buf, []byte{}))
}
589366
func (s *IndicesExistsTypeService) Pretty(pretty bool) *IndicesExistsTypeService {
	s.pretty = pretty
	return s
}
1210596
func lookupTLSHash(hash uint8) (crypto.Hash, error) {
	switch hash {
	case hashSHA1:
		return crypto.SHA1, nil
	case hashSHA256:
		return crypto.SHA256, nil
	case hashSHA384:
		return crypto.SHA384, nil
	default:
		return 0, errors.New("tls: unsupported hash algorithm")
	}
}
868423
func LikeCompare(a, b string) (value.BoolValue, bool) {
	// Do we want to always do this replacement?   Or do this at parse time or config?
	if strings.Contains(b, "%") {
		b = strings.Replace(b, "%", "*", -1)
	}
	match, err := glob.Match(b, a)
	if err != nil {
		return value.BoolValueFalse, false
	}
	if match {
		return value.BoolValueTrue, true
	}
	return value.BoolValueFalse, true
}
1012257
func IsHashable(v interface{}) bool {
	if _, ok := v.(iseq.Hashable); ok {
		return true
	}

	switch v.(type) {
	case bool, int, int8, int32, int64,
		uint, uint8, uint32, uint64,
		float32, float64,
		nil,
		string,
		complex64, complex128:
		return true
	}
	return false
}
1343118
func (t *nfkcTrie) lookupUnsafe(s []byte) uint16 {
	c0 := s[0]
	if c0 < 0x80 { // is ASCII
		return nfkcValues[c0]
	}
	i := nfkcIndex[c0]
	if c0 < 0xE0 { // 2-byte UTF-8
		return t.lookupValue(uint32(i), s[1])
	}
	i = nfkcIndex[uint32(i)<<6+uint32(s[1])]
	if c0 < 0xF0 { // 3-byte UTF-8
		return t.lookupValue(uint32(i), s[2])
	}
	i = nfkcIndex[uint32(i)<<6+uint32(s[2])]
	if c0 < 0xF8 { // 4-byte UTF-8
		return t.lookupValue(uint32(i), s[3])
	}
	return 0
}
576914
func isLikeMediaType(s, t string) bool {
	if !strings.HasPrefix(s, "application/") {
		return false
	}
	switch t {
	case "json":
		return strings.Contains(s, "+json")
	case "xml":
		return strings.Contains(s, "+xml")
	default:
		return false
	}
}
362988
func sgExistsInENI(sgID string, iface *ec2.NetworkInterface) bool {
	for _, v := range iface.Groups {
		if *v.GroupId == sgID {
			return true
		}
	}
	return false
}
1272017
func (s *XPackInfoService) Pretty(pretty bool) *XPackInfoService {
	s.pretty = pretty
	return s
}
893326
func LooksLikeIPv6(ip string) bool {
	if !strings.Contains(ip, ":") {
		return false
	}
	return ipv6Pattern.MatchString(ip)
}
875240
func AsSafeValue(i interface{}) *Value {
	return &Value{
		val:  reflect.ValueOf(i),
		safe: true,
	}
}