func (sl *Slice) ElemByNameTry(name string, startIdx int) (Ki, error) {
	idx, ok := sl.IndexByName(name, startIdx)
	if !ok {
		return nil, fmt.Errorf("ki.Slice: element named: %v not found", name)
	}
	return (*sl)[idx], nil
}
ElemByNameTry returns first element that has given name, error if not found.
See IndexOf for info on startIdx.
package ki
import (
	"fmt"
	"reflect"
	"github.com/goki/ki/kit"
)
type Slice []Ki
func SliceIsValidIndex(sl *[]Ki, idx int) error {
	if idx >= 0 && idx < len(*sl) {
		return nil
	}
	return fmt.Errorf("ki.Slice: invalid index: %v -- len = %v", idx, len(*sl))
}
func (sl *Slice) IsValidIndex(idx int) error {
	if idx >= 0 && idx < len(*sl) {
		return nil
	}
	return fmt.Errorf("ki.Slice: invalid index: %v -- len = %v", idx, len(*sl))
}
func (sl *Slice) Elem(idx int) Ki {
	return (*sl)[idx]
}
func (sl *Slice) ElemTry(idx int) (Ki, error) {
	if err := sl.IsValidIndex(idx); err != nil {
		return nil, err
	}
	return (*sl)[idx], nil
}
func (sl *Slice) ElemFromEnd(idx int) Ki {
	return (*sl)[len(*sl)-1-idx]
}
func (sl *Slice) ElemFromEndTry(idx int) (Ki, error) {
	return sl.ElemTry(len(*sl) - 1 - idx)
}
func SliceIndexByFunc(sl *[]Ki, startIdx int, match func(k Ki) bool) (int, bool) {
	sz := len(*sl)
	if sz == 0 {
		return -1, false
	}
	if startIdx < 0 {
		startIdx = sz / 2
	}
	if startIdx == 0 {
		for idx, child := range *sl {
			if match(child) {
				return idx, true
			}
		}
	} else {
		if startIdx >= sz {
			startIdx = sz - 1
		}
		upi := startIdx + 1
		dni := startIdx
		upo := false
		for {
			if !upo && upi < sz {
				if match((*sl)[upi]) {
					return upi, true
				}
				upi++
			} else {
				upo = true
			}
			if dni >= 0 {
				if match((*sl)[dni]) {
					return dni, true
				}
				dni--
			} else if upo {
				break
			}
		}
	}
	return -1, false
}
func (sl *Slice) IndexByFunc(startIdx int, match func(k Ki) bool) (int, bool) {
	return SliceIndexByFunc((*[]Ki)(sl), startIdx, match)
}
func SliceIndexOf(sl *[]Ki, kid Ki, startIdx int) (int, bool) {
	return SliceIndexByFunc(sl, startIdx, func(ch Ki) bool { return ch == kid })
}
func (sl *Slice) IndexOf(kid Ki, startIdx int) (int, bool) {
	return sl.IndexByFunc(startIdx, func(ch Ki) bool { return ch == kid })
}
func SliceIndexByName(sl *[]Ki, name string, startIdx int) (int, bool) {
	return SliceIndexByFunc(sl, startIdx, func(ch Ki) bool { return ch.Name() == name })
}
func (sl *Slice) IndexByName(name string, startIdx int) (int, bool) {
	return sl.IndexByFunc(startIdx, func(ch Ki) bool { return ch.Name() == name })
}
func SliceIndexByType(sl *[]Ki, t reflect.Type, embeds bool, startIdx int) (int, bool) {
	if embeds {
		return SliceIndexByFunc(sl, startIdx, func(ch Ki) bool { return TypeEmbeds(ch, t) })
	}
	return SliceIndexByFunc(sl, startIdx, func(ch Ki) bool { return Type(ch) == t })
}
func (sl *Slice) IndexByType(t reflect.Type, embeds bool, startIdx int) (int, bool) {
	if embeds {
		return sl.IndexByFunc(startIdx, func(ch Ki) bool { return TypeEmbeds(ch, t) })
	}
	return sl.IndexByFunc(startIdx, func(ch Ki) bool { return Type(ch) == t })
}
func (sl *Slice) ElemByName(name string, startIdx int) Ki {
	idx, ok := sl.IndexByName(name, startIdx)
	if !ok {
		return nil
	}
	return (*sl)[idx]
}