func (n *Node) Prop(key string) interface{} {
	return n.Props[key]
}
Prop returns property value for key that is known to exist.
Returns nil if it actually doesn't -- this version allows
direct conversion of return.  See PropTry for version with
error message if uncertain if property exists.
package ki
import (
	"bytes"
	"encoding/gob"
	"errors"
	"fmt"
	"strconv"
	"sync/atomic"
	"unsafe"
	"log"
	"reflect"
	"strings"
	"github.com/goki/ki/bitflag"
	"github.com/goki/ki/kit"
	"github.com/jinzhu/copier"
)
type Node struct {
	Nm        string    `copy:"-" label:"Name" desc:"Ki.Name() user-supplied name of this node -- can be empty or non-unique"`
	Flag      int64     `tableview:"-" copy:"-" json:"-" xml:"-" max-width:"80" height:"3" desc:"bit flags for internal node state"`
	Props     Props     `tableview:"-" xml:"-" copy:"-" label:"Properties" desc:"Ki.Properties() property map for arbitrary extensible properties, including style properties"`
	Par       Ki        `tableview:"-" copy:"-" json:"-" xml:"-" label:"Parent" view:"-" desc:"Ki.Parent() parent of this node -- set automatically when this node is added as a child of parent"`
	Kids      Slice     `tableview:"-" copy:"-" label:"Children" desc:"Ki.Children() list of children of this node -- all are set to have this node as their parent -- can reorder etc but generally use Ki Node methods to Add / Delete to ensure proper usage"`
	NodeSig   Signal    `copy:"-" json:"-" xml:"-" view:"-" desc:"Ki.NodeSignal() signal for node structure / state changes -- emits NodeSignals signals -- can also extend to custom signals (see signal.go) but in general better to create a new Signal instead"`
	Ths       Ki        `copy:"-" json:"-" xml:"-" view:"-" desc:"we need a pointer to ourselves as a Ki, which can always be used to extract the true underlying type of object when Node is embedded in other structs -- function receivers do not have this ability so this is necessary.  This is set to nil when deleted.  Typically use This() convenience accessor which protects against concurrent access."`
	index     int       `copy:"-" json:"-" xml:"-" view:"-" desc:"last value of our index -- used as a starting point for finding us in our parent next time -- is not guaranteed to be accurate!  use IndexInParent() method"`
	depth     int       `copy:"-" json:"-" xml:"-" view:"-" desc:"optional depth parameter of this node -- only valid during specific contexts, not generally -- e.g., used in FuncDownBreadthFirst function"`
	fieldOffs []uintptr `copy:"-" json:"-" xml:"-" view:"-" desc:"cached version of the field offsets relative to base Node address -- used in generic field access."`
}
var KiT_Node = kit.Types.AddType(&Node{}, Props{"EnumType:Flag": KiT_Flags})
func (n *Node) String() string {
	return n.This().Path()
}
func (n *Node) This() Ki {
	if n == nil || n.IsDestroyed() {
		return nil
	}
	return n.Ths
}
func (n *Node) AsNode() *Node {
	return n
}
func (n *Node) InitName(k Ki, name string) {
	InitNode(k)
	n.SetName(name)
}
func (n *Node) Embed(t reflect.Type) Ki {
	if n == nil {
		return nil
	}
	es := kit.Embed(n.This(), t)
	if es != nil {
		k, ok := es.(Ki)
		if ok {
			return k
		}
		log.Printf("ki.Embed on: %v embedded struct is not a Ki type -- use kit.Embed for a more general version\n", n.Path())
		return nil
	}
	return nil
}
func (n *Node) BaseIface() reflect.Type {
	return KiType
}
func (n *Node) Name() string {
	return n.Nm
}
func (n *Node) SetName(name string) {
	n.Nm = name
}
func (n *Node) Parent() Ki {
	return n.Par
}
func (n *Node) IndexInParent() (int, bool) {
	if n.Par == nil {
		return -1, false
	}
	idx, ok := n.Par.Children().IndexOf(n.This(), n.index)  
	if ok {
		n.index = idx
	}
	return idx, ok
}
func (n *Node) ParentLevel(par Ki) int {
	parLev := -1
	n.FuncUpParent(0, n, func(k Ki, level int, d interface{}) bool {
		if k == par {
			parLev = level
			return Break
		}
		return Continue
	})
	return parLev
}
func (n *Node) ParentByName(name string) Ki {
	if IsRoot(n) {
		return nil
	}
	if n.Par.Name() == name {
		return n.Par
	}
	return n.Par.ParentByName(name)
}
func (n *Node) ParentByNameTry(name string) (Ki, error) {
	par := n.ParentByName(name)
	if par != nil {
		return par, nil
	}
	return nil, fmt.Errorf("ki %v: Parent name: %v not found", n.Nm, name)
}
func (n *Node) ParentByType(t reflect.Type, embeds bool) Ki {
	if IsRoot(n) {
		return nil
	}
	if embeds {
		if TypeEmbeds(n.Par, t) {
			return n.Par
		}
	} else {
		if Type(n.Par) == t {
			return n.Par
		}
	}
	return n.Par.ParentByType(t, embeds)
}
func (n *Node) ParentByTypeTry(t reflect.Type, embeds bool) (Ki, error) {
	par := n.ParentByType(t, embeds)
	if par != nil {
		return par, nil
	}
	return nil, fmt.Errorf("ki %v: Parent of type: %v not found", n.Nm, t)
}
func (n *Node) HasChildren() bool {
	return len(n.Kids) > 0
}
func (n *Node) NumChildren() int {
	return len(n.Kids)
}
func (n *Node) Children() *Slice {
	return &n.Kids
}
func (n *Node) IsValidIndex(idx int) error {
	sz := len(n.Kids)
	if idx >= 0 && idx < sz {
		return nil
	}
	return fmt.Errorf("ki %v: invalid index: %v -- len = %v", n.Nm, idx, sz)
}
func (n *Node) Child(idx int) Ki {
	return n.Kids[idx]
}
func (n *Node) ChildTry(idx int) (Ki, error) {
	if err := n.IsValidIndex(idx); err != nil {
		return nil, err
	}
	return n.Kids[idx], nil
}
func (n *Node) ChildByName(name string, startIdx int) Ki {
	return n.Kids.ElemByName(name, startIdx)
}
func (n *Node) ChildByNameTry(name string, startIdx int) (Ki, error) {
	idx, ok := n.Kids.IndexByName(name, startIdx)
	if !ok {
		return nil, fmt.Errorf("ki %v: child named: %v not found", n.Nm, name)
	}
	return n.Kids[idx], nil
}
func (n *Node) ChildByType(t reflect.Type, embeds bool, startIdx int) Ki {
	return n.Kids.ElemByType(t, embeds, startIdx)
}
func (n *Node) ChildByTypeTry(t reflect.Type, embeds bool, startIdx int) (Ki, error) {
	idx, ok := n.Kids.IndexByType(t, embeds, startIdx)
	if !ok {
		return nil, fmt.Errorf("ki %v: child of type: %t not found", n.Nm, t)
	}
	return n.Kids[idx], nil
}
func EscapePathName(name string) string {
	return strings.Replace(strings.Replace(name, ".", `\,`, -1), "/", `\\`, -1)
}
func UnescapePathName(name string) string {
	return strings.Replace(strings.Replace(name, `\,`, ".", -1), `\\`, "/", -1)
}
func (n *Node) Path() string {
	if n.Par != nil {
		if n.IsField() {
			return n.Par.Path() + "." + EscapePathName(n.Nm)
		}
		return n.Par.Path() + "/" + EscapePathName(n.Nm)
	}
	return "/" + EscapePathName(n.Nm)
}
func (n *Node) PathFrom(par Ki) string {
	if n.Par != nil {
		ppath := ""
		if n.Par == par {
			ppath = "/" + EscapePathName(par.Name())
		} else {
			ppath = n.Par.PathFrom(par)
		}
		if n.IsField() {
			return ppath + "." + EscapePathName(n.Nm)
		}
		return ppath + "/" + EscapePathName(n.Nm)
	}
	return "/" + n.Nm
}
func findPathChild(k Ki, child string) (int, bool) {
	if child[0] == '[' && child[len(child)-1] == ']' {
		idx, err := strconv.Atoi(child[1 : len(child)-1])
		if err != nil {
			return idx, false
		}
		if idx < 0 {  
			idx = len(*k.Children()) + idx
		}
		if k.Children().IsValidIndex(idx) != nil {
			return idx, false
		}
		return idx, true
	}
	return k.Children().IndexByName(child, 0)
}
func (n *Node) FindPath(path string) Ki {
	if n.Par != nil {  
		myp := n.Path()
		path = strings.TrimPrefix(path, myp)
	}
	curn := Ki(n)
	pels := strings.Split(strings.Trim(strings.TrimSpace(path), "\""), "/")
	for i, pe := range pels {
		if len(pe) == 0 {
			continue
		}
		if i <= 1 && curn.Name() == UnescapePathName(pe) {
			continue
		}
		if strings.Contains(pe, ".") {  
			fels := strings.Split(pe, ".")
			idx, ok := findPathChild(curn, UnescapePathName(fels[0]))
			if !ok {
				return nil
			}
			curn = (*(curn.Children()))[idx]
			for i := 1; i < len(fels); i++ {
				fe := UnescapePathName(fels[i])
				fk := KiFieldByName(curn.AsNode(), fe)
				if fk == nil {
					return nil
				}
				curn = fk
			}
		} else {
			idx, ok := findPathChild(curn, UnescapePathName(pe))
			if !ok {
				return nil
			}
			curn = (*(curn.Children()))[idx]
		}
	}
	return curn
}
func (n *Node) FindPathTry(path string) (Ki, error) {
	fk := n.This().FindPath(path)
	if fk != nil {
		return fk, nil
	}
	return nil, fmt.Errorf("ki %v: element at path: %v not found", n.Nm, path)
}
func (n *Node) AddChild(kid Ki) error {
	if err := ThisCheck(n); err != nil {
		return err
	}
	InitNode(kid)
	n.Kids = append(n.Kids, kid)
	SetParent(kid, n.This())  
	return nil
}
func (n *Node) AddNewChild(typ reflect.Type, name string) Ki {
	if err := ThisCheck(n); err != nil {
		return nil
	}
	kid := NewOfType(typ)
	InitNode(kid)
	n.Kids = append(n.Kids, kid)
	kid.SetName(name)
	SetParent(kid, n.This())
	return kid
}
func (n *Node) SetChild(kid Ki, idx int, name string) error {
	if err := n.Kids.IsValidIndex(idx); err != nil {
		return err
	}
	if name != "" {
		kid.InitName(kid, name)
	} else {
		InitNode(kid)
	}
	n.Kids[idx] = kid
	SetParent(kid, n.This())
	return nil
}
func (n *Node) InsertChild(kid Ki, at int) error {
	if err := ThisCheck(n); err != nil {
		return err
	}
	InitNode(kid)
	n.Kids.Insert(kid, at)
	SetParent(kid, n.This())
	return nil
}
func (n *Node) InsertNewChild(typ reflect.Type, at int, name string) Ki {
	if err := ThisCheck(n); err != nil {
		return nil
	}
	kid := NewOfType(typ)
	InitNode(kid)
	n.Kids.Insert(kid, at)
	kid.SetName(name)
	SetParent(kid, n.This())
	return kid
}
func (n *Node) SetNChildren(trgn int, typ reflect.Type, nameStub string) (mods, updt bool) {
	mods, updt = false, false
	sz := len(n.Kids)
	if trgn == sz {
		return
	}
	for sz > trgn {
		if !mods {
			mods = true
			updt = n.UpdateStart()
		}
		sz--
		n.DeleteChildAtIndex(sz, true)
	}
	for sz < trgn {
		if !mods {
			mods = true
			updt = n.UpdateStart()
		}
		nm := fmt.Sprintf("%s%d", nameStub, sz)
		n.InsertNewChild(typ, sz, nm)
		sz++
	}
	return
}
func (n *Node) ConfigChildren(config kit.TypeAndNameList) (mods, updt bool) {
	return n.Kids.Config(n.This(), config)
}
func (n *Node) DeleteChildAtIndex(idx int, destroy bool) error {
	child, err := n.ChildTry(idx)
	if err != nil {
		return err
	}
	updt := n.UpdateStart()
	n.SetFlag(int(ChildDeleted))
	if child.Parent() == n.This() {
		child.SetFlag(int(NodeDeleted))
		child.NodeSignal().Emit(child, int64(NodeSignalDeleting), nil)
		SetParent(child, nil)
	}
	n.Kids.DeleteAtIndex(idx)
	if destroy {
		DelMgr.Add(child)
	}
	UpdateReset(child)  
	n.UpdateEnd(updt)
	return nil
}
func (n *Node) DeleteChild(child Ki, destroy bool) error {
	if child == nil {
		return errors.New("ki DeleteChild: child is nil")
	}
	idx, ok := n.Kids.IndexOf(child, 0)
	if !ok {
		return fmt.Errorf("ki %v: child: %v not found", n.Nm, child.Path())
	}
	return n.DeleteChildAtIndex(idx, destroy)
}
func (n *Node) DeleteChildByName(name string, destroy bool) (Ki, error) {
	idx, ok := n.Kids.IndexByName(name, 0)
	if !ok {
		return nil, fmt.Errorf("ki %v: child named: %v not found", n.Nm, name)
	}
	child := n.Kids[idx]
	return child, n.DeleteChildAtIndex(idx, destroy)
}
func (n *Node) DeleteChildren(destroy bool) {
	updt := n.UpdateStart()
	n.SetFlag(int(ChildrenDeleted))
	for _, child := range n.Kids {
		if child == nil {
			continue
		}
		child.SetFlag(int(NodeDeleted))
		child.NodeSignal().Emit(child, int64(NodeSignalDeleting), nil)
		SetParent(child, nil)
		UpdateReset(child)
	}
	if destroy {
		DelMgr.Add(n.Kids...)
	}
	n.Kids = n.Kids[:0]  
	n.UpdateEnd(updt)
}
func (n *Node) Delete(destroy bool) {
	if n.Par == nil {
		if destroy {
			n.This().Destroy()
		}
	} else {
		n.Par.DeleteChild(n.This(), destroy)
	}
}
func (n *Node) Destroy() {
	if n.This() == nil {  
		return
	}
	n.DisconnectAll()
	n.DeleteChildren(true)  
	n.FuncFields(0, nil, func(k Ki, level int, d interface{}) bool {
		k.Destroy()
		return true
	})
	DelMgr.DestroyDeleted()  
	n.SetFlag(int(NodeDestroyed))
	n.Ths = nil  
}
func (n *Node) Flags() int64 {
	return atomic.LoadInt64(&n.Flag)
}
func (n *Node) HasFlag(flag int) bool {
	return bitflag.HasAtomic(&n.Flag, flag)
}
func (n *Node) SetFlag(flag ...int) {
	bitflag.SetAtomic(&n.Flag, flag...)
}
func (n *Node) SetFlagState(on bool, flag ...int) {
	bitflag.SetStateAtomic(&n.Flag, on, flag...)
}
func (n *Node) SetFlagMask(mask int64) {
	bitflag.SetMaskAtomic(&n.Flag, mask)
}
func (n *Node) ClearFlag(flag ...int) {
	bitflag.ClearAtomic(&n.Flag, flag...)
}
func (n *Node) ClearFlagMask(mask int64) {
	bitflag.ClearMaskAtomic(&n.Flag, mask)
}
func (n *Node) IsField() bool {
	return bitflag.HasAtomic(&n.Flag, int(IsField))
}
func (n *Node) IsUpdating() bool {
	return bitflag.HasAtomic(&n.Flag, int(Updating))
}
func (n *Node) OnlySelfUpdate() bool {
	return bitflag.HasAtomic(&n.Flag, int(OnlySelfUpdate))
}
func (n *Node) SetOnlySelfUpdate() {
	n.SetFlag(int(OnlySelfUpdate))
}
func (n *Node) SetChildAdded() {
	n.SetFlag(int(ChildAdded))
}
func (n *Node) SetValUpdated() {
	n.SetFlag(int(ValUpdated))
}
func (n *Node) IsDeleted() bool {
	return bitflag.HasAtomic(&n.Flag, int(NodeDeleted))
}
func (n *Node) IsDestroyed() bool {
	return bitflag.HasAtomic(&n.Flag, int(NodeDestroyed))
}
func (n *Node) Properties() *Props {
	return &n.Props
}
func (n *Node) SetProp(key string, val interface{}) {
	if n.Props == nil {
		n.Props = make(Props)
	}
	n.Props[key] = val
}
func (n *Node) SetPropStr(key string, val string) {
	n.SetProp(key, val)
}
func (n *Node) SetPropInt(key string, val int) {
	n.SetProp(key, val)
}
func (n *Node) SetPropFloat64(key string, val float64) {
	n.SetProp(key, val)
}
func (n *Node) SetSubProps(key string, val Props) {
	n.SetProp(key, val)
}
func (n *Node) SetProps(props Props) {
	if n.Props == nil {
		n.Props = make(Props, len(props))
	}
	for key, val := range props {
		n.Props[key] = val
	}
}