func (n *Node) LeavesAll() []*Node {
	var leaves []*Node
	for _, node := range n.All() {
		if node.IsLeaf() {
			leaves = append(leaves, node)
		}
	}
	SortNodesByID(leaves)
	return leaves
}
LeavesAll returns a list of all leaves in the multitree, not just the leaves
local to the node. The nodes are sorted by ID in ascending order.
package multitree
import (
	"fmt"
	"time"
)
type Node struct {
	ID   int64
	Name string
	Alias string
	Created int64
	Completed *int64
	parents  []*Node
	children []*Node
}
func NewNode(name string) *Node {
	return &Node{Name: name}
}
func (n *Node) nextID() int64 {
	var max int64
	for _, node := range n.All() {
		if node.ID > max {
			max = node.ID
		}
	}
	return max + 1
}
func (n *Node) New(name string) *Node {
	return &Node{ID: n.nextID(), Name: name}
}
func (n *Node) IsCompleted() bool {
	return n.Completed != nil
}
func (n *Node) IsCompletedOnDate(date string, offset int) bool {
	t := n.TimeCompleted()
	if !t.IsZero() {
		start, err := time.Parse("2006-01-02", date)
		if err != nil {
			panic(err)
		}
		start = start.Local().Add(time.Duration(offset) * time.Hour)
		end := start.Add(24 * time.Hour)
		if t.Equal(start) || (t.After(start) && t.Before(end)) {
			return true
		}
	}
	return false
}
func (n *Node) IsInProgress() bool {
	if n.IsCompleted() {
		return false
	}
	for _, d := range n.Descendants() {
		if d.IsCompleted() {
			return true
		}
	}
	return false
}
func (n *Node) IsInactive() bool {
	return !n.IsCompleted() && !n.IsInProgress()
}
func (n *Node) IsRoot() bool {
	return len(n.parents) == 0
}
func (n *Node) IsDateNode() bool {
	if n.IsRoot() && ValidateDateNodeName(n.Name) == nil {
		return true
	}
	return false
}
func (n *Node) TimeCompleted() time.Time {
	var t time.Time
	if n.Completed != nil {
		t = time.Unix(*n.Completed, 0)
	}
	return t
}
func (n *Node) Children() []*Node {
	return n.children
}
func (n *Node) Parents() []*Node {
	return n.parents
}
func (n *Node) Ancestors() []*Node {
	var nodes []*Node
	n.TraverseAncestors(func(current *Node, _ func()) {
		nodes = append(nodes, current)
	})
	if len(nodes) > 0 {
		return nodes[1:]
	}
	return nodes
}
func (n *Node) Descendants() []*Node {
	var nodes []*Node
	n.TraverseDescendants(func(current *Node, _ func()) {
		nodes = append(nodes, current)
	})
	if len(nodes) > 0 {
		return nodes[1:]
	}
	return nodes
}
func (n *Node) All() []*Node {
	var nodes []*Node
	n.DepthFirstSearchUndirected(func(cur *Node, ss SearchState, _ func()) {
		if ss == SearchStateWhite {
			nodes = append(nodes, cur)
		}
	})
	SortNodesByID(nodes)
	return nodes
}
func (n *Node) Roots() []*Node {
	var roots []*Node
	n.TraverseAncestors(func(current *Node, _ func()) {
		if current.IsRoot() {
			roots = append(roots, current)
		}
	})
	SortNodesByID(roots)
	return roots
}
func (n *Node) RootsAll() []*Node {
	var roots []*Node
	for _, node := range n.All() {
		if node.IsRoot() {
			roots = append(roots, node)
		}
	}
	SortNodesByID(roots)
	return roots
}
func (n *Node) IsLeaf() bool {
	return len(n.children) == 0
}
func (n *Node) HasChildren() bool {
	return len(n.children) != 0
}
func (n *Node) HasParents() bool {
	return len(n.parents) != 0
}
func (n *Node) Leaves() []*Node {
	var leaves []*Node
	n.TraverseDescendants(func(current *Node, _ func()) {
		if current.IsLeaf() {
			leaves = append(leaves, current)
		}
	})
	SortNodesByID(leaves)
	return leaves
}