func (n *Node) GetName(name string) *Node {
	if n.getRootNode().namedRoutes != nil {
		return n.getRootNode().namedRoutes[name]
	}
	return nil
}
GetName returns the name for the route, if any.
package mux
import (
	"fmt"
	"net/url"
	"regexp"
	"strings"
)
const Version = "0.0.1"
var (
	allowSuffixExt = []string{".json", ".xml", ".html"}
	extWildRegexp = regexp.MustCompile(`([^.]+).(.+)`)
	wildRegexp = regexp.MustCompile(`(.+)`)
	wordRegexp = regexp.MustCompile(`^\w+$`)
	paramRegexp = regexp.MustCompile(`^:\w+$`)
	optionalParamRegexp = regexp.MustCompile(`^\?:\w+$`)
	defaultOptions = Options{
		CaseSensitive:  true,
		PathClean:      true,
		StrictSlash:    true,
		UseEncodedPath: true,
	}
)
type Options struct {
	CaseSensitive bool
	PathClean bool
	StrictSlash bool
	UseEncodedPath bool
}
func NewTrie(args ...Options) *Trie {
	opts := defaultOptions
	if len(args) > 0 {
		opts = args[0]
	}
	return &Trie{
		caseSensitive:  opts.CaseSensitive,
		pathClean:      opts.PathClean,
		strictSlash:    opts.StrictSlash,
		useEncodedPath: opts.UseEncodedPath,
		root: &Node{
			parent:   nil,
			children: make(map[string]*Node),
			handlers: make(map[string]interface{}),
		},
	}
}
type Trie struct {
	caseSensitive  bool
	pathClean      bool
	strictSlash    bool
	useEncodedPath bool
	root           *Node
}
func (t *Trie) Parse(pattern string) *Node {
	if strings.Contains(pattern, "//") {
		panic(fmt.Errorf(`multi-slash exist: "%s"`, pattern))
	}
	_pattern := strings.TrimPrefix(pattern, "/")
	if !t.caseSensitive {
		_pattern = strings.ToLower(_pattern)
	}
	node := parsePattern(t.root, strings.Split(_pattern, "/"))
	if node.pattern == "" {
		node.pattern = pattern
	}
	return node
}
func (t *Trie) Match(path string) (*Matched, error) {
	if path == "" || path[0] != '/' {
		return nil, fmt.Errorf(`path is not start with "/": "%s"`, path)
	}
	if t.pathClean {
		path = pathClean(path)
	}
	if !t.caseSensitive {
		path = strings.ToLower(path)
	}
	start := 1
	end := len(path)
	matched := new(Matched)
	parent := t.root
	for i := 1; i <= end; i++ {
		if i < end && path[i] != '/' {
			continue
		}
		segment := path[start:i]
		node := matchNode(parent, segment, path[i:])
		if node == nil {
			if parent.endpoint && i == end && segment == "" {
				matched.Path = path[:end-1]
			}
			if i == end {
				for _, ext := range allowSuffixExt {
					if strings.HasSuffix(segment, ext) {
						node = matchNode(parent, strings.TrimSuffix(segment, ext), path[i:])
						if node != nil {
							if matched.Params == nil {
								matched.Params = make(map[string]string)
							}
							matched.Params[":ext"] = ext[1:]
							goto ParentNode
						}
					}
				}
			}
			return matched, nil
		}
	ParentNode:
		parent = node
		if len(parent.name) > 0 {
			if matched.Params == nil {
				matched.Params = make(map[string]string)
			}
			if parent.wildcard {
				if len(parent.name) == 1 {
					segs := strings.Split(path[start:end], "/")
					starValue := []string{}
					for {
						if len(segs) > 0 {
							starValue = append(starValue, segs[0])
						}
						if len(segs) == 1 {
							break
						} else {
							segs = segs[1:]
						}
						n := matchNode(parent, segs[0], strings.Join(segs, "/"))
						if n != nil {
							matched.Params[parent.name[0]] = strings.Join(starValue, "/")
							parent = n
							i = i + 1 + len(segs[0])
							start = start + len(strings.Join(starValue, "/"))
							goto END
						} else {
							i = i + 1 + len(segs[0])
						}
					}
					matched.Params[parent.name[0]] = strings.Join(starValue, "/")
				} else {
					values := parent.regex.FindStringSubmatch(path[start:end])
					if len(values) != len(parent.name)+1 {
						return nil, fmt.Errorf("%s: Find wrong match %v, need names %v", path, values, parent.name)
					}
					for i, name := range parent.name {
						matched.Params[name] = values[i+1]
					}
				}
				break
			} else if parent.regex == nil {  
				matched.Params[parent.name[0]] = segment
			} else {
				values := parent.regex.FindStringSubmatch(segment)
				for i, name := range parent.name {
					matched.Params[name] = values[i+1]
				}
			}
		}
		start = i + 1
	END:
	}
	switch {
	case parent.endpoint:
		matched.Node = parent
	case parent.getChild("") != nil:
		matched.Path = path + "/"
	case len(parent.optionChildren) > 0:
		for _, child := range parent.optionChildren {
			matched.Node = child
			break
		}
	}
	return matched, nil
}
type Matched struct {
	Node *Node
	Params map[string]string
	Path string
}
type Node struct {
	name, allow                  []string
	pattern, segment             string
	endpoint, wildcard, optional bool
	parent                       *Node
	segChildren                  []*Node
	optionChildren               []*Node
	varyChildren                 []*Node
	children                     map[string]*Node
	handlers                     map[string]interface{}
	regex                        *regexp.Regexp
	namedRoutes                  map[string]*Node
}
func (n *Node) getSegments() string {
	segments := n.segment
	if n.parent != nil {
		segments = n.parent.getSegments() + "/" + segments
	}
	return segments
}
func (n *Node) getChild(key string) *Node {
	if strings.Contains(key, "::") {
		key = strings.Replace(key, "::", ":", -1)
	}
	if v, ok := n.children[key]; ok {
		return v
	}
	for _, c := range n.segChildren {
		if c.segment == key {
			return c
		}
	}
	for _, c := range n.optionChildren {
		if c.segment == key {
			return c
		}
	}
	for _, c := range n.varyChildren {
		if c.segment == key {
			return c
		}
	}
	return nil
}
func (n *Node) Name(name string) *Node {
	if n.getRootNode().namedRoutes == nil {
		n.getRootNode().namedRoutes = map[string]*Node{name: n}
	} else {
		if _, ok := n.getRootNode().namedRoutes[name]; ok {
			panic(fmt.Errorf("mux: route already has name %q, can't set", name))
		}
		n.getRootNode().namedRoutes[name] = n
	}
	return n
}