func SliceSwap(sl *[]Ki, i, j int) error {
	if err := SliceIsValidIndex(sl, i); err != nil {
		return err
	}
	if err := SliceIsValidIndex(sl, j); err != nil {
		return err
	}
	if i == j {
		return nil
	}
	(*sl)[j], (*sl)[i] = (*sl)[i], (*sl)[j]
	return nil
}
SliceSwap swaps elements between positions.  Returns error if either index is invalid
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]
}
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
}
func (sl *Slice) ElemByType(t reflect.Type, embeds bool, startIdx int) Ki {
	idx, ok := sl.IndexByType(t, embeds, startIdx)
	if !ok {
		return nil
	}
	return (*sl)[idx]
}
func (sl *Slice) ElemByTypeTry(t reflect.Type, embeds bool, startIdx int) (Ki, error) {
	idx, ok := sl.IndexByType(t, embeds, startIdx)
	if !ok {
		return nil, fmt.Errorf("ki.Slice: element of type: %v not found", t)
	}
	return (*sl)[idx], nil
}
func SliceInsert(sl *[]Ki, k Ki, idx int) {
	kl := len(*sl)
	if idx < 0 {
		idx = kl + idx
	}
	if idx < 0 {  
		idx = 0
	}
	if idx > kl {  
		idx = kl
	}
	*sl = append(*sl, nil)
	if idx < kl {
		copy((*sl)[idx+1:], (*sl)[idx:kl])
	}
	(*sl)[idx] = k
}
func (sl *Slice) Insert(k Ki, idx int) {
	SliceInsert((*[]Ki)(sl), k, idx)
}
func SliceDeleteAtIndex(sl *[]Ki, idx int) error {
	if err := SliceIsValidIndex(sl, idx); err != nil {
		return err
	}
	sz := len(*sl)
	copy((*sl)[idx:], (*sl)[idx+1:])
	(*sl)[sz-1] = nil
	(*sl) = (*sl)[:sz-1]
	return nil
}
func (sl *Slice) DeleteAtIndex(idx int) error {
	return SliceDeleteAtIndex((*[]Ki)(sl), idx)
}
func SliceMove(sl *[]Ki, frm, to int) error {
	if err := SliceIsValidIndex(sl, frm); err != nil {
		return err
	}
	if err := SliceIsValidIndex(sl, to); err != nil {
		return err
	}
	if frm == to {
		return nil
	}
	tmp := (*sl)[frm]
	SliceDeleteAtIndex(sl, frm)
	SliceInsert(sl, tmp, to)
	return nil
}
func (sl *Slice) Move(frm, to int) error {
	return SliceMove((*[]Ki)(sl), frm, to)
}