Kaynağa Gözat

Merge pull request #420 from benbjohnson/logging

Logging
Xiang Li 12 yıl önce
ebeveyn
işleme
6b77b94127
100 değiştirilmiş dosya ile 6591 ekleme ve 2486 silme
  1. 1 1
      .travis.yml
  2. 5 5
      server/join_command.go
  3. 73 0
      server/peer_server.go
  4. 7 7
      server/remove_command.go
  5. 2 2
      store/v2/compare_and_swap_command.go
  6. 2 2
      store/v2/create_command.go
  7. 2 2
      store/v2/delete_command.go
  8. 2 2
      store/v2/set_command.go
  9. 2 2
      store/v2/sync_command.go
  10. 2 2
      store/v2/update_command.go
  11. 6 2
      test.sh
  12. 1 0
      third_party/code.google.com/p/go.net/.hgignore
  13. 1 1
      third_party/code.google.com/p/go.net/codereview.cfg
  14. 227 0
      third_party/code.google.com/p/go.net/html/charset/charset.go
  15. 200 0
      third_party/code.google.com/p/go.net/html/charset/charset_test.go
  16. 107 0
      third_party/code.google.com/p/go.net/html/charset/gen.go
  17. 235 0
      third_party/code.google.com/p/go.net/html/charset/table.go
  18. 48 0
      third_party/code.google.com/p/go.net/html/charset/testdata/HTTP-charset.html
  19. 48 0
      third_party/code.google.com/p/go.net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html
  20. 49 0
      third_party/code.google.com/p/go.net/html/charset/testdata/HTTP-vs-meta-charset.html
  21. 49 0
      third_party/code.google.com/p/go.net/html/charset/testdata/HTTP-vs-meta-content.html
  22. 47 0
      third_party/code.google.com/p/go.net/html/charset/testdata/No-encoding-declaration.html
  23. 1 0
      third_party/code.google.com/p/go.net/html/charset/testdata/README
  24. BIN
      third_party/code.google.com/p/go.net/html/charset/testdata/UTF-16BE-BOM.html
  25. BIN
      third_party/code.google.com/p/go.net/html/charset/testdata/UTF-16LE-BOM.html
  26. 49 0
      third_party/code.google.com/p/go.net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html
  27. 48 0
      third_party/code.google.com/p/go.net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html
  28. 48 0
      third_party/code.google.com/p/go.net/html/charset/testdata/meta-charset-attribute.html
  29. 48 0
      third_party/code.google.com/p/go.net/html/charset/testdata/meta-content-attribute.html
  30. 2077 2077
      third_party/code.google.com/p/go.net/html/entity.go
  31. 7 9
      third_party/code.google.com/p/go.net/html/token.go
  32. 35 16
      third_party/code.google.com/p/go.net/html/token_test.go
  33. 151 0
      third_party/code.google.com/p/go.net/ipv6/control_rfc2292_unix.go
  34. 210 0
      third_party/code.google.com/p/go.net/ipv6/control_rfc3542_unix.go
  35. 18 0
      third_party/code.google.com/p/go.net/ipv6/icmp_test.go
  36. 0 22
      third_party/code.google.com/p/go.net/ipv6/mocktransponder_test.go
  37. 21 11
      third_party/code.google.com/p/go.net/ipv6/multicast_test.go
  38. 168 0
      third_party/code.google.com/p/go.net/ipv6/readwrite_test.go
  39. 73 0
      third_party/code.google.com/p/go.net/ipv6/sockopt_rfc2292_unix.go
  40. 23 0
      third_party/code.google.com/p/go.net/ipv6/sys.go
  41. 48 0
      third_party/code.google.com/p/go.net/ipv6/sys_bsd.go
  42. 54 0
      third_party/code.google.com/p/go.net/ipv6/sys_darwin.go
  43. 45 0
      third_party/code.google.com/p/go.net/ipv6/sys_linux.go
  44. 16 0
      third_party/code.google.com/p/go.net/ipv6/sys_unix.go
  45. 33 0
      third_party/code.google.com/p/go.net/ipv6/sys_windows.go
  46. 42 0
      third_party/code.google.com/p/go.net/ipv6/syscall_linux_386.go
  47. 56 0
      third_party/code.google.com/p/go.net/ipv6/syscall_linux_386.s
  48. 15 0
      third_party/code.google.com/p/go.net/ipv6/syscall_nosplit4_linux_386.go
  49. 15 0
      third_party/code.google.com/p/go.net/ipv6/syscall_nosplit7_linux_386.go
  50. 26 0
      third_party/code.google.com/p/go.net/ipv6/syscall_unix.go
  51. 32 91
      third_party/code.google.com/p/go.net/ipv6/unicast_test.go
  52. 9 9
      third_party/code.google.com/p/go.net/spdy/spdy_test.go
  53. 2 0
      third_party/code.google.com/p/goprotobuf/README
  54. 1 1
      third_party/code.google.com/p/goprotobuf/lib/codereview/codereview.cfg
  55. 58 3
      third_party/github.com/BurntSushi/toml/README.md
  56. 138 23
      third_party/github.com/BurntSushi/toml/decode.go
  57. 91 6
      third_party/github.com/BurntSushi/toml/decode_test.go
  58. 460 29
      third_party/github.com/BurntSushi/toml/encode.go
  59. 271 14
      third_party/github.com/BurntSushi/toml/encode_test.go
  60. 36 7
      third_party/github.com/BurntSushi/toml/parse.go
  61. 14 0
      third_party/github.com/BurntSushi/toml/toml-test-encoder/COPYING
  62. 14 0
      third_party/github.com/BurntSushi/toml/toml-test-encoder/README.md
  63. 129 0
      third_party/github.com/BurntSushi/toml/toml-test-encoder/main.go
  64. 0 1
      third_party/github.com/BurntSushi/toml/toml-test-go/main.go
  65. 0 0
      third_party/github.com/BurntSushi/toml/type_check.go
  66. 241 0
      third_party/github.com/BurntSushi/toml/type_fields.go
  67. 2 2
      third_party/github.com/coreos/go-etcd/etcd/add_child_test.go
  68. 27 7
      third_party/github.com/coreos/go-etcd/etcd/client.go
  69. 12 6
      third_party/github.com/coreos/go-etcd/etcd/compare_and_swap_test.go
  70. 21 7
      third_party/github.com/coreos/go-etcd/etcd/delete.go
  71. 25 8
      third_party/github.com/coreos/go-etcd/etcd/delete_test.go
  72. 21 1
      third_party/github.com/coreos/go-etcd/etcd/error.go
  73. 25 12
      third_party/github.com/coreos/go-etcd/etcd/get_test.go
  74. 2 0
      third_party/github.com/coreos/go-etcd/etcd/options.go
  75. 23 9
      third_party/github.com/coreos/go-etcd/etcd/requests.go
  76. 24 4
      third_party/github.com/coreos/go-etcd/etcd/response.go
  77. 33 23
      third_party/github.com/coreos/go-etcd/etcd/set_update_create.go
  78. 34 12
      third_party/github.com/coreos/go-etcd/etcd/set_update_create_test.go
  79. 13 15
      third_party/github.com/coreos/go-log/log/commands.go
  80. 1 0
      third_party/github.com/coreos/go-log/log/fields.go
  81. 1 0
      third_party/github.com/coreos/go-log/log/logger.go
  82. 1 0
      third_party/github.com/coreos/go-log/log/priority.go
  83. 1 0
      third_party/github.com/coreos/go-log/log/sinks.go
  84. 5 0
      third_party/github.com/coreos/go-systemd/README.md
  85. 1 1
      third_party/github.com/coreos/go-systemd/activation/files.go
  86. 68 0
      third_party/github.com/coreos/go-systemd/activation/files_test.go
  87. 44 0
      third_party/github.com/coreos/go-systemd/examples/activation/activation.go
  88. 1 0
      third_party/github.com/coreos/go-systemd/examples/activation/httpserver/README.md
  89. 11 0
      third_party/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service
  90. 5 0
      third_party/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket
  91. 29 0
      third_party/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go
  92. 9 0
      third_party/github.com/coreos/go-systemd/test
  93. 3 1
      third_party/github.com/coreos/raft/.travis.yml
  94. 1 0
      third_party/github.com/coreos/raft/Makefile
  95. 50 2
      third_party/github.com/coreos/raft/README.md
  96. 1 1
      third_party/github.com/coreos/raft/append_entries_request_test.go
  97. 11 28
      third_party/github.com/coreos/raft/command.go
  98. 39 0
      third_party/github.com/coreos/raft/context.go
  99. 58 0
      third_party/github.com/coreos/raft/event.go
  100. 50 0
      third_party/github.com/coreos/raft/event_dispatcher.go

+ 1 - 1
.travis.yml

@@ -1,5 +1,5 @@
 language: go
-go: 1.1
+go: 1.2
 
 install:
  - echo "Skip install"

+ 5 - 5
server/join_command.go

@@ -37,11 +37,11 @@ func (c *JoinCommand) CommandName() string {
 }
 
 // Join a server to the cluster
-func (c *JoinCommand) Apply(server raft.Server) (interface{}, error) {
-	ps, _ := server.Context().(*PeerServer)
+func (c *JoinCommand) Apply(context raft.Context) (interface{}, error) {
+	ps, _ := context.Server().Context().(*PeerServer)
 
 	b := make([]byte, 8)
-	binary.PutUvarint(b, server.CommitIndex())
+	binary.PutUvarint(b, context.CommitIndex())
 
 	// Make sure we're not getting a cached value from the registry.
 	ps.registry.Invalidate(c.Name)
@@ -54,14 +54,14 @@ func (c *JoinCommand) Apply(server raft.Server) (interface{}, error) {
 	// Check peer number in the cluster
 	if ps.registry.Count() == ps.MaxClusterSize {
 		log.Debug("Reject join request from ", c.Name)
-		return []byte{0}, etcdErr.NewError(etcdErr.EcodeNoMorePeer, "", server.CommitIndex())
+		return []byte{0}, etcdErr.NewError(etcdErr.EcodeNoMorePeer, "", context.CommitIndex())
 	}
 
 	// Add to shared peer registry.
 	ps.registry.Register(c.Name, c.RaftURL, c.EtcdURL)
 
 	// Add peer in raft
-	err := server.AddPeer(c.Name, "")
+	err := context.Server().AddPeer(c.Name, "")
 
 	// Add peer stats
 	if c.Name != ps.RaftServer().Name() {

+ 73 - 0
server/peer_server.go

@@ -22,6 +22,8 @@ import (
 
 const retryInterval = 10
 
+const ThresholdMonitorTimeout = 5 * time.Second
+
 type PeerServer struct {
 	raftServer       raft.Server
 	server           *Server
@@ -42,6 +44,9 @@ type PeerServer struct {
 	RetryTimes       int
 	HeartbeatTimeout time.Duration
 	ElectionTimeout  time.Duration
+
+	closeChan chan bool
+	timeoutThresholdChan chan interface{}
 }
 
 // TODO: find a good policy to do snapshot
@@ -83,6 +88,8 @@ func NewPeerServer(name string, path string, url string, bindAddr string, tlsCon
 		},
 		HeartbeatTimeout: defaultHeartbeatTimeout,
 		ElectionTimeout:  defaultElectionTimeout,
+
+		timeoutThresholdChan: make(chan interface{}, 1),
 	}
 
 	// Create transporter for raft
@@ -95,6 +102,13 @@ func NewPeerServer(name string, path string, url string, bindAddr string, tlsCon
 	}
 
 	s.raftServer = raftServer
+	s.raftServer.AddEventListener(raft.StateChangeEventType, s.raftEventLogger)
+	s.raftServer.AddEventListener(raft.LeaderChangeEventType, s.raftEventLogger)
+	s.raftServer.AddEventListener(raft.TermChangeEventType, s.raftEventLogger)
+	s.raftServer.AddEventListener(raft.AddPeerEventType, s.raftEventLogger)
+	s.raftServer.AddEventListener(raft.RemovePeerEventType, s.raftEventLogger)
+	s.raftServer.AddEventListener(raft.HeartbeatTimeoutEventType, s.raftEventLogger)
+	s.raftServer.AddEventListener(raft.ElectionTimeoutThresholdEventType, s.raftEventLogger)
 
 	return s
 }
@@ -143,7 +157,10 @@ func (s *PeerServer) ListenAndServe(snapshot bool, cluster []string) error {
 		log.Debugf("%s restart as a follower", s.name)
 	}
 
+	s.closeChan = make(chan bool)
+
 	go s.monitorSync()
+	go s.monitorTimeoutThreshold(s.closeChan)
 
 	// open the snapshot
 	if snapshot {
@@ -201,6 +218,10 @@ func (s *PeerServer) listenAndServeTLS(certFile, keyFile string) error {
 
 // Stops the server.
 func (s *PeerServer) Close() {
+	if s.closeChan != nil {
+		close(s.closeChan)
+		s.closeChan = nil
+	}
 	if s.listener != nil {
 		s.listener.Close()
 		s.listener = nil
@@ -429,6 +450,43 @@ func (s *PeerServer) PeerStats() []byte {
 	return nil
 }
 
+// raftEventLogger converts events from the Raft server into log messages.
+func (s *PeerServer) raftEventLogger(event raft.Event) {
+	value := event.Value()
+	prevValue := event.PrevValue()
+	if value == nil {
+		value = "<nil>"
+	}
+	if prevValue == nil {
+		prevValue = "<nil>"
+	}
+
+	switch event.Type() {
+	case raft.StateChangeEventType:
+		log.Infof("%s: state changed from '%v' to '%v'.", s.name, prevValue, value)
+	case raft.TermChangeEventType:
+		log.Infof("%s: term #%v started.", s.name, value)
+	case raft.LeaderChangeEventType:
+		log.Infof("%s: leader changed from '%v' to '%v'.", s.name, prevValue, value)
+	case raft.AddPeerEventType:
+		log.Infof("%s: peer added: '%v'", s.name, value)
+	case raft.RemovePeerEventType:
+		log.Infof("%s: peer removed: '%v'", s.name, value)
+	case raft.HeartbeatTimeoutEventType:
+		var name = "<unknown>"
+		if peer, ok := value.(*raft.Peer); ok {
+			name = peer.Name
+		}
+		log.Infof("%s: warning: heartbeat timed out: '%v'", s.name, name)
+	case raft.ElectionTimeoutThresholdEventType:
+		select {
+		case s.timeoutThresholdChan <- value:
+		default:
+		}
+		
+	}
+}
+
 func (s *PeerServer) monitorSnapshot() {
 	for {
 		time.Sleep(s.snapConf.checkingInterval)
@@ -451,3 +509,18 @@ func (s *PeerServer) monitorSync() {
 		}
 	}
 }
+
+// monitorTimeoutThreshold groups timeout threshold events together and prints
+// them as a single log line.
+func (s *PeerServer) monitorTimeoutThreshold(closeChan chan bool) {
+	for {
+		select {
+		case value := <-s.timeoutThresholdChan:
+			log.Infof("%s: warning: heartbeat near election timeout: %v", s.name, value)
+		case <-closeChan:
+			return
+		}
+
+		time.Sleep(ThresholdMonitorTimeout)
+	}
+}

+ 7 - 7
server/remove_command.go

@@ -23,8 +23,8 @@ func (c *RemoveCommand) CommandName() string {
 }
 
 // Remove a server from the cluster
-func (c *RemoveCommand) Apply(server raft.Server) (interface{}, error) {
-	ps, _ := server.Context().(*PeerServer)
+func (c *RemoveCommand) Apply(context raft.Context) (interface{}, error) {
+	ps, _ := context.Server().Context().(*PeerServer)
 
 	// Remove node from the shared registry.
 	err := ps.registry.Unregister(c.Name)
@@ -38,21 +38,21 @@ func (c *RemoveCommand) Apply(server raft.Server) (interface{}, error) {
 	}
 
 	// Remove peer in raft
-	err = server.RemovePeer(c.Name)
+	err = context.Server().RemovePeer(c.Name)
 	if err != nil {
 		log.Debugf("Unable to remove peer: %s (%v)", c.Name, err)
 		return []byte{0}, err
 	}
 
-	if c.Name == server.Name() {
+	if c.Name == context.Server().Name() {
 		// the removed node is this node
 
 		// if the node is not replaying the previous logs
 		// and the node has sent out a join request in this
 		// start. It is sure that this node received a new remove
 		// command and need to be removed
-		if server.CommitIndex() > ps.joinIndex && ps.joinIndex != 0 {
-			log.Debugf("server [%s] is removed", server.Name())
+		if context.CommitIndex() > ps.joinIndex && ps.joinIndex != 0 {
+			log.Debugf("server [%s] is removed", context.Server().Name())
 			os.Exit(0)
 		} else {
 			// else ignore remove
@@ -61,7 +61,7 @@ func (c *RemoveCommand) Apply(server raft.Server) (interface{}, error) {
 	}
 
 	b := make([]byte, 8)
-	binary.PutUvarint(b, server.CommitIndex())
+	binary.PutUvarint(b, context.CommitIndex())
 
 	return b, err
 }

+ 2 - 2
store/v2/compare_and_swap_command.go

@@ -27,8 +27,8 @@ func (c *CompareAndSwapCommand) CommandName() string {
 }
 
 // Set the key-value pair if the current value of the key equals to the given prevValue
-func (c *CompareAndSwapCommand) Apply(server raft.Server) (interface{}, error) {
-	s, _ := server.StateMachine().(store.Store)
+func (c *CompareAndSwapCommand) Apply(context raft.Context) (interface{}, error) {
+	s, _ := context.Server().StateMachine().(store.Store)
 
 	e, err := s.CompareAndSwap(c.Key, c.PrevValue, c.PrevIndex, c.Value, c.ExpireTime)
 

+ 2 - 2
store/v2/create_command.go

@@ -27,8 +27,8 @@ func (c *CreateCommand) CommandName() string {
 }
 
 // Create node
-func (c *CreateCommand) Apply(server raft.Server) (interface{}, error) {
-	s, _ := server.StateMachine().(store.Store)
+func (c *CreateCommand) Apply(context raft.Context) (interface{}, error) {
+	s, _ := context.Server().StateMachine().(store.Store)
 
 	e, err := s.Create(c.Key, c.Dir, c.Value, c.Unique, c.ExpireTime)
 

+ 2 - 2
store/v2/delete_command.go

@@ -23,8 +23,8 @@ func (c *DeleteCommand) CommandName() string {
 }
 
 // Delete the key
-func (c *DeleteCommand) Apply(server raft.Server) (interface{}, error) {
-	s, _ := server.StateMachine().(store.Store)
+func (c *DeleteCommand) Apply(context raft.Context) (interface{}, error) {
+	s, _ := context.Server().StateMachine().(store.Store)
 
 	if c.Recursive {
 		// recursive implies dir

+ 2 - 2
store/v2/set_command.go

@@ -26,8 +26,8 @@ func (c *SetCommand) CommandName() string {
 }
 
 // Create node
-func (c *SetCommand) Apply(server raft.Server) (interface{}, error) {
-	s, _ := server.StateMachine().(store.Store)
+func (c *SetCommand) Apply(context raft.Context) (interface{}, error) {
+	s, _ := context.Server().StateMachine().(store.Store)
 
 	// create a new node or replace the old node.
 	e, err := s.Set(c.Key, c.Dir, c.Value, c.ExpireTime)

+ 2 - 2
store/v2/sync_command.go

@@ -20,8 +20,8 @@ func (c SyncCommand) CommandName() string {
 	return "etcd:sync"
 }
 
-func (c SyncCommand) Apply(server raft.Server) (interface{}, error) {
-	s, _ := server.StateMachine().(store.Store)
+func (c SyncCommand) Apply(context raft.Context) (interface{}, error) {
+	s, _ := context.Server().StateMachine().(store.Store)
 	s.DeleteExpiredKeys(c.Time)
 
 	return nil, nil

+ 2 - 2
store/v2/update_command.go

@@ -24,8 +24,8 @@ func (c *UpdateCommand) CommandName() string {
 }
 
 // Create node
-func (c *UpdateCommand) Apply(server raft.Server) (interface{}, error) {
-	s, _ := server.StateMachine().(store.Store)
+func (c *UpdateCommand) Apply(context raft.Context) (interface{}, error) {
+	s, _ := context.Server().StateMachine().(store.Store)
 
 	e, err := s.Update(c.Key, c.Value, c.ExpireTime)
 

+ 6 - 2
test.sh

@@ -5,6 +5,10 @@ if [ -z "$PKG" ]; then
     PKG="./store ./server ./server/v2/tests ./mod/lock/v2/tests"
 fi
 
+if [ -z "$RUN" ]; then
+    RUN="."
+fi
+
 # Get GOPATH, etc from build
 . ./build
 
@@ -15,9 +19,9 @@ export GOPATH="${PWD}"
 for i in $PKG
 do
     go test -i $i
-    go test -v $i
+    go test -v -test.run=$RUN $i
 done
 
 # Functional tests
 go test -i ./tests/functional
-ETCD_BIN_PATH=$(pwd)/etcd go test -v ./tests/functional
+ETCD_BIN_PATH=$(pwd)/etcd go test -v  -test.run=$RUN ./tests/functional

+ 1 - 0
third_party/code.google.com/p/go.net/.hgignore

@@ -1,2 +1,3 @@
+# Add no patterns to .hgignore except for files generated by the build.
 syntax:glob
 last-change

+ 1 - 1
third_party/code.google.com/p/go.net/codereview.cfg

@@ -1,2 +1,2 @@
-defaultcc: golang-dev@googlegroups.com
+defaultcc: golang-codereviews@googlegroups.com
 contributors: http://go.googlecode.com/hg/CONTRIBUTORS

+ 227 - 0
third_party/code.google.com/p/go.net/html/charset/charset.go

@@ -0,0 +1,227 @@
+// Package charset provides common text encodings for HTML documents.
+//
+// The mapping from encoding labels to encodings is defined at
+// http://encoding.spec.whatwg.org.
+package charset
+
+import (
+	"bytes"
+	"io"
+	"mime"
+	"strings"
+	"unicode/utf8"
+
+	"code.google.com/p/go.net/html"
+	"code.google.com/p/go.text/encoding"
+	"code.google.com/p/go.text/encoding/charmap"
+	"code.google.com/p/go.text/transform"
+)
+
+// Lookup returns the encoding with the specified label, and its canonical
+// name. It returns nil and the empty string if label is not one of the
+// standard encodings for HTML. Matching is case-insensitive and ignores
+// leading and trailing whitespace.
+func Lookup(label string) (e encoding.Encoding, name string) {
+	label = strings.ToLower(strings.Trim(label, "\t\n\r\f "))
+	enc := encodings[label]
+	return enc.e, enc.name
+}
+
+// DetermineEncoding determines the encoding of an HTML document by examining
+// up to the first 1024 bytes of content and the declared Content-Type.
+//
+// See http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#determining-the-character-encoding
+func DetermineEncoding(content []byte, contentType string) (e encoding.Encoding, name string, certain bool) {
+	if len(content) > 1024 {
+		content = content[:1024]
+	}
+
+	for _, b := range boms {
+		if bytes.HasPrefix(content, b.bom) {
+			e, name = Lookup(b.enc)
+			return e, name, true
+		}
+	}
+
+	if _, params, err := mime.ParseMediaType(contentType); err == nil {
+		if cs, ok := params["charset"]; ok {
+			if e, name = Lookup(cs); e != nil {
+				return e, name, true
+			}
+		}
+	}
+
+	if len(content) > 0 {
+		e, name = prescan(content)
+		if e != nil {
+			return e, name, false
+		}
+	}
+
+	// Try to detect UTF-8.
+	// First eliminate any partial rune at the end.
+	for i := len(content) - 1; i >= 0 && i > len(content)-4; i-- {
+		b := content[i]
+		if b < 0x80 {
+			break
+		}
+		if utf8.RuneStart(b) {
+			content = content[:i]
+			break
+		}
+	}
+	hasHighBit := false
+	for _, c := range content {
+		if c >= 0x80 {
+			hasHighBit = true
+			break
+		}
+	}
+	if hasHighBit && utf8.Valid(content) {
+		return encoding.Nop, "utf-8", false
+	}
+
+	// TODO: change default depending on user's locale?
+	return charmap.Windows1252, "windows-1252", false
+}
+
+// NewReader returns an io.Reader that converts the content of r to UTF-8.
+// It calls DetermineEncoding to find out what r's encoding is.
+func NewReader(r io.Reader, contentType string) (io.Reader, error) {
+	preview := make([]byte, 1024)
+	n, err := io.ReadFull(r, preview)
+	switch {
+	case err == io.ErrUnexpectedEOF:
+		preview = preview[:n]
+		r = bytes.NewReader(preview)
+	case err != nil:
+		return nil, err
+	default:
+		r = io.MultiReader(bytes.NewReader(preview), r)
+	}
+
+	if e, _, _ := DetermineEncoding(preview, contentType); e != encoding.Nop {
+		r = transform.NewReader(r, e.NewDecoder())
+	}
+	return r, nil
+}
+
+func prescan(content []byte) (e encoding.Encoding, name string) {
+	z := html.NewTokenizer(bytes.NewReader(content))
+	for {
+		switch z.Next() {
+		case html.ErrorToken:
+			return nil, ""
+
+		case html.StartTagToken, html.SelfClosingTagToken:
+			tagName, hasAttr := z.TagName()
+			if !bytes.Equal(tagName, []byte("meta")) {
+				continue
+			}
+			attrList := make(map[string]bool)
+			gotPragma := false
+
+			const (
+				dontKnow = iota
+				doNeedPragma
+				doNotNeedPragma
+			)
+			needPragma := dontKnow
+
+			name = ""
+			e = nil
+			for hasAttr {
+				var key, val []byte
+				key, val, hasAttr = z.TagAttr()
+				ks := string(key)
+				if attrList[ks] {
+					continue
+				}
+				attrList[ks] = true
+				for i, c := range val {
+					if 'A' <= c && c <= 'Z' {
+						val[i] = c + 0x20
+					}
+				}
+
+				switch ks {
+				case "http-equiv":
+					if bytes.Equal(val, []byte("content-type")) {
+						gotPragma = true
+					}
+
+				case "content":
+					if e == nil {
+						name = fromMetaElement(string(val))
+						if name != "" {
+							e, name = Lookup(name)
+							if e != nil {
+								needPragma = doNeedPragma
+							}
+						}
+					}
+
+				case "charset":
+					e, name = Lookup(string(val))
+					needPragma = doNotNeedPragma
+				}
+			}
+
+			if needPragma == dontKnow || needPragma == doNeedPragma && !gotPragma {
+				continue
+			}
+
+			if strings.HasPrefix(name, "utf-16") {
+				name = "utf-8"
+				e = encoding.Nop
+			}
+
+			if e != nil {
+				return e, name
+			}
+		}
+	}
+}
+
+func fromMetaElement(s string) string {
+	for s != "" {
+		csLoc := strings.Index(s, "charset")
+		if csLoc == -1 {
+			return ""
+		}
+		s = s[csLoc+len("charset"):]
+		s = strings.TrimLeft(s, " \t\n\f\r")
+		if !strings.HasPrefix(s, "=") {
+			continue
+		}
+		s = s[1:]
+		s = strings.TrimLeft(s, " \t\n\f\r")
+		if s == "" {
+			return ""
+		}
+		if q := s[0]; q == '"' || q == '\'' {
+			s = s[1:]
+			closeQuote := strings.IndexRune(s, rune(q))
+			if closeQuote == -1 {
+				return ""
+			}
+			return s[:closeQuote]
+		}
+
+		end := strings.IndexAny(s, "; \t\n\f\r")
+		if end == -1 {
+			end = len(s)
+		}
+		return s[:end]
+	}
+	return ""
+}
+
+var boms = []struct {
+	bom []byte
+	enc string
+}{
+	{[]byte{0xfe, 0xff}, "utf-16be"},
+	{[]byte{0xff, 0xfe}, "utf-16le"},
+	{[]byte{0xef, 0xbb, 0xbf}, "utf-8"},
+}

+ 200 - 0
third_party/code.google.com/p/go.net/html/charset/charset_test.go

@@ -0,0 +1,200 @@
+package charset
+
+import (
+	"bytes"
+	"io/ioutil"
+	"strings"
+	"testing"
+
+	"code.google.com/p/go.text/transform"
+)
+
+func transformString(t transform.Transformer, s string) (string, error) {
+	r := transform.NewReader(strings.NewReader(s), t)
+	b, err := ioutil.ReadAll(r)
+	return string(b), err
+}
+
+var testCases = []struct {
+	utf8, other, otherEncoding string
+}{
+	{"Résumé", "Résumé", "utf8"},
+	{"Résumé", "R\xe9sum\xe9", "latin1"},
+	{"これは漢字です。", "S0\x8c0o0\"oW[g0Y0\x020", "UTF-16LE"},
+	{"これは漢字です。", "0S0\x8c0oo\"[W0g0Y0\x02", "UTF-16BE"},
+	{"Hello, world", "Hello, world", "ASCII"},
+	{"Gdańsk", "Gda\xf1sk", "ISO-8859-2"},
+	{"Ââ Čč Đđ Ŋŋ Õõ Šš Žž Åå Ää", "\xc2\xe2 \xc8\xe8 \xa9\xb9 \xaf\xbf \xd5\xf5 \xaa\xba \xac\xbc \xc5\xe5 \xc4\xe4", "ISO-8859-10"},
+	{"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "ISO-8859-11"},
+	{"latviešu", "latvie\xf0u", "ISO-8859-13"},
+	{"Seònaid", "Se\xf2naid", "ISO-8859-14"},
+	{"€1 is cheap", "\xa41 is cheap", "ISO-8859-15"},
+	{"românește", "rom\xe2ne\xbate", "ISO-8859-16"},
+	{"nutraĵo", "nutra\xbco", "ISO-8859-3"},
+	{"Kalâdlit", "Kal\xe2dlit", "ISO-8859-4"},
+	{"русский", "\xe0\xe3\xe1\xe1\xda\xd8\xd9", "ISO-8859-5"},
+	{"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "ISO-8859-7"},
+	{"Kağan", "Ka\xf0an", "ISO-8859-9"},
+	{"Résumé", "R\x8esum\x8e", "macintosh"},
+	{"Gdańsk", "Gda\xf1sk", "windows-1250"},
+	{"русский", "\xf0\xf3\xf1\xf1\xea\xe8\xe9", "windows-1251"},
+	{"Résumé", "R\xe9sum\xe9", "windows-1252"},
+	{"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "windows-1253"},
+	{"Kağan", "Ka\xf0an", "windows-1254"},
+	{"עִבְרִית", "\xf2\xc4\xe1\xc0\xf8\xc4\xe9\xfa", "windows-1255"},
+	{"العربية", "\xc7\xe1\xda\xd1\xc8\xed\xc9", "windows-1256"},
+	{"latviešu", "latvie\xf0u", "windows-1257"},
+	{"Việt", "Vi\xea\xf2t", "windows-1258"},
+	{"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "windows-874"},
+	{"русский", "\xd2\xd5\xd3\xd3\xcb\xc9\xca", "KOI8-R"},
+	{"українська", "\xd5\xcb\xd2\xc1\xa7\xce\xd3\xd8\xcb\xc1", "KOI8-U"},
+	{"Hello 常用國字標準字體表", "Hello \xb1`\xa5\u03b0\xea\xa6r\xbc\u0437\u01e6r\xc5\xe9\xaa\xed", "big5"},
+	{"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gbk"},
+	{"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gb18030"},
+	{"עִבְרִית", "\x81\x30\xfb\x30\x81\x30\xf6\x34\x81\x30\xf9\x33\x81\x30\xf6\x30\x81\x30\xfb\x36\x81\x30\xf6\x34\x81\x30\xfa\x31\x81\x30\xfb\x38", "gb18030"},
+	{"㧯", "\x82\x31\x89\x38", "gb18030"},
+	{"これは漢字です。", "\x82\xb1\x82\xea\x82\xcd\x8a\xbf\x8e\x9a\x82\xc5\x82\xb7\x81B", "SJIS"},
+	{"Hello, 世界!", "Hello, \x90\xa2\x8aE!", "SJIS"},
+	{"イウエオカ", "\xb2\xb3\xb4\xb5\xb6", "SJIS"},
+	{"これは漢字です。", "\xa4\xb3\xa4\xec\xa4\u03f4\xc1\xbb\xfa\xa4\u01e4\xb9\xa1\xa3", "EUC-JP"},
+	{"Hello, 世界!", "Hello, \x1b$B@$3&\x1b(B!", "ISO-2022-JP"},
+	{"네이트 | 즐거움의 시작, 슈파스(Spaβ) NATE", "\xb3\xd7\xc0\xcc\xc6\xae | \xc1\xf1\xb0\xc5\xbf\xf2\xc0\xc7 \xbd\xc3\xc0\xdb, \xbd\xb4\xc6\xc4\xbd\xba(Spa\xa5\xe2) NATE", "EUC-KR"},
+}
+
+func TestDecode(t *testing.T) {
+	for _, tc := range testCases {
+		e, _ := Lookup(tc.otherEncoding)
+		if e == nil {
+			t.Errorf("%s: not found", tc.otherEncoding)
+			continue
+		}
+		s, err := transformString(e.NewDecoder(), tc.other)
+		if err != nil {
+			t.Errorf("%s: decode %q: %v", tc.otherEncoding, tc.other, err)
+			continue
+		}
+		if s != tc.utf8 {
+			t.Errorf("%s: got %q, want %q", tc.otherEncoding, s, tc.utf8)
+		}
+	}
+}
+
+func TestEncode(t *testing.T) {
+	for _, tc := range testCases {
+		e, _ := Lookup(tc.otherEncoding)
+		if e == nil {
+			t.Errorf("%s: not found", tc.otherEncoding)
+			continue
+		}
+		s, err := transformString(e.NewEncoder(), tc.utf8)
+		if err != nil {
+			t.Errorf("%s: encode %q: %s", tc.otherEncoding, tc.utf8, err)
+			continue
+		}
+		if s != tc.other {
+			t.Errorf("%s: got %q, want %q", tc.otherEncoding, s, tc.other)
+		}
+	}
+}
+
+// TestNames verifies that you can pass an encoding's name to Lookup and get
+// the same encoding back (except for "replacement").
+func TestNames(t *testing.T) {
+	for _, e := range encodings {
+		if e.name == "replacement" {
+			continue
+		}
+		_, got := Lookup(e.name)
+		if got != e.name {
+			t.Errorf("got %q, want %q", got, e.name)
+			continue
+		}
+	}
+}
+
+var sniffTestCases = []struct {
+	filename, declared, want string
+}{
+	{"HTTP-charset.html", "text/html; charset=iso-8859-15", "iso-8859-15"},
+	{"UTF-16LE-BOM.html", "", "utf-16le"},
+	{"UTF-16BE-BOM.html", "", "utf-16be"},
+	{"meta-content-attribute.html", "text/html", "iso-8859-15"},
+	{"meta-charset-attribute.html", "text/html", "iso-8859-15"},
+	{"No-encoding-declaration.html", "text/html", "utf-8"},
+	{"HTTP-vs-UTF-8-BOM.html", "text/html; charset=iso-8859-15", "utf-8"},
+	{"HTTP-vs-meta-content.html", "text/html; charset=iso-8859-15", "iso-8859-15"},
+	{"HTTP-vs-meta-charset.html", "text/html; charset=iso-8859-15", "iso-8859-15"},
+	{"UTF-8-BOM-vs-meta-content.html", "text/html", "utf-8"},
+	{"UTF-8-BOM-vs-meta-charset.html", "text/html", "utf-8"},
+}
+
+func TestSniff(t *testing.T) {
+	for _, tc := range sniffTestCases {
+		content, err := ioutil.ReadFile("testdata/" + tc.filename)
+		if err != nil {
+			t.Errorf("%s: error reading file: %v", tc.filename, err)
+			continue
+		}
+
+		_, name, _ := DetermineEncoding(content, tc.declared)
+		if name != tc.want {
+			t.Errorf("%s: got %q, want %q", tc.filename, name, tc.want)
+			continue
+		}
+	}
+}
+
+func TestReader(t *testing.T) {
+	for _, tc := range sniffTestCases {
+		content, err := ioutil.ReadFile("testdata/" + tc.filename)
+		if err != nil {
+			t.Errorf("%s: error reading file: %v", tc.filename, err)
+			continue
+		}
+
+		r, err := NewReader(bytes.NewReader(content), tc.declared)
+		if err != nil {
+			t.Errorf("%s: error creating reader: %v", tc.filename, err)
+			continue
+		}
+
+		got, err := ioutil.ReadAll(r)
+		if err != nil {
+			t.Errorf("%s: error reading from charset.NewReader: %v", tc.filename, err)
+			continue
+		}
+
+		e, _ := Lookup(tc.want)
+		want, err := ioutil.ReadAll(transform.NewReader(bytes.NewReader(content), e.NewDecoder()))
+		if err != nil {
+			t.Errorf("%s: error decoding with hard-coded charset name: %v", tc.filename, err)
+			continue
+		}
+
+		if !bytes.Equal(got, want) {
+			t.Errorf("%s: got %q, want %q", tc.filename, got, want)
+			continue
+		}
+	}
+}
+
+var metaTestCases = []struct {
+	meta, want string
+}{
+	{"", ""},
+	{"text/html", ""},
+	{"text/html; charset utf-8", ""},
+	{"text/html; charset=latin-2", "latin-2"},
+	{"text/html; charset; charset = utf-8", "utf-8"},
+	{`charset="big5"`, "big5"},
+	{"charset='shift_jis'", "shift_jis"},
+}
+
+func TestFromMeta(t *testing.T) {
+	for _, tc := range metaTestCases {
+		got := fromMetaElement(tc.meta)
+		if got != tc.want {
+			t.Errorf("%q: got %q, want %q", tc.meta, got, tc.want)
+		}
+	}
+}

+ 107 - 0
third_party/code.google.com/p/go.net/html/charset/gen.go

@@ -0,0 +1,107 @@
+// +build ignore
+
+package main
+
+// Download http://encoding.spec.whatwg.org/encodings.json and use it to
+// generate table.go.
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"net/http"
+	"strings"
+)
+
+type enc struct {
+	Name   string
+	Labels []string
+}
+
+type group struct {
+	Encodings []enc
+	Heading   string
+}
+
+const specURL = "http://encoding.spec.whatwg.org/encodings.json"
+
+func main() {
+	resp, err := http.Get(specURL)
+	if err != nil {
+		log.Fatalf("error fetching %s: %s", specURL, err)
+	}
+	if resp.StatusCode != 200 {
+		log.Fatalf("error fetching %s: HTTP status %s", specURL, resp.Status)
+	}
+	defer resp.Body.Close()
+
+	var groups []group
+	d := json.NewDecoder(resp.Body)
+	err = d.Decode(&groups)
+	if err != nil {
+		log.Fatalf("error reading encodings.json: %s", err)
+	}
+
+	fmt.Println("// generated by go run gen.go; DO NOT EDIT")
+	fmt.Println()
+	fmt.Println("package charset")
+	fmt.Println()
+
+	fmt.Println("import (")
+	fmt.Println(`"code.google.com/p/go.text/encoding"`)
+	for _, pkg := range []string{"charmap", "japanese", "korean", "simplifiedchinese", "traditionalchinese", "unicode"} {
+		fmt.Printf("\"code.google.com/p/go.text/encoding/%s\"\n", pkg)
+	}
+	fmt.Println(")")
+	fmt.Println()
+
+	fmt.Println("var encodings = map[string]struct{e encoding.Encoding; name string} {")
+	for _, g := range groups {
+		for _, e := range g.Encodings {
+			goName, ok := miscNames[e.Name]
+			if !ok {
+				for k, v := range prefixes {
+					if strings.HasPrefix(e.Name, k) {
+						goName = v + e.Name[len(k):]
+						break
+					}
+				}
+				if goName == "" {
+					log.Fatalf("unrecognized encoding name: %s", e.Name)
+				}
+			}
+
+			for _, label := range e.Labels {
+				fmt.Printf("%q: {%s, %q},\n", label, goName, e.Name)
+			}
+		}
+	}
+	fmt.Println("}")
+}
+
+var prefixes = map[string]string{
+	"iso-8859-": "charmap.ISO8859_",
+	"windows-":  "charmap.Windows",
+}
+
+var miscNames = map[string]string{
+	"utf-8":          "encoding.Nop",
+	"ibm866":         "charmap.CodePage866",
+	"iso-8859-8-i":   "charmap.ISO8859_8",
+	"koi8-r":         "charmap.KOI8R",
+	"koi8-u":         "charmap.KOI8U",
+	"macintosh":      "charmap.Macintosh",
+	"x-mac-cyrillic": "charmap.MacintoshCyrillic",
+	"gbk":            "simplifiedchinese.GBK",
+	"gb18030":        "simplifiedchinese.GB18030",
+	"hz-gb-2312":     "simplifiedchinese.HZGB2312",
+	"big5":           "traditionalchinese.Big5",
+	"euc-jp":         "japanese.EUCJP",
+	"iso-2022-jp":    "japanese.ISO2022JP",
+	"shift_jis":      "japanese.ShiftJIS",
+	"euc-kr":         "korean.EUCKR",
+	"replacement":    "encoding.Replacement",
+	"utf-16be":       "unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM)",
+	"utf-16le":       "unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)",
+	"x-user-defined": "charmap.XUserDefined",
+}

+ 235 - 0
third_party/code.google.com/p/go.net/html/charset/table.go

@@ -0,0 +1,235 @@
+// generated by go run gen.go; DO NOT EDIT
+
+package charset
+
+import (
+	"code.google.com/p/go.text/encoding"
+	"code.google.com/p/go.text/encoding/charmap"
+	"code.google.com/p/go.text/encoding/japanese"
+	"code.google.com/p/go.text/encoding/korean"
+	"code.google.com/p/go.text/encoding/simplifiedchinese"
+	"code.google.com/p/go.text/encoding/traditionalchinese"
+	"code.google.com/p/go.text/encoding/unicode"
+)
+
+var encodings = map[string]struct {
+	e    encoding.Encoding
+	name string
+}{
+	"unicode-1-1-utf-8":   {encoding.Nop, "utf-8"},
+	"utf-8":               {encoding.Nop, "utf-8"},
+	"utf8":                {encoding.Nop, "utf-8"},
+	"866":                 {charmap.CodePage866, "ibm866"},
+	"cp866":               {charmap.CodePage866, "ibm866"},
+	"csibm866":            {charmap.CodePage866, "ibm866"},
+	"ibm866":              {charmap.CodePage866, "ibm866"},
+	"csisolatin2":         {charmap.ISO8859_2, "iso-8859-2"},
+	"iso-8859-2":          {charmap.ISO8859_2, "iso-8859-2"},
+	"iso-ir-101":          {charmap.ISO8859_2, "iso-8859-2"},
+	"iso8859-2":           {charmap.ISO8859_2, "iso-8859-2"},
+	"iso88592":            {charmap.ISO8859_2, "iso-8859-2"},
+	"iso_8859-2":          {charmap.ISO8859_2, "iso-8859-2"},
+	"iso_8859-2:1987":     {charmap.ISO8859_2, "iso-8859-2"},
+	"l2":                  {charmap.ISO8859_2, "iso-8859-2"},
+	"latin2":              {charmap.ISO8859_2, "iso-8859-2"},
+	"csisolatin3":         {charmap.ISO8859_3, "iso-8859-3"},
+	"iso-8859-3":          {charmap.ISO8859_3, "iso-8859-3"},
+	"iso-ir-109":          {charmap.ISO8859_3, "iso-8859-3"},
+	"iso8859-3":           {charmap.ISO8859_3, "iso-8859-3"},
+	"iso88593":            {charmap.ISO8859_3, "iso-8859-3"},
+	"iso_8859-3":          {charmap.ISO8859_3, "iso-8859-3"},
+	"iso_8859-3:1988":     {charmap.ISO8859_3, "iso-8859-3"},
+	"l3":                  {charmap.ISO8859_3, "iso-8859-3"},
+	"latin3":              {charmap.ISO8859_3, "iso-8859-3"},
+	"csisolatin4":         {charmap.ISO8859_4, "iso-8859-4"},
+	"iso-8859-4":          {charmap.ISO8859_4, "iso-8859-4"},
+	"iso-ir-110":          {charmap.ISO8859_4, "iso-8859-4"},
+	"iso8859-4":           {charmap.ISO8859_4, "iso-8859-4"},
+	"iso88594":            {charmap.ISO8859_4, "iso-8859-4"},
+	"iso_8859-4":          {charmap.ISO8859_4, "iso-8859-4"},
+	"iso_8859-4:1988":     {charmap.ISO8859_4, "iso-8859-4"},
+	"l4":                  {charmap.ISO8859_4, "iso-8859-4"},
+	"latin4":              {charmap.ISO8859_4, "iso-8859-4"},
+	"csisolatincyrillic":  {charmap.ISO8859_5, "iso-8859-5"},
+	"cyrillic":            {charmap.ISO8859_5, "iso-8859-5"},
+	"iso-8859-5":          {charmap.ISO8859_5, "iso-8859-5"},
+	"iso-ir-144":          {charmap.ISO8859_5, "iso-8859-5"},
+	"iso8859-5":           {charmap.ISO8859_5, "iso-8859-5"},
+	"iso88595":            {charmap.ISO8859_5, "iso-8859-5"},
+	"iso_8859-5":          {charmap.ISO8859_5, "iso-8859-5"},
+	"iso_8859-5:1988":     {charmap.ISO8859_5, "iso-8859-5"},
+	"arabic":              {charmap.ISO8859_6, "iso-8859-6"},
+	"asmo-708":            {charmap.ISO8859_6, "iso-8859-6"},
+	"csiso88596e":         {charmap.ISO8859_6, "iso-8859-6"},
+	"csiso88596i":         {charmap.ISO8859_6, "iso-8859-6"},
+	"csisolatinarabic":    {charmap.ISO8859_6, "iso-8859-6"},
+	"ecma-114":            {charmap.ISO8859_6, "iso-8859-6"},
+	"iso-8859-6":          {charmap.ISO8859_6, "iso-8859-6"},
+	"iso-8859-6-e":        {charmap.ISO8859_6, "iso-8859-6"},
+	"iso-8859-6-i":        {charmap.ISO8859_6, "iso-8859-6"},
+	"iso-ir-127":          {charmap.ISO8859_6, "iso-8859-6"},
+	"iso8859-6":           {charmap.ISO8859_6, "iso-8859-6"},
+	"iso88596":            {charmap.ISO8859_6, "iso-8859-6"},
+	"iso_8859-6":          {charmap.ISO8859_6, "iso-8859-6"},
+	"iso_8859-6:1987":     {charmap.ISO8859_6, "iso-8859-6"},
+	"csisolatingreek":     {charmap.ISO8859_7, "iso-8859-7"},
+	"ecma-118":            {charmap.ISO8859_7, "iso-8859-7"},
+	"elot_928":            {charmap.ISO8859_7, "iso-8859-7"},
+	"greek":               {charmap.ISO8859_7, "iso-8859-7"},
+	"greek8":              {charmap.ISO8859_7, "iso-8859-7"},
+	"iso-8859-7":          {charmap.ISO8859_7, "iso-8859-7"},
+	"iso-ir-126":          {charmap.ISO8859_7, "iso-8859-7"},
+	"iso8859-7":           {charmap.ISO8859_7, "iso-8859-7"},
+	"iso88597":            {charmap.ISO8859_7, "iso-8859-7"},
+	"iso_8859-7":          {charmap.ISO8859_7, "iso-8859-7"},
+	"iso_8859-7:1987":     {charmap.ISO8859_7, "iso-8859-7"},
+	"sun_eu_greek":        {charmap.ISO8859_7, "iso-8859-7"},
+	"csiso88598e":         {charmap.ISO8859_8, "iso-8859-8"},
+	"csisolatinhebrew":    {charmap.ISO8859_8, "iso-8859-8"},
+	"hebrew":              {charmap.ISO8859_8, "iso-8859-8"},
+	"iso-8859-8":          {charmap.ISO8859_8, "iso-8859-8"},
+	"iso-8859-8-e":        {charmap.ISO8859_8, "iso-8859-8"},
+	"iso-ir-138":          {charmap.ISO8859_8, "iso-8859-8"},
+	"iso8859-8":           {charmap.ISO8859_8, "iso-8859-8"},
+	"iso88598":            {charmap.ISO8859_8, "iso-8859-8"},
+	"iso_8859-8":          {charmap.ISO8859_8, "iso-8859-8"},
+	"iso_8859-8:1988":     {charmap.ISO8859_8, "iso-8859-8"},
+	"visual":              {charmap.ISO8859_8, "iso-8859-8"},
+	"csiso88598i":         {charmap.ISO8859_8, "iso-8859-8-i"},
+	"iso-8859-8-i":        {charmap.ISO8859_8, "iso-8859-8-i"},
+	"logical":             {charmap.ISO8859_8, "iso-8859-8-i"},
+	"csisolatin6":         {charmap.ISO8859_10, "iso-8859-10"},
+	"iso-8859-10":         {charmap.ISO8859_10, "iso-8859-10"},
+	"iso-ir-157":          {charmap.ISO8859_10, "iso-8859-10"},
+	"iso8859-10":          {charmap.ISO8859_10, "iso-8859-10"},
+	"iso885910":           {charmap.ISO8859_10, "iso-8859-10"},
+	"l6":                  {charmap.ISO8859_10, "iso-8859-10"},
+	"latin6":              {charmap.ISO8859_10, "iso-8859-10"},
+	"iso-8859-13":         {charmap.ISO8859_13, "iso-8859-13"},
+	"iso8859-13":          {charmap.ISO8859_13, "iso-8859-13"},
+	"iso885913":           {charmap.ISO8859_13, "iso-8859-13"},
+	"iso-8859-14":         {charmap.ISO8859_14, "iso-8859-14"},
+	"iso8859-14":          {charmap.ISO8859_14, "iso-8859-14"},
+	"iso885914":           {charmap.ISO8859_14, "iso-8859-14"},
+	"csisolatin9":         {charmap.ISO8859_15, "iso-8859-15"},
+	"iso-8859-15":         {charmap.ISO8859_15, "iso-8859-15"},
+	"iso8859-15":          {charmap.ISO8859_15, "iso-8859-15"},
+	"iso885915":           {charmap.ISO8859_15, "iso-8859-15"},
+	"iso_8859-15":         {charmap.ISO8859_15, "iso-8859-15"},
+	"l9":                  {charmap.ISO8859_15, "iso-8859-15"},
+	"iso-8859-16":         {charmap.ISO8859_16, "iso-8859-16"},
+	"cskoi8r":             {charmap.KOI8R, "koi8-r"},
+	"koi":                 {charmap.KOI8R, "koi8-r"},
+	"koi8":                {charmap.KOI8R, "koi8-r"},
+	"koi8-r":              {charmap.KOI8R, "koi8-r"},
+	"koi8_r":              {charmap.KOI8R, "koi8-r"},
+	"koi8-u":              {charmap.KOI8U, "koi8-u"},
+	"csmacintosh":         {charmap.Macintosh, "macintosh"},
+	"mac":                 {charmap.Macintosh, "macintosh"},
+	"macintosh":           {charmap.Macintosh, "macintosh"},
+	"x-mac-roman":         {charmap.Macintosh, "macintosh"},
+	"dos-874":             {charmap.Windows874, "windows-874"},
+	"iso-8859-11":         {charmap.Windows874, "windows-874"},
+	"iso8859-11":          {charmap.Windows874, "windows-874"},
+	"iso885911":           {charmap.Windows874, "windows-874"},
+	"tis-620":             {charmap.Windows874, "windows-874"},
+	"windows-874":         {charmap.Windows874, "windows-874"},
+	"cp1250":              {charmap.Windows1250, "windows-1250"},
+	"windows-1250":        {charmap.Windows1250, "windows-1250"},
+	"x-cp1250":            {charmap.Windows1250, "windows-1250"},
+	"cp1251":              {charmap.Windows1251, "windows-1251"},
+	"windows-1251":        {charmap.Windows1251, "windows-1251"},
+	"x-cp1251":            {charmap.Windows1251, "windows-1251"},
+	"ansi_x3.4-1968":      {charmap.Windows1252, "windows-1252"},
+	"ascii":               {charmap.Windows1252, "windows-1252"},
+	"cp1252":              {charmap.Windows1252, "windows-1252"},
+	"cp819":               {charmap.Windows1252, "windows-1252"},
+	"csisolatin1":         {charmap.Windows1252, "windows-1252"},
+	"ibm819":              {charmap.Windows1252, "windows-1252"},
+	"iso-8859-1":          {charmap.Windows1252, "windows-1252"},
+	"iso-ir-100":          {charmap.Windows1252, "windows-1252"},
+	"iso8859-1":           {charmap.Windows1252, "windows-1252"},
+	"iso88591":            {charmap.Windows1252, "windows-1252"},
+	"iso_8859-1":          {charmap.Windows1252, "windows-1252"},
+	"iso_8859-1:1987":     {charmap.Windows1252, "windows-1252"},
+	"l1":                  {charmap.Windows1252, "windows-1252"},
+	"latin1":              {charmap.Windows1252, "windows-1252"},
+	"us-ascii":            {charmap.Windows1252, "windows-1252"},
+	"windows-1252":        {charmap.Windows1252, "windows-1252"},
+	"x-cp1252":            {charmap.Windows1252, "windows-1252"},
+	"cp1253":              {charmap.Windows1253, "windows-1253"},
+	"windows-1253":        {charmap.Windows1253, "windows-1253"},
+	"x-cp1253":            {charmap.Windows1253, "windows-1253"},
+	"cp1254":              {charmap.Windows1254, "windows-1254"},
+	"csisolatin5":         {charmap.Windows1254, "windows-1254"},
+	"iso-8859-9":          {charmap.Windows1254, "windows-1254"},
+	"iso-ir-148":          {charmap.Windows1254, "windows-1254"},
+	"iso8859-9":           {charmap.Windows1254, "windows-1254"},
+	"iso88599":            {charmap.Windows1254, "windows-1254"},
+	"iso_8859-9":          {charmap.Windows1254, "windows-1254"},
+	"iso_8859-9:1989":     {charmap.Windows1254, "windows-1254"},
+	"l5":                  {charmap.Windows1254, "windows-1254"},
+	"latin5":              {charmap.Windows1254, "windows-1254"},
+	"windows-1254":        {charmap.Windows1254, "windows-1254"},
+	"x-cp1254":            {charmap.Windows1254, "windows-1254"},
+	"cp1255":              {charmap.Windows1255, "windows-1255"},
+	"windows-1255":        {charmap.Windows1255, "windows-1255"},
+	"x-cp1255":            {charmap.Windows1255, "windows-1255"},
+	"cp1256":              {charmap.Windows1256, "windows-1256"},
+	"windows-1256":        {charmap.Windows1256, "windows-1256"},
+	"x-cp1256":            {charmap.Windows1256, "windows-1256"},
+	"cp1257":              {charmap.Windows1257, "windows-1257"},
+	"windows-1257":        {charmap.Windows1257, "windows-1257"},
+	"x-cp1257":            {charmap.Windows1257, "windows-1257"},
+	"cp1258":              {charmap.Windows1258, "windows-1258"},
+	"windows-1258":        {charmap.Windows1258, "windows-1258"},
+	"x-cp1258":            {charmap.Windows1258, "windows-1258"},
+	"x-mac-cyrillic":      {charmap.MacintoshCyrillic, "x-mac-cyrillic"},
+	"x-mac-ukrainian":     {charmap.MacintoshCyrillic, "x-mac-cyrillic"},
+	"chinese":             {simplifiedchinese.GBK, "gbk"},
+	"csgb2312":            {simplifiedchinese.GBK, "gbk"},
+	"csiso58gb231280":     {simplifiedchinese.GBK, "gbk"},
+	"gb2312":              {simplifiedchinese.GBK, "gbk"},
+	"gb_2312":             {simplifiedchinese.GBK, "gbk"},
+	"gb_2312-80":          {simplifiedchinese.GBK, "gbk"},
+	"gbk":                 {simplifiedchinese.GBK, "gbk"},
+	"iso-ir-58":           {simplifiedchinese.GBK, "gbk"},
+	"x-gbk":               {simplifiedchinese.GBK, "gbk"},
+	"gb18030":             {simplifiedchinese.GB18030, "gb18030"},
+	"hz-gb-2312":          {simplifiedchinese.HZGB2312, "hz-gb-2312"},
+	"big5":                {traditionalchinese.Big5, "big5"},
+	"big5-hkscs":          {traditionalchinese.Big5, "big5"},
+	"cn-big5":             {traditionalchinese.Big5, "big5"},
+	"csbig5":              {traditionalchinese.Big5, "big5"},
+	"x-x-big5":            {traditionalchinese.Big5, "big5"},
+	"cseucpkdfmtjapanese": {japanese.EUCJP, "euc-jp"},
+	"euc-jp":              {japanese.EUCJP, "euc-jp"},
+	"x-euc-jp":            {japanese.EUCJP, "euc-jp"},
+	"csiso2022jp":         {japanese.ISO2022JP, "iso-2022-jp"},
+	"iso-2022-jp":         {japanese.ISO2022JP, "iso-2022-jp"},
+	"csshiftjis":          {japanese.ShiftJIS, "shift_jis"},
+	"ms_kanji":            {japanese.ShiftJIS, "shift_jis"},
+	"shift-jis":           {japanese.ShiftJIS, "shift_jis"},
+	"shift_jis":           {japanese.ShiftJIS, "shift_jis"},
+	"sjis":                {japanese.ShiftJIS, "shift_jis"},
+	"windows-31j":         {japanese.ShiftJIS, "shift_jis"},
+	"x-sjis":              {japanese.ShiftJIS, "shift_jis"},
+	"cseuckr":             {korean.EUCKR, "euc-kr"},
+	"csksc56011987":       {korean.EUCKR, "euc-kr"},
+	"euc-kr":              {korean.EUCKR, "euc-kr"},
+	"iso-ir-149":          {korean.EUCKR, "euc-kr"},
+	"korean":              {korean.EUCKR, "euc-kr"},
+	"ks_c_5601-1987":      {korean.EUCKR, "euc-kr"},
+	"ks_c_5601-1989":      {korean.EUCKR, "euc-kr"},
+	"ksc5601":             {korean.EUCKR, "euc-kr"},
+	"ksc_5601":            {korean.EUCKR, "euc-kr"},
+	"windows-949":         {korean.EUCKR, "euc-kr"},
+	"csiso2022kr":         {encoding.Replacement, "replacement"},
+	"iso-2022-kr":         {encoding.Replacement, "replacement"},
+	"iso-2022-cn":         {encoding.Replacement, "replacement"},
+	"iso-2022-cn-ext":     {encoding.Replacement, "replacement"},
+	"utf-16be":            {unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM), "utf-16be"},
+	"utf-16":              {unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM), "utf-16le"},
+	"utf-16le":            {unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM), "utf-16le"},
+	"x-user-defined":      {charmap.XUserDefined, "x-user-defined"},
+}

+ 48 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/HTTP-charset.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+  <title>HTTP charset</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="The character encoding of a page can be set using the HTTP header charset declaration.">
+<style type='text/css'>
+.test div { width: 50px; }</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
+</head>
+<body>
+<p class='title'>HTTP charset</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">The character encoding of a page can be set using the HTTP header charset declaration.</p>
+<div class="notes"><p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00C3;&#x0153;&#x00C3;&#x20AC;&#x00C3;&#x0161;</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p><p>The only character encoding declaration for this HTML file is in the HTTP header, which sets the encoding to ISO 8859-15.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-003">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-001<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#basics" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-001" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
+				<li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 48 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+  <title>HTTP vs UTF-8 BOM</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="A character encoding set in the HTTP header has lower precedence than the UTF-8 signature.">
+<style type='text/css'>
+.test div { width: 50px; }</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-utf8.css">
+</head>
+<body>
+<p class='title'>HTTP vs UTF-8 BOM</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">A character encoding set in the HTTP header has lower precedence than the UTF-8 signature.</p>
+<div class="notes"><p><p>The HTTP header attempts to set the character encoding to ISO 8859-15. The page starts with a UTF-8 signature.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00FD;&#x00E4;&#x00E8;</code>. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.</p><p>If the test is unsuccessful, the characters &#x00EF;&#x00BB;&#x00BF; should appear at the top of the page.  These represent the bytes that make up the UTF-8 signature when encountered in the ISO 8859-15 encoding.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-022">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-034<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-034" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
+				<li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 49 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/HTTP-vs-meta-charset.html

@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+ <meta charset="iso-8859-1" > <title>HTTP vs meta charset</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="The HTTP header has a higher precedence than an encoding declaration in a meta charset attribute.">
+<style type='text/css'>
+.test div { width: 50px; }.test div { width: 90px; }
+</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
+</head>
+<body>
+<p class='title'>HTTP vs meta charset</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">The HTTP header has a higher precedence than an encoding declaration in a meta charset attribute.</p>
+<div class="notes"><p><p>The HTTP header attempts to set the character encoding to ISO 8859-15. The page contains an encoding declaration in a meta charset attribute that attempts to set the character encoding to ISO 8859-1.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00C3;&#x0153;&#x00C3;&#x20AC;&#x00C3;&#x0161;</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-037">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-018<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-018" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
+				<li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 49 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/HTTP-vs-meta-content.html

@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=iso-8859-1" > <title>HTTP vs meta content</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="The HTTP header has a higher precedence than an encoding declaration in a meta content attribute.">
+<style type='text/css'>
+.test div { width: 50px; }.test div { width: 90px; }
+</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
+</head>
+<body>
+<p class='title'>HTTP vs meta content</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">The HTTP header has a higher precedence than an encoding declaration in a meta content attribute.</p>
+<div class="notes"><p><p>The HTTP header attempts to set the character encoding to ISO 8859-15. The page contains an encoding declaration in a meta content attribute that attempts to set the character encoding to ISO 8859-1.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00C3;&#x0153;&#x00C3;&#x20AC;&#x00C3;&#x0161;</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-018">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-016<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-016" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
+				<li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 47 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/No-encoding-declaration.html

@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+  <title>No encoding declaration</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="A page with no encoding information in HTTP, BOM, XML declaration or meta element will be treated as UTF-8.">
+<style type='text/css'>
+.test div { width: 50px; }</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-utf8.css">
+</head>
+<body>
+<p class='title'>No encoding declaration</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">A page with no encoding information in HTTP, BOM, XML declaration or meta element will be treated as UTF-8.</p>
+<div class="notes"><p><p>The test on this page contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00FD;&#x00E4;&#x00E8;</code>. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-034">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-015<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#basics" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-015" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 1 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/README

@@ -0,0 +1 @@
+These test cases come from http://www.w3.org/International/tests/html5/the-input-byte-stream/results-basics

BIN
third_party/code.google.com/p/go.net/html/charset/testdata/UTF-16BE-BOM.html


BIN
third_party/code.google.com/p/go.net/html/charset/testdata/UTF-16LE-BOM.html


+ 49 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html

@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+ <meta charset="iso-8859-15"> <title>UTF-8 BOM vs meta charset</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta charset attribute declares a different encoding.">
+<style type='text/css'>
+.test div { width: 50px; }.test div { width: 90px; }
+</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-utf8.css">
+</head>
+<body>
+<p class='title'>UTF-8 BOM vs meta charset</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta charset attribute declares a different encoding.</p>
+<div class="notes"><p><p>The page contains an encoding declaration in a meta charset attribute that attempts to set the character encoding to ISO 8859-15, but the file starts with a UTF-8 signature.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00FD;&#x00E4;&#x00E8;</code>. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-024">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-038<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-038" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
+				<li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 48 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-15"> <title>UTF-8 BOM vs meta content</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta content attribute declares a different encoding.">
+<style type='text/css'>
+.test div { width: 50px; }</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-utf8.css">
+</head>
+<body>
+<p class='title'>UTF-8 BOM vs meta content</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta content attribute declares a different encoding.</p>
+<div class="notes"><p><p>The page contains an encoding declaration in a meta content attribute that attempts to set the character encoding to ISO 8859-15, but the file starts with a UTF-8 signature.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00FD;&#x00E4;&#x00E8;</code>. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-038">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-037<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#precedence" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-037" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
+				<li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 48 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/meta-charset-attribute.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+ <meta charset="iso-8859-15"> <title>meta charset attribute</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="The character encoding of the page can be set by a meta element with charset attribute.">
+<style type='text/css'>
+.test div { width: 50px; }</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
+</head>
+<body>
+<p class='title'>meta charset attribute</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">The character encoding of the page can be set by a meta element with charset attribute.</p>
+<div class="notes"><p><p>The only character encoding declaration for this HTML file is in the charset attribute of the meta element, which declares the encoding to be ISO 8859-15.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00C3;&#x0153;&#x00C3;&#x20AC;&#x00C3;&#x0161;</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-015">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-009<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#basics" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-009" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
+				<li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 48 - 0
third_party/code.google.com/p/go.net/html/charset/testdata/meta-content-attribute.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-15"> <title>meta content attribute</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream'>
+<link rel="stylesheet" type="text/css" href="./generatedtests.css">
+<script src="http://w3c-test.org/resources/testharness.js"></script>
+<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
+<meta name='flags' content='http'>
+<meta name="assert" content="The character encoding of the page can be set by a meta element with http-equiv and content attributes.">
+<style type='text/css'>
+.test div { width: 50px; }</style>
+<link rel="stylesheet" type="text/css" href="the-input-byte-stream/support/encodingtests-15.css">
+</head>
+<body>
+<p class='title'>meta content attribute</p>
+
+
+<div id='log'></div>
+
+
+<div class='test'><div id='box' class='ýäè'>&#xA0;</div></div>
+
+
+
+
+
+<div class='description'>
+<p class="assertion" title="Assertion">The character encoding of the page can be set by a meta element with http-equiv and content attributes.</p>
+<div class="notes"><p><p>The only character encoding declaration for this HTML file is in the content attribute of the meta element, which declares the encoding to be ISO 8859-15.</p><p>The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector <code>.test div.&#x00C3;&#x0153;&#x00C3;&#x20AC;&#x00C3;&#x0161;</code>. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.</p></p>
+</div>
+</div>
+<div class="nexttest"><div><a href="generate?test=the-input-byte-stream-009">Next test</a></div><div class="doctype">HTML5</div>
+<p class="jump">the-input-byte-stream-007<br /><a href="/International/tests/html5/the-input-byte-stream/results-basics#basics" target="_blank">Result summary &amp; related tests</a><br /><a href="http://w3c-test.org/framework/details/i18n-html5/the-input-byte-stream-007" target="_blank">Detailed results for this test</a><br/>	<a href="http://www.w3.org/TR/html5/syntax.html#the-input-byte-stream" target="_blank">Link to spec</a></p>
+<div class='prereq'>Assumptions: <ul><li>The default encoding for the browser you are testing is not set to ISO 8859-15.</li>
+				<li>The test is read from a server that supports HTTP.</li></ul></div>
+</div>
+<script>
+test(function() {
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, " ");
+</script>
+
+</body>
+</html>
+
+

+ 2077 - 2077
third_party/code.google.com/p/go.net/html/entity.go

@@ -75,2083 +75,2083 @@ var entity = map[string]rune{
 	"Copf;":                            '\U00002102',
 	"Coproduct;":                       '\U00002210',
 	"CounterClockwiseContourIntegral;": '\U00002233',
-	"Cross;":                    '\U00002A2F',
-	"Cscr;":                     '\U0001D49E',
-	"Cup;":                      '\U000022D3',
-	"CupCap;":                   '\U0000224D',
-	"DD;":                       '\U00002145',
-	"DDotrahd;":                 '\U00002911',
-	"DJcy;":                     '\U00000402',
-	"DScy;":                     '\U00000405',
-	"DZcy;":                     '\U0000040F',
-	"Dagger;":                   '\U00002021',
-	"Darr;":                     '\U000021A1',
-	"Dashv;":                    '\U00002AE4',
-	"Dcaron;":                   '\U0000010E',
-	"Dcy;":                      '\U00000414',
-	"Del;":                      '\U00002207',
-	"Delta;":                    '\U00000394',
-	"Dfr;":                      '\U0001D507',
-	"DiacriticalAcute;":         '\U000000B4',
-	"DiacriticalDot;":           '\U000002D9',
-	"DiacriticalDoubleAcute;":   '\U000002DD',
-	"DiacriticalGrave;":         '\U00000060',
-	"DiacriticalTilde;":         '\U000002DC',
-	"Diamond;":                  '\U000022C4',
-	"DifferentialD;":            '\U00002146',
-	"Dopf;":                     '\U0001D53B',
-	"Dot;":                      '\U000000A8',
-	"DotDot;":                   '\U000020DC',
-	"DotEqual;":                 '\U00002250',
-	"DoubleContourIntegral;":    '\U0000222F',
-	"DoubleDot;":                '\U000000A8',
-	"DoubleDownArrow;":          '\U000021D3',
-	"DoubleLeftArrow;":          '\U000021D0',
-	"DoubleLeftRightArrow;":     '\U000021D4',
-	"DoubleLeftTee;":            '\U00002AE4',
-	"DoubleLongLeftArrow;":      '\U000027F8',
-	"DoubleLongLeftRightArrow;": '\U000027FA',
-	"DoubleLongRightArrow;":     '\U000027F9',
-	"DoubleRightArrow;":         '\U000021D2',
-	"DoubleRightTee;":           '\U000022A8',
-	"DoubleUpArrow;":            '\U000021D1',
-	"DoubleUpDownArrow;":        '\U000021D5',
-	"DoubleVerticalBar;":        '\U00002225',
-	"DownArrow;":                '\U00002193',
-	"DownArrowBar;":             '\U00002913',
-	"DownArrowUpArrow;":         '\U000021F5',
-	"DownBreve;":                '\U00000311',
-	"DownLeftRightVector;":      '\U00002950',
-	"DownLeftTeeVector;":        '\U0000295E',
-	"DownLeftVector;":           '\U000021BD',
-	"DownLeftVectorBar;":        '\U00002956',
-	"DownRightTeeVector;":       '\U0000295F',
-	"DownRightVector;":          '\U000021C1',
-	"DownRightVectorBar;":       '\U00002957',
-	"DownTee;":                  '\U000022A4',
-	"DownTeeArrow;":             '\U000021A7',
-	"Downarrow;":                '\U000021D3',
-	"Dscr;":                     '\U0001D49F',
-	"Dstrok;":                   '\U00000110',
-	"ENG;":                      '\U0000014A',
-	"ETH;":                      '\U000000D0',
-	"Eacute;":                   '\U000000C9',
-	"Ecaron;":                   '\U0000011A',
-	"Ecirc;":                    '\U000000CA',
-	"Ecy;":                      '\U0000042D',
-	"Edot;":                     '\U00000116',
-	"Efr;":                      '\U0001D508',
-	"Egrave;":                   '\U000000C8',
-	"Element;":                  '\U00002208',
-	"Emacr;":                    '\U00000112',
-	"EmptySmallSquare;":         '\U000025FB',
-	"EmptyVerySmallSquare;":     '\U000025AB',
-	"Eogon;":                    '\U00000118',
-	"Eopf;":                     '\U0001D53C',
-	"Epsilon;":                  '\U00000395',
-	"Equal;":                    '\U00002A75',
-	"EqualTilde;":               '\U00002242',
-	"Equilibrium;":              '\U000021CC',
-	"Escr;":                     '\U00002130',
-	"Esim;":                     '\U00002A73',
-	"Eta;":                      '\U00000397',
-	"Euml;":                     '\U000000CB',
-	"Exists;":                   '\U00002203',
-	"ExponentialE;":             '\U00002147',
-	"Fcy;":                      '\U00000424',
-	"Ffr;":                      '\U0001D509',
-	"FilledSmallSquare;":        '\U000025FC',
-	"FilledVerySmallSquare;":    '\U000025AA',
-	"Fopf;":                     '\U0001D53D',
-	"ForAll;":                   '\U00002200',
-	"Fouriertrf;":               '\U00002131',
-	"Fscr;":                     '\U00002131',
-	"GJcy;":                     '\U00000403',
-	"GT;":                       '\U0000003E',
-	"Gamma;":                    '\U00000393',
-	"Gammad;":                   '\U000003DC',
-	"Gbreve;":                   '\U0000011E',
-	"Gcedil;":                   '\U00000122',
-	"Gcirc;":                    '\U0000011C',
-	"Gcy;":                      '\U00000413',
-	"Gdot;":                     '\U00000120',
-	"Gfr;":                      '\U0001D50A',
-	"Gg;":                       '\U000022D9',
-	"Gopf;":                     '\U0001D53E',
-	"GreaterEqual;":             '\U00002265',
-	"GreaterEqualLess;":         '\U000022DB',
-	"GreaterFullEqual;":         '\U00002267',
-	"GreaterGreater;":           '\U00002AA2',
-	"GreaterLess;":              '\U00002277',
-	"GreaterSlantEqual;":        '\U00002A7E',
-	"GreaterTilde;":             '\U00002273',
-	"Gscr;":                     '\U0001D4A2',
-	"Gt;":                       '\U0000226B',
-	"HARDcy;":                   '\U0000042A',
-	"Hacek;":                    '\U000002C7',
-	"Hat;":                      '\U0000005E',
-	"Hcirc;":                    '\U00000124',
-	"Hfr;":                      '\U0000210C',
-	"HilbertSpace;":             '\U0000210B',
-	"Hopf;":                     '\U0000210D',
-	"HorizontalLine;":           '\U00002500',
-	"Hscr;":                     '\U0000210B',
-	"Hstrok;":                   '\U00000126',
-	"HumpDownHump;":             '\U0000224E',
-	"HumpEqual;":                '\U0000224F',
-	"IEcy;":                     '\U00000415',
-	"IJlig;":                    '\U00000132',
-	"IOcy;":                     '\U00000401',
-	"Iacute;":                   '\U000000CD',
-	"Icirc;":                    '\U000000CE',
-	"Icy;":                      '\U00000418',
-	"Idot;":                     '\U00000130',
-	"Ifr;":                      '\U00002111',
-	"Igrave;":                   '\U000000CC',
-	"Im;":                       '\U00002111',
-	"Imacr;":                    '\U0000012A',
-	"ImaginaryI;":               '\U00002148',
-	"Implies;":                  '\U000021D2',
-	"Int;":                      '\U0000222C',
-	"Integral;":                 '\U0000222B',
-	"Intersection;":             '\U000022C2',
-	"InvisibleComma;":           '\U00002063',
-	"InvisibleTimes;":           '\U00002062',
-	"Iogon;":                    '\U0000012E',
-	"Iopf;":                     '\U0001D540',
-	"Iota;":                     '\U00000399',
-	"Iscr;":                     '\U00002110',
-	"Itilde;":                   '\U00000128',
-	"Iukcy;":                    '\U00000406',
-	"Iuml;":                     '\U000000CF',
-	"Jcirc;":                    '\U00000134',
-	"Jcy;":                      '\U00000419',
-	"Jfr;":                      '\U0001D50D',
-	"Jopf;":                     '\U0001D541',
-	"Jscr;":                     '\U0001D4A5',
-	"Jsercy;":                   '\U00000408',
-	"Jukcy;":                    '\U00000404',
-	"KHcy;":                     '\U00000425',
-	"KJcy;":                     '\U0000040C',
-	"Kappa;":                    '\U0000039A',
-	"Kcedil;":                   '\U00000136',
-	"Kcy;":                      '\U0000041A',
-	"Kfr;":                      '\U0001D50E',
-	"Kopf;":                     '\U0001D542',
-	"Kscr;":                     '\U0001D4A6',
-	"LJcy;":                     '\U00000409',
-	"LT;":                       '\U0000003C',
-	"Lacute;":                   '\U00000139',
-	"Lambda;":                   '\U0000039B',
-	"Lang;":                     '\U000027EA',
-	"Laplacetrf;":               '\U00002112',
-	"Larr;":                     '\U0000219E',
-	"Lcaron;":                   '\U0000013D',
-	"Lcedil;":                   '\U0000013B',
-	"Lcy;":                      '\U0000041B',
-	"LeftAngleBracket;":         '\U000027E8',
-	"LeftArrow;":                '\U00002190',
-	"LeftArrowBar;":             '\U000021E4',
-	"LeftArrowRightArrow;":      '\U000021C6',
-	"LeftCeiling;":              '\U00002308',
-	"LeftDoubleBracket;":        '\U000027E6',
-	"LeftDownTeeVector;":        '\U00002961',
-	"LeftDownVector;":           '\U000021C3',
-	"LeftDownVectorBar;":        '\U00002959',
-	"LeftFloor;":                '\U0000230A',
-	"LeftRightArrow;":           '\U00002194',
-	"LeftRightVector;":          '\U0000294E',
-	"LeftTee;":                  '\U000022A3',
-	"LeftTeeArrow;":             '\U000021A4',
-	"LeftTeeVector;":            '\U0000295A',
-	"LeftTriangle;":             '\U000022B2',
-	"LeftTriangleBar;":          '\U000029CF',
-	"LeftTriangleEqual;":        '\U000022B4',
-	"LeftUpDownVector;":         '\U00002951',
-	"LeftUpTeeVector;":          '\U00002960',
-	"LeftUpVector;":             '\U000021BF',
-	"LeftUpVectorBar;":          '\U00002958',
-	"LeftVector;":               '\U000021BC',
-	"LeftVectorBar;":            '\U00002952',
-	"Leftarrow;":                '\U000021D0',
-	"Leftrightarrow;":           '\U000021D4',
-	"LessEqualGreater;":         '\U000022DA',
-	"LessFullEqual;":            '\U00002266',
-	"LessGreater;":              '\U00002276',
-	"LessLess;":                 '\U00002AA1',
-	"LessSlantEqual;":           '\U00002A7D',
-	"LessTilde;":                '\U00002272',
-	"Lfr;":                      '\U0001D50F',
-	"Ll;":                       '\U000022D8',
-	"Lleftarrow;":               '\U000021DA',
-	"Lmidot;":                   '\U0000013F',
-	"LongLeftArrow;":            '\U000027F5',
-	"LongLeftRightArrow;":       '\U000027F7',
-	"LongRightArrow;":           '\U000027F6',
-	"Longleftarrow;":            '\U000027F8',
-	"Longleftrightarrow;":       '\U000027FA',
-	"Longrightarrow;":           '\U000027F9',
-	"Lopf;":                     '\U0001D543',
-	"LowerLeftArrow;":           '\U00002199',
-	"LowerRightArrow;":          '\U00002198',
-	"Lscr;":                     '\U00002112',
-	"Lsh;":                      '\U000021B0',
-	"Lstrok;":                   '\U00000141',
-	"Lt;":                       '\U0000226A',
-	"Map;":                      '\U00002905',
-	"Mcy;":                      '\U0000041C',
-	"MediumSpace;":              '\U0000205F',
-	"Mellintrf;":                '\U00002133',
-	"Mfr;":                      '\U0001D510',
-	"MinusPlus;":                '\U00002213',
-	"Mopf;":                     '\U0001D544',
-	"Mscr;":                     '\U00002133',
-	"Mu;":                       '\U0000039C',
-	"NJcy;":                     '\U0000040A',
-	"Nacute;":                   '\U00000143',
-	"Ncaron;":                   '\U00000147',
-	"Ncedil;":                   '\U00000145',
-	"Ncy;":                      '\U0000041D',
-	"NegativeMediumSpace;":      '\U0000200B',
-	"NegativeThickSpace;":       '\U0000200B',
-	"NegativeThinSpace;":        '\U0000200B',
-	"NegativeVeryThinSpace;":    '\U0000200B',
-	"NestedGreaterGreater;":     '\U0000226B',
-	"NestedLessLess;":           '\U0000226A',
-	"NewLine;":                  '\U0000000A',
-	"Nfr;":                      '\U0001D511',
-	"NoBreak;":                  '\U00002060',
-	"NonBreakingSpace;":         '\U000000A0',
-	"Nopf;":                     '\U00002115',
-	"Not;":                      '\U00002AEC',
-	"NotCongruent;":             '\U00002262',
-	"NotCupCap;":                '\U0000226D',
-	"NotDoubleVerticalBar;":     '\U00002226',
-	"NotElement;":               '\U00002209',
-	"NotEqual;":                 '\U00002260',
-	"NotExists;":                '\U00002204',
-	"NotGreater;":               '\U0000226F',
-	"NotGreaterEqual;":          '\U00002271',
-	"NotGreaterLess;":           '\U00002279',
-	"NotGreaterTilde;":          '\U00002275',
-	"NotLeftTriangle;":          '\U000022EA',
-	"NotLeftTriangleEqual;":     '\U000022EC',
-	"NotLess;":                  '\U0000226E',
-	"NotLessEqual;":             '\U00002270',
-	"NotLessGreater;":           '\U00002278',
-	"NotLessTilde;":             '\U00002274',
-	"NotPrecedes;":              '\U00002280',
-	"NotPrecedesSlantEqual;":    '\U000022E0',
-	"NotReverseElement;":        '\U0000220C',
-	"NotRightTriangle;":         '\U000022EB',
-	"NotRightTriangleEqual;":    '\U000022ED',
-	"NotSquareSubsetEqual;":     '\U000022E2',
-	"NotSquareSupersetEqual;":   '\U000022E3',
-	"NotSubsetEqual;":           '\U00002288',
-	"NotSucceeds;":              '\U00002281',
-	"NotSucceedsSlantEqual;":    '\U000022E1',
-	"NotSupersetEqual;":         '\U00002289',
-	"NotTilde;":                 '\U00002241',
-	"NotTildeEqual;":            '\U00002244',
-	"NotTildeFullEqual;":        '\U00002247',
-	"NotTildeTilde;":            '\U00002249',
-	"NotVerticalBar;":           '\U00002224',
-	"Nscr;":                     '\U0001D4A9',
-	"Ntilde;":                   '\U000000D1',
-	"Nu;":                       '\U0000039D',
-	"OElig;":                    '\U00000152',
-	"Oacute;":                   '\U000000D3',
-	"Ocirc;":                    '\U000000D4',
-	"Ocy;":                      '\U0000041E',
-	"Odblac;":                   '\U00000150',
-	"Ofr;":                      '\U0001D512',
-	"Ograve;":                   '\U000000D2',
-	"Omacr;":                    '\U0000014C',
-	"Omega;":                    '\U000003A9',
-	"Omicron;":                  '\U0000039F',
-	"Oopf;":                     '\U0001D546',
-	"OpenCurlyDoubleQuote;":     '\U0000201C',
-	"OpenCurlyQuote;":           '\U00002018',
-	"Or;":                       '\U00002A54',
-	"Oscr;":                     '\U0001D4AA',
-	"Oslash;":                   '\U000000D8',
-	"Otilde;":                   '\U000000D5',
-	"Otimes;":                   '\U00002A37',
-	"Ouml;":                     '\U000000D6',
-	"OverBar;":                  '\U0000203E',
-	"OverBrace;":                '\U000023DE',
-	"OverBracket;":              '\U000023B4',
-	"OverParenthesis;":          '\U000023DC',
-	"PartialD;":                 '\U00002202',
-	"Pcy;":                      '\U0000041F',
-	"Pfr;":                      '\U0001D513',
-	"Phi;":                      '\U000003A6',
-	"Pi;":                       '\U000003A0',
-	"PlusMinus;":                '\U000000B1',
-	"Poincareplane;":            '\U0000210C',
-	"Popf;":                     '\U00002119',
-	"Pr;":                       '\U00002ABB',
-	"Precedes;":                 '\U0000227A',
-	"PrecedesEqual;":            '\U00002AAF',
-	"PrecedesSlantEqual;":       '\U0000227C',
-	"PrecedesTilde;":            '\U0000227E',
-	"Prime;":                    '\U00002033',
-	"Product;":                  '\U0000220F',
-	"Proportion;":               '\U00002237',
-	"Proportional;":             '\U0000221D',
-	"Pscr;":                     '\U0001D4AB',
-	"Psi;":                      '\U000003A8',
-	"QUOT;":                     '\U00000022',
-	"Qfr;":                      '\U0001D514',
-	"Qopf;":                     '\U0000211A',
-	"Qscr;":                     '\U0001D4AC',
-	"RBarr;":                    '\U00002910',
-	"REG;":                      '\U000000AE',
-	"Racute;":                   '\U00000154',
-	"Rang;":                     '\U000027EB',
-	"Rarr;":                     '\U000021A0',
-	"Rarrtl;":                   '\U00002916',
-	"Rcaron;":                   '\U00000158',
-	"Rcedil;":                   '\U00000156',
-	"Rcy;":                      '\U00000420',
-	"Re;":                       '\U0000211C',
-	"ReverseElement;":           '\U0000220B',
-	"ReverseEquilibrium;":       '\U000021CB',
-	"ReverseUpEquilibrium;":     '\U0000296F',
-	"Rfr;":                      '\U0000211C',
-	"Rho;":                      '\U000003A1',
-	"RightAngleBracket;":        '\U000027E9',
-	"RightArrow;":               '\U00002192',
-	"RightArrowBar;":            '\U000021E5',
-	"RightArrowLeftArrow;":      '\U000021C4',
-	"RightCeiling;":             '\U00002309',
-	"RightDoubleBracket;":       '\U000027E7',
-	"RightDownTeeVector;":       '\U0000295D',
-	"RightDownVector;":          '\U000021C2',
-	"RightDownVectorBar;":       '\U00002955',
-	"RightFloor;":               '\U0000230B',
-	"RightTee;":                 '\U000022A2',
-	"RightTeeArrow;":            '\U000021A6',
-	"RightTeeVector;":           '\U0000295B',
-	"RightTriangle;":            '\U000022B3',
-	"RightTriangleBar;":         '\U000029D0',
-	"RightTriangleEqual;":       '\U000022B5',
-	"RightUpDownVector;":        '\U0000294F',
-	"RightUpTeeVector;":         '\U0000295C',
-	"RightUpVector;":            '\U000021BE',
-	"RightUpVectorBar;":         '\U00002954',
-	"RightVector;":              '\U000021C0',
-	"RightVectorBar;":           '\U00002953',
-	"Rightarrow;":               '\U000021D2',
-	"Ropf;":                     '\U0000211D',
-	"RoundImplies;":             '\U00002970',
-	"Rrightarrow;":              '\U000021DB',
-	"Rscr;":                     '\U0000211B',
-	"Rsh;":                      '\U000021B1',
-	"RuleDelayed;":              '\U000029F4',
-	"SHCHcy;":                   '\U00000429',
-	"SHcy;":                     '\U00000428',
-	"SOFTcy;":                   '\U0000042C',
-	"Sacute;":                   '\U0000015A',
-	"Sc;":                       '\U00002ABC',
-	"Scaron;":                   '\U00000160',
-	"Scedil;":                   '\U0000015E',
-	"Scirc;":                    '\U0000015C',
-	"Scy;":                      '\U00000421',
-	"Sfr;":                      '\U0001D516',
-	"ShortDownArrow;":           '\U00002193',
-	"ShortLeftArrow;":           '\U00002190',
-	"ShortRightArrow;":          '\U00002192',
-	"ShortUpArrow;":             '\U00002191',
-	"Sigma;":                    '\U000003A3',
-	"SmallCircle;":              '\U00002218',
-	"Sopf;":                     '\U0001D54A',
-	"Sqrt;":                     '\U0000221A',
-	"Square;":                   '\U000025A1',
-	"SquareIntersection;":       '\U00002293',
-	"SquareSubset;":             '\U0000228F',
-	"SquareSubsetEqual;":        '\U00002291',
-	"SquareSuperset;":           '\U00002290',
-	"SquareSupersetEqual;":      '\U00002292',
-	"SquareUnion;":              '\U00002294',
-	"Sscr;":                     '\U0001D4AE',
-	"Star;":                     '\U000022C6',
-	"Sub;":                      '\U000022D0',
-	"Subset;":                   '\U000022D0',
-	"SubsetEqual;":              '\U00002286',
-	"Succeeds;":                 '\U0000227B',
-	"SucceedsEqual;":            '\U00002AB0',
-	"SucceedsSlantEqual;":       '\U0000227D',
-	"SucceedsTilde;":            '\U0000227F',
-	"SuchThat;":                 '\U0000220B',
-	"Sum;":                      '\U00002211',
-	"Sup;":                      '\U000022D1',
-	"Superset;":                 '\U00002283',
-	"SupersetEqual;":            '\U00002287',
-	"Supset;":                   '\U000022D1',
-	"THORN;":                    '\U000000DE',
-	"TRADE;":                    '\U00002122',
-	"TSHcy;":                    '\U0000040B',
-	"TScy;":                     '\U00000426',
-	"Tab;":                      '\U00000009',
-	"Tau;":                      '\U000003A4',
-	"Tcaron;":                   '\U00000164',
-	"Tcedil;":                   '\U00000162',
-	"Tcy;":                      '\U00000422',
-	"Tfr;":                      '\U0001D517',
-	"Therefore;":                '\U00002234',
-	"Theta;":                    '\U00000398',
-	"ThinSpace;":                '\U00002009',
-	"Tilde;":                    '\U0000223C',
-	"TildeEqual;":               '\U00002243',
-	"TildeFullEqual;":           '\U00002245',
-	"TildeTilde;":               '\U00002248',
-	"Topf;":                     '\U0001D54B',
-	"TripleDot;":                '\U000020DB',
-	"Tscr;":                     '\U0001D4AF',
-	"Tstrok;":                   '\U00000166',
-	"Uacute;":                   '\U000000DA',
-	"Uarr;":                     '\U0000219F',
-	"Uarrocir;":                 '\U00002949',
-	"Ubrcy;":                    '\U0000040E',
-	"Ubreve;":                   '\U0000016C',
-	"Ucirc;":                    '\U000000DB',
-	"Ucy;":                      '\U00000423',
-	"Udblac;":                   '\U00000170',
-	"Ufr;":                      '\U0001D518',
-	"Ugrave;":                   '\U000000D9',
-	"Umacr;":                    '\U0000016A',
-	"UnderBar;":                 '\U0000005F',
-	"UnderBrace;":               '\U000023DF',
-	"UnderBracket;":             '\U000023B5',
-	"UnderParenthesis;":         '\U000023DD',
-	"Union;":                    '\U000022C3',
-	"UnionPlus;":                '\U0000228E',
-	"Uogon;":                    '\U00000172',
-	"Uopf;":                     '\U0001D54C',
-	"UpArrow;":                  '\U00002191',
-	"UpArrowBar;":               '\U00002912',
-	"UpArrowDownArrow;":         '\U000021C5',
-	"UpDownArrow;":              '\U00002195',
-	"UpEquilibrium;":            '\U0000296E',
-	"UpTee;":                    '\U000022A5',
-	"UpTeeArrow;":               '\U000021A5',
-	"Uparrow;":                  '\U000021D1',
-	"Updownarrow;":              '\U000021D5',
-	"UpperLeftArrow;":           '\U00002196',
-	"UpperRightArrow;":          '\U00002197',
-	"Upsi;":                     '\U000003D2',
-	"Upsilon;":                  '\U000003A5',
-	"Uring;":                    '\U0000016E',
-	"Uscr;":                     '\U0001D4B0',
-	"Utilde;":                   '\U00000168',
-	"Uuml;":                     '\U000000DC',
-	"VDash;":                    '\U000022AB',
-	"Vbar;":                     '\U00002AEB',
-	"Vcy;":                      '\U00000412',
-	"Vdash;":                    '\U000022A9',
-	"Vdashl;":                   '\U00002AE6',
-	"Vee;":                      '\U000022C1',
-	"Verbar;":                   '\U00002016',
-	"Vert;":                     '\U00002016',
-	"VerticalBar;":              '\U00002223',
-	"VerticalLine;":             '\U0000007C',
-	"VerticalSeparator;":        '\U00002758',
-	"VerticalTilde;":            '\U00002240',
-	"VeryThinSpace;":            '\U0000200A',
-	"Vfr;":                      '\U0001D519',
-	"Vopf;":                     '\U0001D54D',
-	"Vscr;":                     '\U0001D4B1',
-	"Vvdash;":                   '\U000022AA',
-	"Wcirc;":                    '\U00000174',
-	"Wedge;":                    '\U000022C0',
-	"Wfr;":                      '\U0001D51A',
-	"Wopf;":                     '\U0001D54E',
-	"Wscr;":                     '\U0001D4B2',
-	"Xfr;":                      '\U0001D51B',
-	"Xi;":                       '\U0000039E',
-	"Xopf;":                     '\U0001D54F',
-	"Xscr;":                     '\U0001D4B3',
-	"YAcy;":                     '\U0000042F',
-	"YIcy;":                     '\U00000407',
-	"YUcy;":                     '\U0000042E',
-	"Yacute;":                   '\U000000DD',
-	"Ycirc;":                    '\U00000176',
-	"Ycy;":                      '\U0000042B',
-	"Yfr;":                      '\U0001D51C',
-	"Yopf;":                     '\U0001D550',
-	"Yscr;":                     '\U0001D4B4',
-	"Yuml;":                     '\U00000178',
-	"ZHcy;":                     '\U00000416',
-	"Zacute;":                   '\U00000179',
-	"Zcaron;":                   '\U0000017D',
-	"Zcy;":                      '\U00000417',
-	"Zdot;":                     '\U0000017B',
-	"ZeroWidthSpace;":           '\U0000200B',
-	"Zeta;":                     '\U00000396',
-	"Zfr;":                      '\U00002128',
-	"Zopf;":                     '\U00002124',
-	"Zscr;":                     '\U0001D4B5',
-	"aacute;":                   '\U000000E1',
-	"abreve;":                   '\U00000103',
-	"ac;":                       '\U0000223E',
-	"acd;":                      '\U0000223F',
-	"acirc;":                    '\U000000E2',
-	"acute;":                    '\U000000B4',
-	"acy;":                      '\U00000430',
-	"aelig;":                    '\U000000E6',
-	"af;":                       '\U00002061',
-	"afr;":                      '\U0001D51E',
-	"agrave;":                   '\U000000E0',
-	"alefsym;":                  '\U00002135',
-	"aleph;":                    '\U00002135',
-	"alpha;":                    '\U000003B1',
-	"amacr;":                    '\U00000101',
-	"amalg;":                    '\U00002A3F',
-	"amp;":                      '\U00000026',
-	"and;":                      '\U00002227',
-	"andand;":                   '\U00002A55',
-	"andd;":                     '\U00002A5C',
-	"andslope;":                 '\U00002A58',
-	"andv;":                     '\U00002A5A',
-	"ang;":                      '\U00002220',
-	"ange;":                     '\U000029A4',
-	"angle;":                    '\U00002220',
-	"angmsd;":                   '\U00002221',
-	"angmsdaa;":                 '\U000029A8',
-	"angmsdab;":                 '\U000029A9',
-	"angmsdac;":                 '\U000029AA',
-	"angmsdad;":                 '\U000029AB',
-	"angmsdae;":                 '\U000029AC',
-	"angmsdaf;":                 '\U000029AD',
-	"angmsdag;":                 '\U000029AE',
-	"angmsdah;":                 '\U000029AF',
-	"angrt;":                    '\U0000221F',
-	"angrtvb;":                  '\U000022BE',
-	"angrtvbd;":                 '\U0000299D',
-	"angsph;":                   '\U00002222',
-	"angst;":                    '\U000000C5',
-	"angzarr;":                  '\U0000237C',
-	"aogon;":                    '\U00000105',
-	"aopf;":                     '\U0001D552',
-	"ap;":                       '\U00002248',
-	"apE;":                      '\U00002A70',
-	"apacir;":                   '\U00002A6F',
-	"ape;":                      '\U0000224A',
-	"apid;":                     '\U0000224B',
-	"apos;":                     '\U00000027',
-	"approx;":                   '\U00002248',
-	"approxeq;":                 '\U0000224A',
-	"aring;":                    '\U000000E5',
-	"ascr;":                     '\U0001D4B6',
-	"ast;":                      '\U0000002A',
-	"asymp;":                    '\U00002248',
-	"asympeq;":                  '\U0000224D',
-	"atilde;":                   '\U000000E3',
-	"auml;":                     '\U000000E4',
-	"awconint;":                 '\U00002233',
-	"awint;":                    '\U00002A11',
-	"bNot;":                     '\U00002AED',
-	"backcong;":                 '\U0000224C',
-	"backepsilon;":              '\U000003F6',
-	"backprime;":                '\U00002035',
-	"backsim;":                  '\U0000223D',
-	"backsimeq;":                '\U000022CD',
-	"barvee;":                   '\U000022BD',
-	"barwed;":                   '\U00002305',
-	"barwedge;":                 '\U00002305',
-	"bbrk;":                     '\U000023B5',
-	"bbrktbrk;":                 '\U000023B6',
-	"bcong;":                    '\U0000224C',
-	"bcy;":                      '\U00000431',
-	"bdquo;":                    '\U0000201E',
-	"becaus;":                   '\U00002235',
-	"because;":                  '\U00002235',
-	"bemptyv;":                  '\U000029B0',
-	"bepsi;":                    '\U000003F6',
-	"bernou;":                   '\U0000212C',
-	"beta;":                     '\U000003B2',
-	"beth;":                     '\U00002136',
-	"between;":                  '\U0000226C',
-	"bfr;":                      '\U0001D51F',
-	"bigcap;":                   '\U000022C2',
-	"bigcirc;":                  '\U000025EF',
-	"bigcup;":                   '\U000022C3',
-	"bigodot;":                  '\U00002A00',
-	"bigoplus;":                 '\U00002A01',
-	"bigotimes;":                '\U00002A02',
-	"bigsqcup;":                 '\U00002A06',
-	"bigstar;":                  '\U00002605',
-	"bigtriangledown;":          '\U000025BD',
-	"bigtriangleup;":            '\U000025B3',
-	"biguplus;":                 '\U00002A04',
-	"bigvee;":                   '\U000022C1',
-	"bigwedge;":                 '\U000022C0',
-	"bkarow;":                   '\U0000290D',
-	"blacklozenge;":             '\U000029EB',
-	"blacksquare;":              '\U000025AA',
-	"blacktriangle;":            '\U000025B4',
-	"blacktriangledown;":        '\U000025BE',
-	"blacktriangleleft;":        '\U000025C2',
-	"blacktriangleright;":       '\U000025B8',
-	"blank;":                    '\U00002423',
-	"blk12;":                    '\U00002592',
-	"blk14;":                    '\U00002591',
-	"blk34;":                    '\U00002593',
-	"block;":                    '\U00002588',
-	"bnot;":                     '\U00002310',
-	"bopf;":                     '\U0001D553',
-	"bot;":                      '\U000022A5',
-	"bottom;":                   '\U000022A5',
-	"bowtie;":                   '\U000022C8',
-	"boxDL;":                    '\U00002557',
-	"boxDR;":                    '\U00002554',
-	"boxDl;":                    '\U00002556',
-	"boxDr;":                    '\U00002553',
-	"boxH;":                     '\U00002550',
-	"boxHD;":                    '\U00002566',
-	"boxHU;":                    '\U00002569',
-	"boxHd;":                    '\U00002564',
-	"boxHu;":                    '\U00002567',
-	"boxUL;":                    '\U0000255D',
-	"boxUR;":                    '\U0000255A',
-	"boxUl;":                    '\U0000255C',
-	"boxUr;":                    '\U00002559',
-	"boxV;":                     '\U00002551',
-	"boxVH;":                    '\U0000256C',
-	"boxVL;":                    '\U00002563',
-	"boxVR;":                    '\U00002560',
-	"boxVh;":                    '\U0000256B',
-	"boxVl;":                    '\U00002562',
-	"boxVr;":                    '\U0000255F',
-	"boxbox;":                   '\U000029C9',
-	"boxdL;":                    '\U00002555',
-	"boxdR;":                    '\U00002552',
-	"boxdl;":                    '\U00002510',
-	"boxdr;":                    '\U0000250C',
-	"boxh;":                     '\U00002500',
-	"boxhD;":                    '\U00002565',
-	"boxhU;":                    '\U00002568',
-	"boxhd;":                    '\U0000252C',
-	"boxhu;":                    '\U00002534',
-	"boxminus;":                 '\U0000229F',
-	"boxplus;":                  '\U0000229E',
-	"boxtimes;":                 '\U000022A0',
-	"boxuL;":                    '\U0000255B',
-	"boxuR;":                    '\U00002558',
-	"boxul;":                    '\U00002518',
-	"boxur;":                    '\U00002514',
-	"boxv;":                     '\U00002502',
-	"boxvH;":                    '\U0000256A',
-	"boxvL;":                    '\U00002561',
-	"boxvR;":                    '\U0000255E',
-	"boxvh;":                    '\U0000253C',
-	"boxvl;":                    '\U00002524',
-	"boxvr;":                    '\U0000251C',
-	"bprime;":                   '\U00002035',
-	"breve;":                    '\U000002D8',
-	"brvbar;":                   '\U000000A6',
-	"bscr;":                     '\U0001D4B7',
-	"bsemi;":                    '\U0000204F',
-	"bsim;":                     '\U0000223D',
-	"bsime;":                    '\U000022CD',
-	"bsol;":                     '\U0000005C',
-	"bsolb;":                    '\U000029C5',
-	"bsolhsub;":                 '\U000027C8',
-	"bull;":                     '\U00002022',
-	"bullet;":                   '\U00002022',
-	"bump;":                     '\U0000224E',
-	"bumpE;":                    '\U00002AAE',
-	"bumpe;":                    '\U0000224F',
-	"bumpeq;":                   '\U0000224F',
-	"cacute;":                   '\U00000107',
-	"cap;":                      '\U00002229',
-	"capand;":                   '\U00002A44',
-	"capbrcup;":                 '\U00002A49',
-	"capcap;":                   '\U00002A4B',
-	"capcup;":                   '\U00002A47',
-	"capdot;":                   '\U00002A40',
-	"caret;":                    '\U00002041',
-	"caron;":                    '\U000002C7',
-	"ccaps;":                    '\U00002A4D',
-	"ccaron;":                   '\U0000010D',
-	"ccedil;":                   '\U000000E7',
-	"ccirc;":                    '\U00000109',
-	"ccups;":                    '\U00002A4C',
-	"ccupssm;":                  '\U00002A50',
-	"cdot;":                     '\U0000010B',
-	"cedil;":                    '\U000000B8',
-	"cemptyv;":                  '\U000029B2',
-	"cent;":                     '\U000000A2',
-	"centerdot;":                '\U000000B7',
-	"cfr;":                      '\U0001D520',
-	"chcy;":                     '\U00000447',
-	"check;":                    '\U00002713',
-	"checkmark;":                '\U00002713',
-	"chi;":                      '\U000003C7',
-	"cir;":                      '\U000025CB',
-	"cirE;":                     '\U000029C3',
-	"circ;":                     '\U000002C6',
-	"circeq;":                   '\U00002257',
-	"circlearrowleft;":          '\U000021BA',
-	"circlearrowright;":         '\U000021BB',
-	"circledR;":                 '\U000000AE',
-	"circledS;":                 '\U000024C8',
-	"circledast;":               '\U0000229B',
-	"circledcirc;":              '\U0000229A',
-	"circleddash;":              '\U0000229D',
-	"cire;":                     '\U00002257',
-	"cirfnint;":                 '\U00002A10',
-	"cirmid;":                   '\U00002AEF',
-	"cirscir;":                  '\U000029C2',
-	"clubs;":                    '\U00002663',
-	"clubsuit;":                 '\U00002663',
-	"colon;":                    '\U0000003A',
-	"colone;":                   '\U00002254',
-	"coloneq;":                  '\U00002254',
-	"comma;":                    '\U0000002C',
-	"commat;":                   '\U00000040',
-	"comp;":                     '\U00002201',
-	"compfn;":                   '\U00002218',
-	"complement;":               '\U00002201',
-	"complexes;":                '\U00002102',
-	"cong;":                     '\U00002245',
-	"congdot;":                  '\U00002A6D',
-	"conint;":                   '\U0000222E',
-	"copf;":                     '\U0001D554',
-	"coprod;":                   '\U00002210',
-	"copy;":                     '\U000000A9',
-	"copysr;":                   '\U00002117',
-	"crarr;":                    '\U000021B5',
-	"cross;":                    '\U00002717',
-	"cscr;":                     '\U0001D4B8',
-	"csub;":                     '\U00002ACF',
-	"csube;":                    '\U00002AD1',
-	"csup;":                     '\U00002AD0',
-	"csupe;":                    '\U00002AD2',
-	"ctdot;":                    '\U000022EF',
-	"cudarrl;":                  '\U00002938',
-	"cudarrr;":                  '\U00002935',
-	"cuepr;":                    '\U000022DE',
-	"cuesc;":                    '\U000022DF',
-	"cularr;":                   '\U000021B6',
-	"cularrp;":                  '\U0000293D',
-	"cup;":                      '\U0000222A',
-	"cupbrcap;":                 '\U00002A48',
-	"cupcap;":                   '\U00002A46',
-	"cupcup;":                   '\U00002A4A',
-	"cupdot;":                   '\U0000228D',
-	"cupor;":                    '\U00002A45',
-	"curarr;":                   '\U000021B7',
-	"curarrm;":                  '\U0000293C',
-	"curlyeqprec;":              '\U000022DE',
-	"curlyeqsucc;":              '\U000022DF',
-	"curlyvee;":                 '\U000022CE',
-	"curlywedge;":               '\U000022CF',
-	"curren;":                   '\U000000A4',
-	"curvearrowleft;":           '\U000021B6',
-	"curvearrowright;":          '\U000021B7',
-	"cuvee;":                    '\U000022CE',
-	"cuwed;":                    '\U000022CF',
-	"cwconint;":                 '\U00002232',
-	"cwint;":                    '\U00002231',
-	"cylcty;":                   '\U0000232D',
-	"dArr;":                     '\U000021D3',
-	"dHar;":                     '\U00002965',
-	"dagger;":                   '\U00002020',
-	"daleth;":                   '\U00002138',
-	"darr;":                     '\U00002193',
-	"dash;":                     '\U00002010',
-	"dashv;":                    '\U000022A3',
-	"dbkarow;":                  '\U0000290F',
-	"dblac;":                    '\U000002DD',
-	"dcaron;":                   '\U0000010F',
-	"dcy;":                      '\U00000434',
-	"dd;":                       '\U00002146',
-	"ddagger;":                  '\U00002021',
-	"ddarr;":                    '\U000021CA',
-	"ddotseq;":                  '\U00002A77',
-	"deg;":                      '\U000000B0',
-	"delta;":                    '\U000003B4',
-	"demptyv;":                  '\U000029B1',
-	"dfisht;":                   '\U0000297F',
-	"dfr;":                      '\U0001D521',
-	"dharl;":                    '\U000021C3',
-	"dharr;":                    '\U000021C2',
-	"diam;":                     '\U000022C4',
-	"diamond;":                  '\U000022C4',
-	"diamondsuit;":              '\U00002666',
-	"diams;":                    '\U00002666',
-	"die;":                      '\U000000A8',
-	"digamma;":                  '\U000003DD',
-	"disin;":                    '\U000022F2',
-	"div;":                      '\U000000F7',
-	"divide;":                   '\U000000F7',
-	"divideontimes;":            '\U000022C7',
-	"divonx;":                   '\U000022C7',
-	"djcy;":                     '\U00000452',
-	"dlcorn;":                   '\U0000231E',
-	"dlcrop;":                   '\U0000230D',
-	"dollar;":                   '\U00000024',
-	"dopf;":                     '\U0001D555',
-	"dot;":                      '\U000002D9',
-	"doteq;":                    '\U00002250',
-	"doteqdot;":                 '\U00002251',
-	"dotminus;":                 '\U00002238',
-	"dotplus;":                  '\U00002214',
-	"dotsquare;":                '\U000022A1',
-	"doublebarwedge;":           '\U00002306',
-	"downarrow;":                '\U00002193',
-	"downdownarrows;":           '\U000021CA',
-	"downharpoonleft;":          '\U000021C3',
-	"downharpoonright;":         '\U000021C2',
-	"drbkarow;":                 '\U00002910',
-	"drcorn;":                   '\U0000231F',
-	"drcrop;":                   '\U0000230C',
-	"dscr;":                     '\U0001D4B9',
-	"dscy;":                     '\U00000455',
-	"dsol;":                     '\U000029F6',
-	"dstrok;":                   '\U00000111',
-	"dtdot;":                    '\U000022F1',
-	"dtri;":                     '\U000025BF',
-	"dtrif;":                    '\U000025BE',
-	"duarr;":                    '\U000021F5',
-	"duhar;":                    '\U0000296F',
-	"dwangle;":                  '\U000029A6',
-	"dzcy;":                     '\U0000045F',
-	"dzigrarr;":                 '\U000027FF',
-	"eDDot;":                    '\U00002A77',
-	"eDot;":                     '\U00002251',
-	"eacute;":                   '\U000000E9',
-	"easter;":                   '\U00002A6E',
-	"ecaron;":                   '\U0000011B',
-	"ecir;":                     '\U00002256',
-	"ecirc;":                    '\U000000EA',
-	"ecolon;":                   '\U00002255',
-	"ecy;":                      '\U0000044D',
-	"edot;":                     '\U00000117',
-	"ee;":                       '\U00002147',
-	"efDot;":                    '\U00002252',
-	"efr;":                      '\U0001D522',
-	"eg;":                       '\U00002A9A',
-	"egrave;":                   '\U000000E8',
-	"egs;":                      '\U00002A96',
-	"egsdot;":                   '\U00002A98',
-	"el;":                       '\U00002A99',
-	"elinters;":                 '\U000023E7',
-	"ell;":                      '\U00002113',
-	"els;":                      '\U00002A95',
-	"elsdot;":                   '\U00002A97',
-	"emacr;":                    '\U00000113',
-	"empty;":                    '\U00002205',
-	"emptyset;":                 '\U00002205',
-	"emptyv;":                   '\U00002205',
-	"emsp;":                     '\U00002003',
-	"emsp13;":                   '\U00002004',
-	"emsp14;":                   '\U00002005',
-	"eng;":                      '\U0000014B',
-	"ensp;":                     '\U00002002',
-	"eogon;":                    '\U00000119',
-	"eopf;":                     '\U0001D556',
-	"epar;":                     '\U000022D5',
-	"eparsl;":                   '\U000029E3',
-	"eplus;":                    '\U00002A71',
-	"epsi;":                     '\U000003B5',
-	"epsilon;":                  '\U000003B5',
-	"epsiv;":                    '\U000003F5',
-	"eqcirc;":                   '\U00002256',
-	"eqcolon;":                  '\U00002255',
-	"eqsim;":                    '\U00002242',
-	"eqslantgtr;":               '\U00002A96',
-	"eqslantless;":              '\U00002A95',
-	"equals;":                   '\U0000003D',
-	"equest;":                   '\U0000225F',
-	"equiv;":                    '\U00002261',
-	"equivDD;":                  '\U00002A78',
-	"eqvparsl;":                 '\U000029E5',
-	"erDot;":                    '\U00002253',
-	"erarr;":                    '\U00002971',
-	"escr;":                     '\U0000212F',
-	"esdot;":                    '\U00002250',
-	"esim;":                     '\U00002242',
-	"eta;":                      '\U000003B7',
-	"eth;":                      '\U000000F0',
-	"euml;":                     '\U000000EB',
-	"euro;":                     '\U000020AC',
-	"excl;":                     '\U00000021',
-	"exist;":                    '\U00002203',
-	"expectation;":              '\U00002130',
-	"exponentiale;":             '\U00002147',
-	"fallingdotseq;":            '\U00002252',
-	"fcy;":                      '\U00000444',
-	"female;":                   '\U00002640',
-	"ffilig;":                   '\U0000FB03',
-	"fflig;":                    '\U0000FB00',
-	"ffllig;":                   '\U0000FB04',
-	"ffr;":                      '\U0001D523',
-	"filig;":                    '\U0000FB01',
-	"flat;":                     '\U0000266D',
-	"fllig;":                    '\U0000FB02',
-	"fltns;":                    '\U000025B1',
-	"fnof;":                     '\U00000192',
-	"fopf;":                     '\U0001D557',
-	"forall;":                   '\U00002200',
-	"fork;":                     '\U000022D4',
-	"forkv;":                    '\U00002AD9',
-	"fpartint;":                 '\U00002A0D',
-	"frac12;":                   '\U000000BD',
-	"frac13;":                   '\U00002153',
-	"frac14;":                   '\U000000BC',
-	"frac15;":                   '\U00002155',
-	"frac16;":                   '\U00002159',
-	"frac18;":                   '\U0000215B',
-	"frac23;":                   '\U00002154',
-	"frac25;":                   '\U00002156',
-	"frac34;":                   '\U000000BE',
-	"frac35;":                   '\U00002157',
-	"frac38;":                   '\U0000215C',
-	"frac45;":                   '\U00002158',
-	"frac56;":                   '\U0000215A',
-	"frac58;":                   '\U0000215D',
-	"frac78;":                   '\U0000215E',
-	"frasl;":                    '\U00002044',
-	"frown;":                    '\U00002322',
-	"fscr;":                     '\U0001D4BB',
-	"gE;":                       '\U00002267',
-	"gEl;":                      '\U00002A8C',
-	"gacute;":                   '\U000001F5',
-	"gamma;":                    '\U000003B3',
-	"gammad;":                   '\U000003DD',
-	"gap;":                      '\U00002A86',
-	"gbreve;":                   '\U0000011F',
-	"gcirc;":                    '\U0000011D',
-	"gcy;":                      '\U00000433',
-	"gdot;":                     '\U00000121',
-	"ge;":                       '\U00002265',
-	"gel;":                      '\U000022DB',
-	"geq;":                      '\U00002265',
-	"geqq;":                     '\U00002267',
-	"geqslant;":                 '\U00002A7E',
-	"ges;":                      '\U00002A7E',
-	"gescc;":                    '\U00002AA9',
-	"gesdot;":                   '\U00002A80',
-	"gesdoto;":                  '\U00002A82',
-	"gesdotol;":                 '\U00002A84',
-	"gesles;":                   '\U00002A94',
-	"gfr;":                      '\U0001D524',
-	"gg;":                       '\U0000226B',
-	"ggg;":                      '\U000022D9',
-	"gimel;":                    '\U00002137',
-	"gjcy;":                     '\U00000453',
-	"gl;":                       '\U00002277',
-	"glE;":                      '\U00002A92',
-	"gla;":                      '\U00002AA5',
-	"glj;":                      '\U00002AA4',
-	"gnE;":                      '\U00002269',
-	"gnap;":                     '\U00002A8A',
-	"gnapprox;":                 '\U00002A8A',
-	"gne;":                      '\U00002A88',
-	"gneq;":                     '\U00002A88',
-	"gneqq;":                    '\U00002269',
-	"gnsim;":                    '\U000022E7',
-	"gopf;":                     '\U0001D558',
-	"grave;":                    '\U00000060',
-	"gscr;":                     '\U0000210A',
-	"gsim;":                     '\U00002273',
-	"gsime;":                    '\U00002A8E',
-	"gsiml;":                    '\U00002A90',
-	"gt;":                       '\U0000003E',
-	"gtcc;":                     '\U00002AA7',
-	"gtcir;":                    '\U00002A7A',
-	"gtdot;":                    '\U000022D7',
-	"gtlPar;":                   '\U00002995',
-	"gtquest;":                  '\U00002A7C',
-	"gtrapprox;":                '\U00002A86',
-	"gtrarr;":                   '\U00002978',
-	"gtrdot;":                   '\U000022D7',
-	"gtreqless;":                '\U000022DB',
-	"gtreqqless;":               '\U00002A8C',
-	"gtrless;":                  '\U00002277',
-	"gtrsim;":                   '\U00002273',
-	"hArr;":                     '\U000021D4',
-	"hairsp;":                   '\U0000200A',
-	"half;":                     '\U000000BD',
-	"hamilt;":                   '\U0000210B',
-	"hardcy;":                   '\U0000044A',
-	"harr;":                     '\U00002194',
-	"harrcir;":                  '\U00002948',
-	"harrw;":                    '\U000021AD',
-	"hbar;":                     '\U0000210F',
-	"hcirc;":                    '\U00000125',
-	"hearts;":                   '\U00002665',
-	"heartsuit;":                '\U00002665',
-	"hellip;":                   '\U00002026',
-	"hercon;":                   '\U000022B9',
-	"hfr;":                      '\U0001D525',
-	"hksearow;":                 '\U00002925',
-	"hkswarow;":                 '\U00002926',
-	"hoarr;":                    '\U000021FF',
-	"homtht;":                   '\U0000223B',
-	"hookleftarrow;":            '\U000021A9',
-	"hookrightarrow;":           '\U000021AA',
-	"hopf;":                     '\U0001D559',
-	"horbar;":                   '\U00002015',
-	"hscr;":                     '\U0001D4BD',
-	"hslash;":                   '\U0000210F',
-	"hstrok;":                   '\U00000127',
-	"hybull;":                   '\U00002043',
-	"hyphen;":                   '\U00002010',
-	"iacute;":                   '\U000000ED',
-	"ic;":                       '\U00002063',
-	"icirc;":                    '\U000000EE',
-	"icy;":                      '\U00000438',
-	"iecy;":                     '\U00000435',
-	"iexcl;":                    '\U000000A1',
-	"iff;":                      '\U000021D4',
-	"ifr;":                      '\U0001D526',
-	"igrave;":                   '\U000000EC',
-	"ii;":                       '\U00002148',
-	"iiiint;":                   '\U00002A0C',
-	"iiint;":                    '\U0000222D',
-	"iinfin;":                   '\U000029DC',
-	"iiota;":                    '\U00002129',
-	"ijlig;":                    '\U00000133',
-	"imacr;":                    '\U0000012B',
-	"image;":                    '\U00002111',
-	"imagline;":                 '\U00002110',
-	"imagpart;":                 '\U00002111',
-	"imath;":                    '\U00000131',
-	"imof;":                     '\U000022B7',
-	"imped;":                    '\U000001B5',
-	"in;":                       '\U00002208',
-	"incare;":                   '\U00002105',
-	"infin;":                    '\U0000221E',
-	"infintie;":                 '\U000029DD',
-	"inodot;":                   '\U00000131',
-	"int;":                      '\U0000222B',
-	"intcal;":                   '\U000022BA',
-	"integers;":                 '\U00002124',
-	"intercal;":                 '\U000022BA',
-	"intlarhk;":                 '\U00002A17',
-	"intprod;":                  '\U00002A3C',
-	"iocy;":                     '\U00000451',
-	"iogon;":                    '\U0000012F',
-	"iopf;":                     '\U0001D55A',
-	"iota;":                     '\U000003B9',
-	"iprod;":                    '\U00002A3C',
-	"iquest;":                   '\U000000BF',
-	"iscr;":                     '\U0001D4BE',
-	"isin;":                     '\U00002208',
-	"isinE;":                    '\U000022F9',
-	"isindot;":                  '\U000022F5',
-	"isins;":                    '\U000022F4',
-	"isinsv;":                   '\U000022F3',
-	"isinv;":                    '\U00002208',
-	"it;":                       '\U00002062',
-	"itilde;":                   '\U00000129',
-	"iukcy;":                    '\U00000456',
-	"iuml;":                     '\U000000EF',
-	"jcirc;":                    '\U00000135',
-	"jcy;":                      '\U00000439',
-	"jfr;":                      '\U0001D527',
-	"jmath;":                    '\U00000237',
-	"jopf;":                     '\U0001D55B',
-	"jscr;":                     '\U0001D4BF',
-	"jsercy;":                   '\U00000458',
-	"jukcy;":                    '\U00000454',
-	"kappa;":                    '\U000003BA',
-	"kappav;":                   '\U000003F0',
-	"kcedil;":                   '\U00000137',
-	"kcy;":                      '\U0000043A',
-	"kfr;":                      '\U0001D528',
-	"kgreen;":                   '\U00000138',
-	"khcy;":                     '\U00000445',
-	"kjcy;":                     '\U0000045C',
-	"kopf;":                     '\U0001D55C',
-	"kscr;":                     '\U0001D4C0',
-	"lAarr;":                    '\U000021DA',
-	"lArr;":                     '\U000021D0',
-	"lAtail;":                   '\U0000291B',
-	"lBarr;":                    '\U0000290E',
-	"lE;":                       '\U00002266',
-	"lEg;":                      '\U00002A8B',
-	"lHar;":                     '\U00002962',
-	"lacute;":                   '\U0000013A',
-	"laemptyv;":                 '\U000029B4',
-	"lagran;":                   '\U00002112',
-	"lambda;":                   '\U000003BB',
-	"lang;":                     '\U000027E8',
-	"langd;":                    '\U00002991',
-	"langle;":                   '\U000027E8',
-	"lap;":                      '\U00002A85',
-	"laquo;":                    '\U000000AB',
-	"larr;":                     '\U00002190',
-	"larrb;":                    '\U000021E4',
-	"larrbfs;":                  '\U0000291F',
-	"larrfs;":                   '\U0000291D',
-	"larrhk;":                   '\U000021A9',
-	"larrlp;":                   '\U000021AB',
-	"larrpl;":                   '\U00002939',
-	"larrsim;":                  '\U00002973',
-	"larrtl;":                   '\U000021A2',
-	"lat;":                      '\U00002AAB',
-	"latail;":                   '\U00002919',
-	"late;":                     '\U00002AAD',
-	"lbarr;":                    '\U0000290C',
-	"lbbrk;":                    '\U00002772',
-	"lbrace;":                   '\U0000007B',
-	"lbrack;":                   '\U0000005B',
-	"lbrke;":                    '\U0000298B',
-	"lbrksld;":                  '\U0000298F',
-	"lbrkslu;":                  '\U0000298D',
-	"lcaron;":                   '\U0000013E',
-	"lcedil;":                   '\U0000013C',
-	"lceil;":                    '\U00002308',
-	"lcub;":                     '\U0000007B',
-	"lcy;":                      '\U0000043B',
-	"ldca;":                     '\U00002936',
-	"ldquo;":                    '\U0000201C',
-	"ldquor;":                   '\U0000201E',
-	"ldrdhar;":                  '\U00002967',
-	"ldrushar;":                 '\U0000294B',
-	"ldsh;":                     '\U000021B2',
-	"le;":                       '\U00002264',
-	"leftarrow;":                '\U00002190',
-	"leftarrowtail;":            '\U000021A2',
-	"leftharpoondown;":          '\U000021BD',
-	"leftharpoonup;":            '\U000021BC',
-	"leftleftarrows;":           '\U000021C7',
-	"leftrightarrow;":           '\U00002194',
-	"leftrightarrows;":          '\U000021C6',
-	"leftrightharpoons;":        '\U000021CB',
-	"leftrightsquigarrow;":      '\U000021AD',
-	"leftthreetimes;":           '\U000022CB',
-	"leg;":                      '\U000022DA',
-	"leq;":                      '\U00002264',
-	"leqq;":                     '\U00002266',
-	"leqslant;":                 '\U00002A7D',
-	"les;":                      '\U00002A7D',
-	"lescc;":                    '\U00002AA8',
-	"lesdot;":                   '\U00002A7F',
-	"lesdoto;":                  '\U00002A81',
-	"lesdotor;":                 '\U00002A83',
-	"lesges;":                   '\U00002A93',
-	"lessapprox;":               '\U00002A85',
-	"lessdot;":                  '\U000022D6',
-	"lesseqgtr;":                '\U000022DA',
-	"lesseqqgtr;":               '\U00002A8B',
-	"lessgtr;":                  '\U00002276',
-	"lesssim;":                  '\U00002272',
-	"lfisht;":                   '\U0000297C',
-	"lfloor;":                   '\U0000230A',
-	"lfr;":                      '\U0001D529',
-	"lg;":                       '\U00002276',
-	"lgE;":                      '\U00002A91',
-	"lhard;":                    '\U000021BD',
-	"lharu;":                    '\U000021BC',
-	"lharul;":                   '\U0000296A',
-	"lhblk;":                    '\U00002584',
-	"ljcy;":                     '\U00000459',
-	"ll;":                       '\U0000226A',
-	"llarr;":                    '\U000021C7',
-	"llcorner;":                 '\U0000231E',
-	"llhard;":                   '\U0000296B',
-	"lltri;":                    '\U000025FA',
-	"lmidot;":                   '\U00000140',
-	"lmoust;":                   '\U000023B0',
-	"lmoustache;":               '\U000023B0',
-	"lnE;":                      '\U00002268',
-	"lnap;":                     '\U00002A89',
-	"lnapprox;":                 '\U00002A89',
-	"lne;":                      '\U00002A87',
-	"lneq;":                     '\U00002A87',
-	"lneqq;":                    '\U00002268',
-	"lnsim;":                    '\U000022E6',
-	"loang;":                    '\U000027EC',
-	"loarr;":                    '\U000021FD',
-	"lobrk;":                    '\U000027E6',
-	"longleftarrow;":            '\U000027F5',
-	"longleftrightarrow;":       '\U000027F7',
-	"longmapsto;":               '\U000027FC',
-	"longrightarrow;":           '\U000027F6',
-	"looparrowleft;":            '\U000021AB',
-	"looparrowright;":           '\U000021AC',
-	"lopar;":                    '\U00002985',
-	"lopf;":                     '\U0001D55D',
-	"loplus;":                   '\U00002A2D',
-	"lotimes;":                  '\U00002A34',
-	"lowast;":                   '\U00002217',
-	"lowbar;":                   '\U0000005F',
-	"loz;":                      '\U000025CA',
-	"lozenge;":                  '\U000025CA',
-	"lozf;":                     '\U000029EB',
-	"lpar;":                     '\U00000028',
-	"lparlt;":                   '\U00002993',
-	"lrarr;":                    '\U000021C6',
-	"lrcorner;":                 '\U0000231F',
-	"lrhar;":                    '\U000021CB',
-	"lrhard;":                   '\U0000296D',
-	"lrm;":                      '\U0000200E',
-	"lrtri;":                    '\U000022BF',
-	"lsaquo;":                   '\U00002039',
-	"lscr;":                     '\U0001D4C1',
-	"lsh;":                      '\U000021B0',
-	"lsim;":                     '\U00002272',
-	"lsime;":                    '\U00002A8D',
-	"lsimg;":                    '\U00002A8F',
-	"lsqb;":                     '\U0000005B',
-	"lsquo;":                    '\U00002018',
-	"lsquor;":                   '\U0000201A',
-	"lstrok;":                   '\U00000142',
-	"lt;":                       '\U0000003C',
-	"ltcc;":                     '\U00002AA6',
-	"ltcir;":                    '\U00002A79',
-	"ltdot;":                    '\U000022D6',
-	"lthree;":                   '\U000022CB',
-	"ltimes;":                   '\U000022C9',
-	"ltlarr;":                   '\U00002976',
-	"ltquest;":                  '\U00002A7B',
-	"ltrPar;":                   '\U00002996',
-	"ltri;":                     '\U000025C3',
-	"ltrie;":                    '\U000022B4',
-	"ltrif;":                    '\U000025C2',
-	"lurdshar;":                 '\U0000294A',
-	"luruhar;":                  '\U00002966',
-	"mDDot;":                    '\U0000223A',
-	"macr;":                     '\U000000AF',
-	"male;":                     '\U00002642',
-	"malt;":                     '\U00002720',
-	"maltese;":                  '\U00002720',
-	"map;":                      '\U000021A6',
-	"mapsto;":                   '\U000021A6',
-	"mapstodown;":               '\U000021A7',
-	"mapstoleft;":               '\U000021A4',
-	"mapstoup;":                 '\U000021A5',
-	"marker;":                   '\U000025AE',
-	"mcomma;":                   '\U00002A29',
-	"mcy;":                      '\U0000043C',
-	"mdash;":                    '\U00002014',
-	"measuredangle;":            '\U00002221',
-	"mfr;":                      '\U0001D52A',
-	"mho;":                      '\U00002127',
-	"micro;":                    '\U000000B5',
-	"mid;":                      '\U00002223',
-	"midast;":                   '\U0000002A',
-	"midcir;":                   '\U00002AF0',
-	"middot;":                   '\U000000B7',
-	"minus;":                    '\U00002212',
-	"minusb;":                   '\U0000229F',
-	"minusd;":                   '\U00002238',
-	"minusdu;":                  '\U00002A2A',
-	"mlcp;":                     '\U00002ADB',
-	"mldr;":                     '\U00002026',
-	"mnplus;":                   '\U00002213',
-	"models;":                   '\U000022A7',
-	"mopf;":                     '\U0001D55E',
-	"mp;":                       '\U00002213',
-	"mscr;":                     '\U0001D4C2',
-	"mstpos;":                   '\U0000223E',
-	"mu;":                       '\U000003BC',
-	"multimap;":                 '\U000022B8',
-	"mumap;":                    '\U000022B8',
-	"nLeftarrow;":               '\U000021CD',
-	"nLeftrightarrow;":          '\U000021CE',
-	"nRightarrow;":              '\U000021CF',
-	"nVDash;":                   '\U000022AF',
-	"nVdash;":                   '\U000022AE',
-	"nabla;":                    '\U00002207',
-	"nacute;":                   '\U00000144',
-	"nap;":                      '\U00002249',
-	"napos;":                    '\U00000149',
-	"napprox;":                  '\U00002249',
-	"natur;":                    '\U0000266E',
-	"natural;":                  '\U0000266E',
-	"naturals;":                 '\U00002115',
-	"nbsp;":                     '\U000000A0',
-	"ncap;":                     '\U00002A43',
-	"ncaron;":                   '\U00000148',
-	"ncedil;":                   '\U00000146',
-	"ncong;":                    '\U00002247',
-	"ncup;":                     '\U00002A42',
-	"ncy;":                      '\U0000043D',
-	"ndash;":                    '\U00002013',
-	"ne;":                       '\U00002260',
-	"neArr;":                    '\U000021D7',
-	"nearhk;":                   '\U00002924',
-	"nearr;":                    '\U00002197',
-	"nearrow;":                  '\U00002197',
-	"nequiv;":                   '\U00002262',
-	"nesear;":                   '\U00002928',
-	"nexist;":                   '\U00002204',
-	"nexists;":                  '\U00002204',
-	"nfr;":                      '\U0001D52B',
-	"nge;":                      '\U00002271',
-	"ngeq;":                     '\U00002271',
-	"ngsim;":                    '\U00002275',
-	"ngt;":                      '\U0000226F',
-	"ngtr;":                     '\U0000226F',
-	"nhArr;":                    '\U000021CE',
-	"nharr;":                    '\U000021AE',
-	"nhpar;":                    '\U00002AF2',
-	"ni;":                       '\U0000220B',
-	"nis;":                      '\U000022FC',
-	"nisd;":                     '\U000022FA',
-	"niv;":                      '\U0000220B',
-	"njcy;":                     '\U0000045A',
-	"nlArr;":                    '\U000021CD',
-	"nlarr;":                    '\U0000219A',
-	"nldr;":                     '\U00002025',
-	"nle;":                      '\U00002270',
-	"nleftarrow;":               '\U0000219A',
-	"nleftrightarrow;":          '\U000021AE',
-	"nleq;":                     '\U00002270',
-	"nless;":                    '\U0000226E',
-	"nlsim;":                    '\U00002274',
-	"nlt;":                      '\U0000226E',
-	"nltri;":                    '\U000022EA',
-	"nltrie;":                   '\U000022EC',
-	"nmid;":                     '\U00002224',
-	"nopf;":                     '\U0001D55F',
-	"not;":                      '\U000000AC',
-	"notin;":                    '\U00002209',
-	"notinva;":                  '\U00002209',
-	"notinvb;":                  '\U000022F7',
-	"notinvc;":                  '\U000022F6',
-	"notni;":                    '\U0000220C',
-	"notniva;":                  '\U0000220C',
-	"notnivb;":                  '\U000022FE',
-	"notnivc;":                  '\U000022FD',
-	"npar;":                     '\U00002226',
-	"nparallel;":                '\U00002226',
-	"npolint;":                  '\U00002A14',
-	"npr;":                      '\U00002280',
-	"nprcue;":                   '\U000022E0',
-	"nprec;":                    '\U00002280',
-	"nrArr;":                    '\U000021CF',
-	"nrarr;":                    '\U0000219B',
-	"nrightarrow;":              '\U0000219B',
-	"nrtri;":                    '\U000022EB',
-	"nrtrie;":                   '\U000022ED',
-	"nsc;":                      '\U00002281',
-	"nsccue;":                   '\U000022E1',
-	"nscr;":                     '\U0001D4C3',
-	"nshortmid;":                '\U00002224',
-	"nshortparallel;":           '\U00002226',
-	"nsim;":                     '\U00002241',
-	"nsime;":                    '\U00002244',
-	"nsimeq;":                   '\U00002244',
-	"nsmid;":                    '\U00002224',
-	"nspar;":                    '\U00002226',
-	"nsqsube;":                  '\U000022E2',
-	"nsqsupe;":                  '\U000022E3',
-	"nsub;":                     '\U00002284',
-	"nsube;":                    '\U00002288',
-	"nsubseteq;":                '\U00002288',
-	"nsucc;":                    '\U00002281',
-	"nsup;":                     '\U00002285',
-	"nsupe;":                    '\U00002289',
-	"nsupseteq;":                '\U00002289',
-	"ntgl;":                     '\U00002279',
-	"ntilde;":                   '\U000000F1',
-	"ntlg;":                     '\U00002278',
-	"ntriangleleft;":            '\U000022EA',
-	"ntrianglelefteq;":          '\U000022EC',
-	"ntriangleright;":           '\U000022EB',
-	"ntrianglerighteq;":         '\U000022ED',
-	"nu;":                       '\U000003BD',
-	"num;":                      '\U00000023',
-	"numero;":                   '\U00002116',
-	"numsp;":                    '\U00002007',
-	"nvDash;":                   '\U000022AD',
-	"nvHarr;":                   '\U00002904',
-	"nvdash;":                   '\U000022AC',
-	"nvinfin;":                  '\U000029DE',
-	"nvlArr;":                   '\U00002902',
-	"nvrArr;":                   '\U00002903',
-	"nwArr;":                    '\U000021D6',
-	"nwarhk;":                   '\U00002923',
-	"nwarr;":                    '\U00002196',
-	"nwarrow;":                  '\U00002196',
-	"nwnear;":                   '\U00002927',
-	"oS;":                       '\U000024C8',
-	"oacute;":                   '\U000000F3',
-	"oast;":                     '\U0000229B',
-	"ocir;":                     '\U0000229A',
-	"ocirc;":                    '\U000000F4',
-	"ocy;":                      '\U0000043E',
-	"odash;":                    '\U0000229D',
-	"odblac;":                   '\U00000151',
-	"odiv;":                     '\U00002A38',
-	"odot;":                     '\U00002299',
-	"odsold;":                   '\U000029BC',
-	"oelig;":                    '\U00000153',
-	"ofcir;":                    '\U000029BF',
-	"ofr;":                      '\U0001D52C',
-	"ogon;":                     '\U000002DB',
-	"ograve;":                   '\U000000F2',
-	"ogt;":                      '\U000029C1',
-	"ohbar;":                    '\U000029B5',
-	"ohm;":                      '\U000003A9',
-	"oint;":                     '\U0000222E',
-	"olarr;":                    '\U000021BA',
-	"olcir;":                    '\U000029BE',
-	"olcross;":                  '\U000029BB',
-	"oline;":                    '\U0000203E',
-	"olt;":                      '\U000029C0',
-	"omacr;":                    '\U0000014D',
-	"omega;":                    '\U000003C9',
-	"omicron;":                  '\U000003BF',
-	"omid;":                     '\U000029B6',
-	"ominus;":                   '\U00002296',
-	"oopf;":                     '\U0001D560',
-	"opar;":                     '\U000029B7',
-	"operp;":                    '\U000029B9',
-	"oplus;":                    '\U00002295',
-	"or;":                       '\U00002228',
-	"orarr;":                    '\U000021BB',
-	"ord;":                      '\U00002A5D',
-	"order;":                    '\U00002134',
-	"orderof;":                  '\U00002134',
-	"ordf;":                     '\U000000AA',
-	"ordm;":                     '\U000000BA',
-	"origof;":                   '\U000022B6',
-	"oror;":                     '\U00002A56',
-	"orslope;":                  '\U00002A57',
-	"orv;":                      '\U00002A5B',
-	"oscr;":                     '\U00002134',
-	"oslash;":                   '\U000000F8',
-	"osol;":                     '\U00002298',
-	"otilde;":                   '\U000000F5',
-	"otimes;":                   '\U00002297',
-	"otimesas;":                 '\U00002A36',
-	"ouml;":                     '\U000000F6',
-	"ovbar;":                    '\U0000233D',
-	"par;":                      '\U00002225',
-	"para;":                     '\U000000B6',
-	"parallel;":                 '\U00002225',
-	"parsim;":                   '\U00002AF3',
-	"parsl;":                    '\U00002AFD',
-	"part;":                     '\U00002202',
-	"pcy;":                      '\U0000043F',
-	"percnt;":                   '\U00000025',
-	"period;":                   '\U0000002E',
-	"permil;":                   '\U00002030',
-	"perp;":                     '\U000022A5',
-	"pertenk;":                  '\U00002031',
-	"pfr;":                      '\U0001D52D',
-	"phi;":                      '\U000003C6',
-	"phiv;":                     '\U000003D5',
-	"phmmat;":                   '\U00002133',
-	"phone;":                    '\U0000260E',
-	"pi;":                       '\U000003C0',
-	"pitchfork;":                '\U000022D4',
-	"piv;":                      '\U000003D6',
-	"planck;":                   '\U0000210F',
-	"planckh;":                  '\U0000210E',
-	"plankv;":                   '\U0000210F',
-	"plus;":                     '\U0000002B',
-	"plusacir;":                 '\U00002A23',
-	"plusb;":                    '\U0000229E',
-	"pluscir;":                  '\U00002A22',
-	"plusdo;":                   '\U00002214',
-	"plusdu;":                   '\U00002A25',
-	"pluse;":                    '\U00002A72',
-	"plusmn;":                   '\U000000B1',
-	"plussim;":                  '\U00002A26',
-	"plustwo;":                  '\U00002A27',
-	"pm;":                       '\U000000B1',
-	"pointint;":                 '\U00002A15',
-	"popf;":                     '\U0001D561',
-	"pound;":                    '\U000000A3',
-	"pr;":                       '\U0000227A',
-	"prE;":                      '\U00002AB3',
-	"prap;":                     '\U00002AB7',
-	"prcue;":                    '\U0000227C',
-	"pre;":                      '\U00002AAF',
-	"prec;":                     '\U0000227A',
-	"precapprox;":               '\U00002AB7',
-	"preccurlyeq;":              '\U0000227C',
-	"preceq;":                   '\U00002AAF',
-	"precnapprox;":              '\U00002AB9',
-	"precneqq;":                 '\U00002AB5',
-	"precnsim;":                 '\U000022E8',
-	"precsim;":                  '\U0000227E',
-	"prime;":                    '\U00002032',
-	"primes;":                   '\U00002119',
-	"prnE;":                     '\U00002AB5',
-	"prnap;":                    '\U00002AB9',
-	"prnsim;":                   '\U000022E8',
-	"prod;":                     '\U0000220F',
-	"profalar;":                 '\U0000232E',
-	"profline;":                 '\U00002312',
-	"profsurf;":                 '\U00002313',
-	"prop;":                     '\U0000221D',
-	"propto;":                   '\U0000221D',
-	"prsim;":                    '\U0000227E',
-	"prurel;":                   '\U000022B0',
-	"pscr;":                     '\U0001D4C5',
-	"psi;":                      '\U000003C8',
-	"puncsp;":                   '\U00002008',
-	"qfr;":                      '\U0001D52E',
-	"qint;":                     '\U00002A0C',
-	"qopf;":                     '\U0001D562',
-	"qprime;":                   '\U00002057',
-	"qscr;":                     '\U0001D4C6',
-	"quaternions;":              '\U0000210D',
-	"quatint;":                  '\U00002A16',
-	"quest;":                    '\U0000003F',
-	"questeq;":                  '\U0000225F',
-	"quot;":                     '\U00000022',
-	"rAarr;":                    '\U000021DB',
-	"rArr;":                     '\U000021D2',
-	"rAtail;":                   '\U0000291C',
-	"rBarr;":                    '\U0000290F',
-	"rHar;":                     '\U00002964',
-	"racute;":                   '\U00000155',
-	"radic;":                    '\U0000221A',
-	"raemptyv;":                 '\U000029B3',
-	"rang;":                     '\U000027E9',
-	"rangd;":                    '\U00002992',
-	"range;":                    '\U000029A5',
-	"rangle;":                   '\U000027E9',
-	"raquo;":                    '\U000000BB',
-	"rarr;":                     '\U00002192',
-	"rarrap;":                   '\U00002975',
-	"rarrb;":                    '\U000021E5',
-	"rarrbfs;":                  '\U00002920',
-	"rarrc;":                    '\U00002933',
-	"rarrfs;":                   '\U0000291E',
-	"rarrhk;":                   '\U000021AA',
-	"rarrlp;":                   '\U000021AC',
-	"rarrpl;":                   '\U00002945',
-	"rarrsim;":                  '\U00002974',
-	"rarrtl;":                   '\U000021A3',
-	"rarrw;":                    '\U0000219D',
-	"ratail;":                   '\U0000291A',
-	"ratio;":                    '\U00002236',
-	"rationals;":                '\U0000211A',
-	"rbarr;":                    '\U0000290D',
-	"rbbrk;":                    '\U00002773',
-	"rbrace;":                   '\U0000007D',
-	"rbrack;":                   '\U0000005D',
-	"rbrke;":                    '\U0000298C',
-	"rbrksld;":                  '\U0000298E',
-	"rbrkslu;":                  '\U00002990',
-	"rcaron;":                   '\U00000159',
-	"rcedil;":                   '\U00000157',
-	"rceil;":                    '\U00002309',
-	"rcub;":                     '\U0000007D',
-	"rcy;":                      '\U00000440',
-	"rdca;":                     '\U00002937',
-	"rdldhar;":                  '\U00002969',
-	"rdquo;":                    '\U0000201D',
-	"rdquor;":                   '\U0000201D',
-	"rdsh;":                     '\U000021B3',
-	"real;":                     '\U0000211C',
-	"realine;":                  '\U0000211B',
-	"realpart;":                 '\U0000211C',
-	"reals;":                    '\U0000211D',
-	"rect;":                     '\U000025AD',
-	"reg;":                      '\U000000AE',
-	"rfisht;":                   '\U0000297D',
-	"rfloor;":                   '\U0000230B',
-	"rfr;":                      '\U0001D52F',
-	"rhard;":                    '\U000021C1',
-	"rharu;":                    '\U000021C0',
-	"rharul;":                   '\U0000296C',
-	"rho;":                      '\U000003C1',
-	"rhov;":                     '\U000003F1',
-	"rightarrow;":               '\U00002192',
-	"rightarrowtail;":           '\U000021A3',
-	"rightharpoondown;":         '\U000021C1',
-	"rightharpoonup;":           '\U000021C0',
-	"rightleftarrows;":          '\U000021C4',
-	"rightleftharpoons;":        '\U000021CC',
-	"rightrightarrows;":         '\U000021C9',
-	"rightsquigarrow;":          '\U0000219D',
-	"rightthreetimes;":          '\U000022CC',
-	"ring;":                     '\U000002DA',
-	"risingdotseq;":             '\U00002253',
-	"rlarr;":                    '\U000021C4',
-	"rlhar;":                    '\U000021CC',
-	"rlm;":                      '\U0000200F',
-	"rmoust;":                   '\U000023B1',
-	"rmoustache;":               '\U000023B1',
-	"rnmid;":                    '\U00002AEE',
-	"roang;":                    '\U000027ED',
-	"roarr;":                    '\U000021FE',
-	"robrk;":                    '\U000027E7',
-	"ropar;":                    '\U00002986',
-	"ropf;":                     '\U0001D563',
-	"roplus;":                   '\U00002A2E',
-	"rotimes;":                  '\U00002A35',
-	"rpar;":                     '\U00000029',
-	"rpargt;":                   '\U00002994',
-	"rppolint;":                 '\U00002A12',
-	"rrarr;":                    '\U000021C9',
-	"rsaquo;":                   '\U0000203A',
-	"rscr;":                     '\U0001D4C7',
-	"rsh;":                      '\U000021B1',
-	"rsqb;":                     '\U0000005D',
-	"rsquo;":                    '\U00002019',
-	"rsquor;":                   '\U00002019',
-	"rthree;":                   '\U000022CC',
-	"rtimes;":                   '\U000022CA',
-	"rtri;":                     '\U000025B9',
-	"rtrie;":                    '\U000022B5',
-	"rtrif;":                    '\U000025B8',
-	"rtriltri;":                 '\U000029CE',
-	"ruluhar;":                  '\U00002968',
-	"rx;":                       '\U0000211E',
-	"sacute;":                   '\U0000015B',
-	"sbquo;":                    '\U0000201A',
-	"sc;":                       '\U0000227B',
-	"scE;":                      '\U00002AB4',
-	"scap;":                     '\U00002AB8',
-	"scaron;":                   '\U00000161',
-	"sccue;":                    '\U0000227D',
-	"sce;":                      '\U00002AB0',
-	"scedil;":                   '\U0000015F',
-	"scirc;":                    '\U0000015D',
-	"scnE;":                     '\U00002AB6',
-	"scnap;":                    '\U00002ABA',
-	"scnsim;":                   '\U000022E9',
-	"scpolint;":                 '\U00002A13',
-	"scsim;":                    '\U0000227F',
-	"scy;":                      '\U00000441',
-	"sdot;":                     '\U000022C5',
-	"sdotb;":                    '\U000022A1',
-	"sdote;":                    '\U00002A66',
-	"seArr;":                    '\U000021D8',
-	"searhk;":                   '\U00002925',
-	"searr;":                    '\U00002198',
-	"searrow;":                  '\U00002198',
-	"sect;":                     '\U000000A7',
-	"semi;":                     '\U0000003B',
-	"seswar;":                   '\U00002929',
-	"setminus;":                 '\U00002216',
-	"setmn;":                    '\U00002216',
-	"sext;":                     '\U00002736',
-	"sfr;":                      '\U0001D530',
-	"sfrown;":                   '\U00002322',
-	"sharp;":                    '\U0000266F',
-	"shchcy;":                   '\U00000449',
-	"shcy;":                     '\U00000448',
-	"shortmid;":                 '\U00002223',
-	"shortparallel;":            '\U00002225',
-	"shy;":                      '\U000000AD',
-	"sigma;":                    '\U000003C3',
-	"sigmaf;":                   '\U000003C2',
-	"sigmav;":                   '\U000003C2',
-	"sim;":                      '\U0000223C',
-	"simdot;":                   '\U00002A6A',
-	"sime;":                     '\U00002243',
-	"simeq;":                    '\U00002243',
-	"simg;":                     '\U00002A9E',
-	"simgE;":                    '\U00002AA0',
-	"siml;":                     '\U00002A9D',
-	"simlE;":                    '\U00002A9F',
-	"simne;":                    '\U00002246',
-	"simplus;":                  '\U00002A24',
-	"simrarr;":                  '\U00002972',
-	"slarr;":                    '\U00002190',
-	"smallsetminus;":            '\U00002216',
-	"smashp;":                   '\U00002A33',
-	"smeparsl;":                 '\U000029E4',
-	"smid;":                     '\U00002223',
-	"smile;":                    '\U00002323',
-	"smt;":                      '\U00002AAA',
-	"smte;":                     '\U00002AAC',
-	"softcy;":                   '\U0000044C',
-	"sol;":                      '\U0000002F',
-	"solb;":                     '\U000029C4',
-	"solbar;":                   '\U0000233F',
-	"sopf;":                     '\U0001D564',
-	"spades;":                   '\U00002660',
-	"spadesuit;":                '\U00002660',
-	"spar;":                     '\U00002225',
-	"sqcap;":                    '\U00002293',
-	"sqcup;":                    '\U00002294',
-	"sqsub;":                    '\U0000228F',
-	"sqsube;":                   '\U00002291',
-	"sqsubset;":                 '\U0000228F',
-	"sqsubseteq;":               '\U00002291',
-	"sqsup;":                    '\U00002290',
-	"sqsupe;":                   '\U00002292',
-	"sqsupset;":                 '\U00002290',
-	"sqsupseteq;":               '\U00002292',
-	"squ;":                      '\U000025A1',
-	"square;":                   '\U000025A1',
-	"squarf;":                   '\U000025AA',
-	"squf;":                     '\U000025AA',
-	"srarr;":                    '\U00002192',
-	"sscr;":                     '\U0001D4C8',
-	"ssetmn;":                   '\U00002216',
-	"ssmile;":                   '\U00002323',
-	"sstarf;":                   '\U000022C6',
-	"star;":                     '\U00002606',
-	"starf;":                    '\U00002605',
-	"straightepsilon;":          '\U000003F5',
-	"straightphi;":              '\U000003D5',
-	"strns;":                    '\U000000AF',
-	"sub;":                      '\U00002282',
-	"subE;":                     '\U00002AC5',
-	"subdot;":                   '\U00002ABD',
-	"sube;":                     '\U00002286',
-	"subedot;":                  '\U00002AC3',
-	"submult;":                  '\U00002AC1',
-	"subnE;":                    '\U00002ACB',
-	"subne;":                    '\U0000228A',
-	"subplus;":                  '\U00002ABF',
-	"subrarr;":                  '\U00002979',
-	"subset;":                   '\U00002282',
-	"subseteq;":                 '\U00002286',
-	"subseteqq;":                '\U00002AC5',
-	"subsetneq;":                '\U0000228A',
-	"subsetneqq;":               '\U00002ACB',
-	"subsim;":                   '\U00002AC7',
-	"subsub;":                   '\U00002AD5',
-	"subsup;":                   '\U00002AD3',
-	"succ;":                     '\U0000227B',
-	"succapprox;":               '\U00002AB8',
-	"succcurlyeq;":              '\U0000227D',
-	"succeq;":                   '\U00002AB0',
-	"succnapprox;":              '\U00002ABA',
-	"succneqq;":                 '\U00002AB6',
-	"succnsim;":                 '\U000022E9',
-	"succsim;":                  '\U0000227F',
-	"sum;":                      '\U00002211',
-	"sung;":                     '\U0000266A',
-	"sup;":                      '\U00002283',
-	"sup1;":                     '\U000000B9',
-	"sup2;":                     '\U000000B2',
-	"sup3;":                     '\U000000B3',
-	"supE;":                     '\U00002AC6',
-	"supdot;":                   '\U00002ABE',
-	"supdsub;":                  '\U00002AD8',
-	"supe;":                     '\U00002287',
-	"supedot;":                  '\U00002AC4',
-	"suphsol;":                  '\U000027C9',
-	"suphsub;":                  '\U00002AD7',
-	"suplarr;":                  '\U0000297B',
-	"supmult;":                  '\U00002AC2',
-	"supnE;":                    '\U00002ACC',
-	"supne;":                    '\U0000228B',
-	"supplus;":                  '\U00002AC0',
-	"supset;":                   '\U00002283',
-	"supseteq;":                 '\U00002287',
-	"supseteqq;":                '\U00002AC6',
-	"supsetneq;":                '\U0000228B',
-	"supsetneqq;":               '\U00002ACC',
-	"supsim;":                   '\U00002AC8',
-	"supsub;":                   '\U00002AD4',
-	"supsup;":                   '\U00002AD6',
-	"swArr;":                    '\U000021D9',
-	"swarhk;":                   '\U00002926',
-	"swarr;":                    '\U00002199',
-	"swarrow;":                  '\U00002199',
-	"swnwar;":                   '\U0000292A',
-	"szlig;":                    '\U000000DF',
-	"target;":                   '\U00002316',
-	"tau;":                      '\U000003C4',
-	"tbrk;":                     '\U000023B4',
-	"tcaron;":                   '\U00000165',
-	"tcedil;":                   '\U00000163',
-	"tcy;":                      '\U00000442',
-	"tdot;":                     '\U000020DB',
-	"telrec;":                   '\U00002315',
-	"tfr;":                      '\U0001D531',
-	"there4;":                   '\U00002234',
-	"therefore;":                '\U00002234',
-	"theta;":                    '\U000003B8',
-	"thetasym;":                 '\U000003D1',
-	"thetav;":                   '\U000003D1',
-	"thickapprox;":              '\U00002248',
-	"thicksim;":                 '\U0000223C',
-	"thinsp;":                   '\U00002009',
-	"thkap;":                    '\U00002248',
-	"thksim;":                   '\U0000223C',
-	"thorn;":                    '\U000000FE',
-	"tilde;":                    '\U000002DC',
-	"times;":                    '\U000000D7',
-	"timesb;":                   '\U000022A0',
-	"timesbar;":                 '\U00002A31',
-	"timesd;":                   '\U00002A30',
-	"tint;":                     '\U0000222D',
-	"toea;":                     '\U00002928',
-	"top;":                      '\U000022A4',
-	"topbot;":                   '\U00002336',
-	"topcir;":                   '\U00002AF1',
-	"topf;":                     '\U0001D565',
-	"topfork;":                  '\U00002ADA',
-	"tosa;":                     '\U00002929',
-	"tprime;":                   '\U00002034',
-	"trade;":                    '\U00002122',
-	"triangle;":                 '\U000025B5',
-	"triangledown;":             '\U000025BF',
-	"triangleleft;":             '\U000025C3',
-	"trianglelefteq;":           '\U000022B4',
-	"triangleq;":                '\U0000225C',
-	"triangleright;":            '\U000025B9',
-	"trianglerighteq;":          '\U000022B5',
-	"tridot;":                   '\U000025EC',
-	"trie;":                     '\U0000225C',
-	"triminus;":                 '\U00002A3A',
-	"triplus;":                  '\U00002A39',
-	"trisb;":                    '\U000029CD',
-	"tritime;":                  '\U00002A3B',
-	"trpezium;":                 '\U000023E2',
-	"tscr;":                     '\U0001D4C9',
-	"tscy;":                     '\U00000446',
-	"tshcy;":                    '\U0000045B',
-	"tstrok;":                   '\U00000167',
-	"twixt;":                    '\U0000226C',
-	"twoheadleftarrow;":         '\U0000219E',
-	"twoheadrightarrow;":        '\U000021A0',
-	"uArr;":                     '\U000021D1',
-	"uHar;":                     '\U00002963',
-	"uacute;":                   '\U000000FA',
-	"uarr;":                     '\U00002191',
-	"ubrcy;":                    '\U0000045E',
-	"ubreve;":                   '\U0000016D',
-	"ucirc;":                    '\U000000FB',
-	"ucy;":                      '\U00000443',
-	"udarr;":                    '\U000021C5',
-	"udblac;":                   '\U00000171',
-	"udhar;":                    '\U0000296E',
-	"ufisht;":                   '\U0000297E',
-	"ufr;":                      '\U0001D532',
-	"ugrave;":                   '\U000000F9',
-	"uharl;":                    '\U000021BF',
-	"uharr;":                    '\U000021BE',
-	"uhblk;":                    '\U00002580',
-	"ulcorn;":                   '\U0000231C',
-	"ulcorner;":                 '\U0000231C',
-	"ulcrop;":                   '\U0000230F',
-	"ultri;":                    '\U000025F8',
-	"umacr;":                    '\U0000016B',
-	"uml;":                      '\U000000A8',
-	"uogon;":                    '\U00000173',
-	"uopf;":                     '\U0001D566',
-	"uparrow;":                  '\U00002191',
-	"updownarrow;":              '\U00002195',
-	"upharpoonleft;":            '\U000021BF',
-	"upharpoonright;":           '\U000021BE',
-	"uplus;":                    '\U0000228E',
-	"upsi;":                     '\U000003C5',
-	"upsih;":                    '\U000003D2',
-	"upsilon;":                  '\U000003C5',
-	"upuparrows;":               '\U000021C8',
-	"urcorn;":                   '\U0000231D',
-	"urcorner;":                 '\U0000231D',
-	"urcrop;":                   '\U0000230E',
-	"uring;":                    '\U0000016F',
-	"urtri;":                    '\U000025F9',
-	"uscr;":                     '\U0001D4CA',
-	"utdot;":                    '\U000022F0',
-	"utilde;":                   '\U00000169',
-	"utri;":                     '\U000025B5',
-	"utrif;":                    '\U000025B4',
-	"uuarr;":                    '\U000021C8',
-	"uuml;":                     '\U000000FC',
-	"uwangle;":                  '\U000029A7',
-	"vArr;":                     '\U000021D5',
-	"vBar;":                     '\U00002AE8',
-	"vBarv;":                    '\U00002AE9',
-	"vDash;":                    '\U000022A8',
-	"vangrt;":                   '\U0000299C',
-	"varepsilon;":               '\U000003F5',
-	"varkappa;":                 '\U000003F0',
-	"varnothing;":               '\U00002205',
-	"varphi;":                   '\U000003D5',
-	"varpi;":                    '\U000003D6',
-	"varpropto;":                '\U0000221D',
-	"varr;":                     '\U00002195',
-	"varrho;":                   '\U000003F1',
-	"varsigma;":                 '\U000003C2',
-	"vartheta;":                 '\U000003D1',
-	"vartriangleleft;":          '\U000022B2',
-	"vartriangleright;":         '\U000022B3',
-	"vcy;":                      '\U00000432',
-	"vdash;":                    '\U000022A2',
-	"vee;":                      '\U00002228',
-	"veebar;":                   '\U000022BB',
-	"veeeq;":                    '\U0000225A',
-	"vellip;":                   '\U000022EE',
-	"verbar;":                   '\U0000007C',
-	"vert;":                     '\U0000007C',
-	"vfr;":                      '\U0001D533',
-	"vltri;":                    '\U000022B2',
-	"vopf;":                     '\U0001D567',
-	"vprop;":                    '\U0000221D',
-	"vrtri;":                    '\U000022B3',
-	"vscr;":                     '\U0001D4CB',
-	"vzigzag;":                  '\U0000299A',
-	"wcirc;":                    '\U00000175',
-	"wedbar;":                   '\U00002A5F',
-	"wedge;":                    '\U00002227',
-	"wedgeq;":                   '\U00002259',
-	"weierp;":                   '\U00002118',
-	"wfr;":                      '\U0001D534',
-	"wopf;":                     '\U0001D568',
-	"wp;":                       '\U00002118',
-	"wr;":                       '\U00002240',
-	"wreath;":                   '\U00002240',
-	"wscr;":                     '\U0001D4CC',
-	"xcap;":                     '\U000022C2',
-	"xcirc;":                    '\U000025EF',
-	"xcup;":                     '\U000022C3',
-	"xdtri;":                    '\U000025BD',
-	"xfr;":                      '\U0001D535',
-	"xhArr;":                    '\U000027FA',
-	"xharr;":                    '\U000027F7',
-	"xi;":                       '\U000003BE',
-	"xlArr;":                    '\U000027F8',
-	"xlarr;":                    '\U000027F5',
-	"xmap;":                     '\U000027FC',
-	"xnis;":                     '\U000022FB',
-	"xodot;":                    '\U00002A00',
-	"xopf;":                     '\U0001D569',
-	"xoplus;":                   '\U00002A01',
-	"xotime;":                   '\U00002A02',
-	"xrArr;":                    '\U000027F9',
-	"xrarr;":                    '\U000027F6',
-	"xscr;":                     '\U0001D4CD',
-	"xsqcup;":                   '\U00002A06',
-	"xuplus;":                   '\U00002A04',
-	"xutri;":                    '\U000025B3',
-	"xvee;":                     '\U000022C1',
-	"xwedge;":                   '\U000022C0',
-	"yacute;":                   '\U000000FD',
-	"yacy;":                     '\U0000044F',
-	"ycirc;":                    '\U00000177',
-	"ycy;":                      '\U0000044B',
-	"yen;":                      '\U000000A5',
-	"yfr;":                      '\U0001D536',
-	"yicy;":                     '\U00000457',
-	"yopf;":                     '\U0001D56A',
-	"yscr;":                     '\U0001D4CE',
-	"yucy;":                     '\U0000044E',
-	"yuml;":                     '\U000000FF',
-	"zacute;":                   '\U0000017A',
-	"zcaron;":                   '\U0000017E',
-	"zcy;":                      '\U00000437',
-	"zdot;":                     '\U0000017C',
-	"zeetrf;":                   '\U00002128',
-	"zeta;":                     '\U000003B6',
-	"zfr;":                      '\U0001D537',
-	"zhcy;":                     '\U00000436',
-	"zigrarr;":                  '\U000021DD',
-	"zopf;":                     '\U0001D56B',
-	"zscr;":                     '\U0001D4CF',
-	"zwj;":                      '\U0000200D',
-	"zwnj;":                     '\U0000200C',
-	"AElig":                     '\U000000C6',
-	"AMP":                       '\U00000026',
-	"Aacute":                    '\U000000C1',
-	"Acirc":                     '\U000000C2',
-	"Agrave":                    '\U000000C0',
-	"Aring":                     '\U000000C5',
-	"Atilde":                    '\U000000C3',
-	"Auml":                      '\U000000C4',
-	"COPY":                      '\U000000A9',
-	"Ccedil":                    '\U000000C7',
-	"ETH":                       '\U000000D0',
-	"Eacute":                    '\U000000C9',
-	"Ecirc":                     '\U000000CA',
-	"Egrave":                    '\U000000C8',
-	"Euml":                      '\U000000CB',
-	"GT":                        '\U0000003E',
-	"Iacute":                    '\U000000CD',
-	"Icirc":                     '\U000000CE',
-	"Igrave":                    '\U000000CC',
-	"Iuml":                      '\U000000CF',
-	"LT":                        '\U0000003C',
-	"Ntilde":                    '\U000000D1',
-	"Oacute":                    '\U000000D3',
-	"Ocirc":                     '\U000000D4',
-	"Ograve":                    '\U000000D2',
-	"Oslash":                    '\U000000D8',
-	"Otilde":                    '\U000000D5',
-	"Ouml":                      '\U000000D6',
-	"QUOT":                      '\U00000022',
-	"REG":                       '\U000000AE',
-	"THORN":                     '\U000000DE',
-	"Uacute":                    '\U000000DA',
-	"Ucirc":                     '\U000000DB',
-	"Ugrave":                    '\U000000D9',
-	"Uuml":                      '\U000000DC',
-	"Yacute":                    '\U000000DD',
-	"aacute":                    '\U000000E1',
-	"acirc":                     '\U000000E2',
-	"acute":                     '\U000000B4',
-	"aelig":                     '\U000000E6',
-	"agrave":                    '\U000000E0',
-	"amp":                       '\U00000026',
-	"aring":                     '\U000000E5',
-	"atilde":                    '\U000000E3',
-	"auml":                      '\U000000E4',
-	"brvbar":                    '\U000000A6',
-	"ccedil":                    '\U000000E7',
-	"cedil":                     '\U000000B8',
-	"cent":                      '\U000000A2',
-	"copy":                      '\U000000A9',
-	"curren":                    '\U000000A4',
-	"deg":                       '\U000000B0',
-	"divide":                    '\U000000F7',
-	"eacute":                    '\U000000E9',
-	"ecirc":                     '\U000000EA',
-	"egrave":                    '\U000000E8',
-	"eth":                       '\U000000F0',
-	"euml":                      '\U000000EB',
-	"frac12":                    '\U000000BD',
-	"frac14":                    '\U000000BC',
-	"frac34":                    '\U000000BE',
-	"gt":                        '\U0000003E',
-	"iacute":                    '\U000000ED',
-	"icirc":                     '\U000000EE',
-	"iexcl":                     '\U000000A1',
-	"igrave":                    '\U000000EC',
-	"iquest":                    '\U000000BF',
-	"iuml":                      '\U000000EF',
-	"laquo":                     '\U000000AB',
-	"lt":                        '\U0000003C',
-	"macr":                      '\U000000AF',
-	"micro":                     '\U000000B5',
-	"middot":                    '\U000000B7',
-	"nbsp":                      '\U000000A0',
-	"not":                       '\U000000AC',
-	"ntilde":                    '\U000000F1',
-	"oacute":                    '\U000000F3',
-	"ocirc":                     '\U000000F4',
-	"ograve":                    '\U000000F2',
-	"ordf":                      '\U000000AA',
-	"ordm":                      '\U000000BA',
-	"oslash":                    '\U000000F8',
-	"otilde":                    '\U000000F5',
-	"ouml":                      '\U000000F6',
-	"para":                      '\U000000B6',
-	"plusmn":                    '\U000000B1',
-	"pound":                     '\U000000A3',
-	"quot":                      '\U00000022',
-	"raquo":                     '\U000000BB',
-	"reg":                       '\U000000AE',
-	"sect":                      '\U000000A7',
-	"shy":                       '\U000000AD',
-	"sup1":                      '\U000000B9',
-	"sup2":                      '\U000000B2',
-	"sup3":                      '\U000000B3',
-	"szlig":                     '\U000000DF',
-	"thorn":                     '\U000000FE',
-	"times":                     '\U000000D7',
-	"uacute":                    '\U000000FA',
-	"ucirc":                     '\U000000FB',
-	"ugrave":                    '\U000000F9',
-	"uml":                       '\U000000A8',
-	"uuml":                      '\U000000FC',
-	"yacute":                    '\U000000FD',
-	"yen":                       '\U000000A5',
-	"yuml":                      '\U000000FF',
+	"Cross;":                           '\U00002A2F',
+	"Cscr;":                            '\U0001D49E',
+	"Cup;":                             '\U000022D3',
+	"CupCap;":                          '\U0000224D',
+	"DD;":                              '\U00002145',
+	"DDotrahd;":                        '\U00002911',
+	"DJcy;":                            '\U00000402',
+	"DScy;":                            '\U00000405',
+	"DZcy;":                            '\U0000040F',
+	"Dagger;":                          '\U00002021',
+	"Darr;":                            '\U000021A1',
+	"Dashv;":                           '\U00002AE4',
+	"Dcaron;":                          '\U0000010E',
+	"Dcy;":                             '\U00000414',
+	"Del;":                             '\U00002207',
+	"Delta;":                           '\U00000394',
+	"Dfr;":                             '\U0001D507',
+	"DiacriticalAcute;":                '\U000000B4',
+	"DiacriticalDot;":                  '\U000002D9',
+	"DiacriticalDoubleAcute;":          '\U000002DD',
+	"DiacriticalGrave;":                '\U00000060',
+	"DiacriticalTilde;":                '\U000002DC',
+	"Diamond;":                         '\U000022C4',
+	"DifferentialD;":                   '\U00002146',
+	"Dopf;":                            '\U0001D53B',
+	"Dot;":                             '\U000000A8',
+	"DotDot;":                          '\U000020DC',
+	"DotEqual;":                        '\U00002250',
+	"DoubleContourIntegral;":           '\U0000222F',
+	"DoubleDot;":                       '\U000000A8',
+	"DoubleDownArrow;":                 '\U000021D3',
+	"DoubleLeftArrow;":                 '\U000021D0',
+	"DoubleLeftRightArrow;":            '\U000021D4',
+	"DoubleLeftTee;":                   '\U00002AE4',
+	"DoubleLongLeftArrow;":             '\U000027F8',
+	"DoubleLongLeftRightArrow;":        '\U000027FA',
+	"DoubleLongRightArrow;":            '\U000027F9',
+	"DoubleRightArrow;":                '\U000021D2',
+	"DoubleRightTee;":                  '\U000022A8',
+	"DoubleUpArrow;":                   '\U000021D1',
+	"DoubleUpDownArrow;":               '\U000021D5',
+	"DoubleVerticalBar;":               '\U00002225',
+	"DownArrow;":                       '\U00002193',
+	"DownArrowBar;":                    '\U00002913',
+	"DownArrowUpArrow;":                '\U000021F5',
+	"DownBreve;":                       '\U00000311',
+	"DownLeftRightVector;":             '\U00002950',
+	"DownLeftTeeVector;":               '\U0000295E',
+	"DownLeftVector;":                  '\U000021BD',
+	"DownLeftVectorBar;":               '\U00002956',
+	"DownRightTeeVector;":              '\U0000295F',
+	"DownRightVector;":                 '\U000021C1',
+	"DownRightVectorBar;":              '\U00002957',
+	"DownTee;":                         '\U000022A4',
+	"DownTeeArrow;":                    '\U000021A7',
+	"Downarrow;":                       '\U000021D3',
+	"Dscr;":                            '\U0001D49F',
+	"Dstrok;":                          '\U00000110',
+	"ENG;":                             '\U0000014A',
+	"ETH;":                             '\U000000D0',
+	"Eacute;":                          '\U000000C9',
+	"Ecaron;":                          '\U0000011A',
+	"Ecirc;":                           '\U000000CA',
+	"Ecy;":                             '\U0000042D',
+	"Edot;":                            '\U00000116',
+	"Efr;":                             '\U0001D508',
+	"Egrave;":                          '\U000000C8',
+	"Element;":                         '\U00002208',
+	"Emacr;":                           '\U00000112',
+	"EmptySmallSquare;":                '\U000025FB',
+	"EmptyVerySmallSquare;":            '\U000025AB',
+	"Eogon;":                           '\U00000118',
+	"Eopf;":                            '\U0001D53C',
+	"Epsilon;":                         '\U00000395',
+	"Equal;":                           '\U00002A75',
+	"EqualTilde;":                      '\U00002242',
+	"Equilibrium;":                     '\U000021CC',
+	"Escr;":                            '\U00002130',
+	"Esim;":                            '\U00002A73',
+	"Eta;":                             '\U00000397',
+	"Euml;":                            '\U000000CB',
+	"Exists;":                          '\U00002203',
+	"ExponentialE;":                    '\U00002147',
+	"Fcy;":                             '\U00000424',
+	"Ffr;":                             '\U0001D509',
+	"FilledSmallSquare;":               '\U000025FC',
+	"FilledVerySmallSquare;":           '\U000025AA',
+	"Fopf;":                            '\U0001D53D',
+	"ForAll;":                          '\U00002200',
+	"Fouriertrf;":                      '\U00002131',
+	"Fscr;":                            '\U00002131',
+	"GJcy;":                            '\U00000403',
+	"GT;":                              '\U0000003E',
+	"Gamma;":                           '\U00000393',
+	"Gammad;":                          '\U000003DC',
+	"Gbreve;":                          '\U0000011E',
+	"Gcedil;":                          '\U00000122',
+	"Gcirc;":                           '\U0000011C',
+	"Gcy;":                             '\U00000413',
+	"Gdot;":                            '\U00000120',
+	"Gfr;":                             '\U0001D50A',
+	"Gg;":                              '\U000022D9',
+	"Gopf;":                            '\U0001D53E',
+	"GreaterEqual;":                    '\U00002265',
+	"GreaterEqualLess;":                '\U000022DB',
+	"GreaterFullEqual;":                '\U00002267',
+	"GreaterGreater;":                  '\U00002AA2',
+	"GreaterLess;":                     '\U00002277',
+	"GreaterSlantEqual;":               '\U00002A7E',
+	"GreaterTilde;":                    '\U00002273',
+	"Gscr;":                            '\U0001D4A2',
+	"Gt;":                              '\U0000226B',
+	"HARDcy;":                          '\U0000042A',
+	"Hacek;":                           '\U000002C7',
+	"Hat;":                             '\U0000005E',
+	"Hcirc;":                           '\U00000124',
+	"Hfr;":                             '\U0000210C',
+	"HilbertSpace;":                    '\U0000210B',
+	"Hopf;":                            '\U0000210D',
+	"HorizontalLine;":                  '\U00002500',
+	"Hscr;":                            '\U0000210B',
+	"Hstrok;":                          '\U00000126',
+	"HumpDownHump;":                    '\U0000224E',
+	"HumpEqual;":                       '\U0000224F',
+	"IEcy;":                            '\U00000415',
+	"IJlig;":                           '\U00000132',
+	"IOcy;":                            '\U00000401',
+	"Iacute;":                          '\U000000CD',
+	"Icirc;":                           '\U000000CE',
+	"Icy;":                             '\U00000418',
+	"Idot;":                            '\U00000130',
+	"Ifr;":                             '\U00002111',
+	"Igrave;":                          '\U000000CC',
+	"Im;":                              '\U00002111',
+	"Imacr;":                           '\U0000012A',
+	"ImaginaryI;":                      '\U00002148',
+	"Implies;":                         '\U000021D2',
+	"Int;":                             '\U0000222C',
+	"Integral;":                        '\U0000222B',
+	"Intersection;":                    '\U000022C2',
+	"InvisibleComma;":                  '\U00002063',
+	"InvisibleTimes;":                  '\U00002062',
+	"Iogon;":                           '\U0000012E',
+	"Iopf;":                            '\U0001D540',
+	"Iota;":                            '\U00000399',
+	"Iscr;":                            '\U00002110',
+	"Itilde;":                          '\U00000128',
+	"Iukcy;":                           '\U00000406',
+	"Iuml;":                            '\U000000CF',
+	"Jcirc;":                           '\U00000134',
+	"Jcy;":                             '\U00000419',
+	"Jfr;":                             '\U0001D50D',
+	"Jopf;":                            '\U0001D541',
+	"Jscr;":                            '\U0001D4A5',
+	"Jsercy;":                          '\U00000408',
+	"Jukcy;":                           '\U00000404',
+	"KHcy;":                            '\U00000425',
+	"KJcy;":                            '\U0000040C',
+	"Kappa;":                           '\U0000039A',
+	"Kcedil;":                          '\U00000136',
+	"Kcy;":                             '\U0000041A',
+	"Kfr;":                             '\U0001D50E',
+	"Kopf;":                            '\U0001D542',
+	"Kscr;":                            '\U0001D4A6',
+	"LJcy;":                            '\U00000409',
+	"LT;":                              '\U0000003C',
+	"Lacute;":                          '\U00000139',
+	"Lambda;":                          '\U0000039B',
+	"Lang;":                            '\U000027EA',
+	"Laplacetrf;":                      '\U00002112',
+	"Larr;":                            '\U0000219E',
+	"Lcaron;":                          '\U0000013D',
+	"Lcedil;":                          '\U0000013B',
+	"Lcy;":                             '\U0000041B',
+	"LeftAngleBracket;":                '\U000027E8',
+	"LeftArrow;":                       '\U00002190',
+	"LeftArrowBar;":                    '\U000021E4',
+	"LeftArrowRightArrow;":             '\U000021C6',
+	"LeftCeiling;":                     '\U00002308',
+	"LeftDoubleBracket;":               '\U000027E6',
+	"LeftDownTeeVector;":               '\U00002961',
+	"LeftDownVector;":                  '\U000021C3',
+	"LeftDownVectorBar;":               '\U00002959',
+	"LeftFloor;":                       '\U0000230A',
+	"LeftRightArrow;":                  '\U00002194',
+	"LeftRightVector;":                 '\U0000294E',
+	"LeftTee;":                         '\U000022A3',
+	"LeftTeeArrow;":                    '\U000021A4',
+	"LeftTeeVector;":                   '\U0000295A',
+	"LeftTriangle;":                    '\U000022B2',
+	"LeftTriangleBar;":                 '\U000029CF',
+	"LeftTriangleEqual;":               '\U000022B4',
+	"LeftUpDownVector;":                '\U00002951',
+	"LeftUpTeeVector;":                 '\U00002960',
+	"LeftUpVector;":                    '\U000021BF',
+	"LeftUpVectorBar;":                 '\U00002958',
+	"LeftVector;":                      '\U000021BC',
+	"LeftVectorBar;":                   '\U00002952',
+	"Leftarrow;":                       '\U000021D0',
+	"Leftrightarrow;":                  '\U000021D4',
+	"LessEqualGreater;":                '\U000022DA',
+	"LessFullEqual;":                   '\U00002266',
+	"LessGreater;":                     '\U00002276',
+	"LessLess;":                        '\U00002AA1',
+	"LessSlantEqual;":                  '\U00002A7D',
+	"LessTilde;":                       '\U00002272',
+	"Lfr;":                             '\U0001D50F',
+	"Ll;":                              '\U000022D8',
+	"Lleftarrow;":                      '\U000021DA',
+	"Lmidot;":                          '\U0000013F',
+	"LongLeftArrow;":                   '\U000027F5',
+	"LongLeftRightArrow;":              '\U000027F7',
+	"LongRightArrow;":                  '\U000027F6',
+	"Longleftarrow;":                   '\U000027F8',
+	"Longleftrightarrow;":              '\U000027FA',
+	"Longrightarrow;":                  '\U000027F9',
+	"Lopf;":                            '\U0001D543',
+	"LowerLeftArrow;":                  '\U00002199',
+	"LowerRightArrow;":                 '\U00002198',
+	"Lscr;":                            '\U00002112',
+	"Lsh;":                             '\U000021B0',
+	"Lstrok;":                          '\U00000141',
+	"Lt;":                              '\U0000226A',
+	"Map;":                             '\U00002905',
+	"Mcy;":                             '\U0000041C',
+	"MediumSpace;":                     '\U0000205F',
+	"Mellintrf;":                       '\U00002133',
+	"Mfr;":                             '\U0001D510',
+	"MinusPlus;":                       '\U00002213',
+	"Mopf;":                            '\U0001D544',
+	"Mscr;":                            '\U00002133',
+	"Mu;":                              '\U0000039C',
+	"NJcy;":                            '\U0000040A',
+	"Nacute;":                          '\U00000143',
+	"Ncaron;":                          '\U00000147',
+	"Ncedil;":                          '\U00000145',
+	"Ncy;":                             '\U0000041D',
+	"NegativeMediumSpace;":             '\U0000200B',
+	"NegativeThickSpace;":              '\U0000200B',
+	"NegativeThinSpace;":               '\U0000200B',
+	"NegativeVeryThinSpace;":           '\U0000200B',
+	"NestedGreaterGreater;":            '\U0000226B',
+	"NestedLessLess;":                  '\U0000226A',
+	"NewLine;":                         '\U0000000A',
+	"Nfr;":                             '\U0001D511',
+	"NoBreak;":                         '\U00002060',
+	"NonBreakingSpace;":                '\U000000A0',
+	"Nopf;":                            '\U00002115',
+	"Not;":                             '\U00002AEC',
+	"NotCongruent;":                    '\U00002262',
+	"NotCupCap;":                       '\U0000226D',
+	"NotDoubleVerticalBar;":            '\U00002226',
+	"NotElement;":                      '\U00002209',
+	"NotEqual;":                        '\U00002260',
+	"NotExists;":                       '\U00002204',
+	"NotGreater;":                      '\U0000226F',
+	"NotGreaterEqual;":                 '\U00002271',
+	"NotGreaterLess;":                  '\U00002279',
+	"NotGreaterTilde;":                 '\U00002275',
+	"NotLeftTriangle;":                 '\U000022EA',
+	"NotLeftTriangleEqual;":            '\U000022EC',
+	"NotLess;":                         '\U0000226E',
+	"NotLessEqual;":                    '\U00002270',
+	"NotLessGreater;":                  '\U00002278',
+	"NotLessTilde;":                    '\U00002274',
+	"NotPrecedes;":                     '\U00002280',
+	"NotPrecedesSlantEqual;":           '\U000022E0',
+	"NotReverseElement;":               '\U0000220C',
+	"NotRightTriangle;":                '\U000022EB',
+	"NotRightTriangleEqual;":           '\U000022ED',
+	"NotSquareSubsetEqual;":            '\U000022E2',
+	"NotSquareSupersetEqual;":          '\U000022E3',
+	"NotSubsetEqual;":                  '\U00002288',
+	"NotSucceeds;":                     '\U00002281',
+	"NotSucceedsSlantEqual;":           '\U000022E1',
+	"NotSupersetEqual;":                '\U00002289',
+	"NotTilde;":                        '\U00002241',
+	"NotTildeEqual;":                   '\U00002244',
+	"NotTildeFullEqual;":               '\U00002247',
+	"NotTildeTilde;":                   '\U00002249',
+	"NotVerticalBar;":                  '\U00002224',
+	"Nscr;":                            '\U0001D4A9',
+	"Ntilde;":                          '\U000000D1',
+	"Nu;":                              '\U0000039D',
+	"OElig;":                           '\U00000152',
+	"Oacute;":                          '\U000000D3',
+	"Ocirc;":                           '\U000000D4',
+	"Ocy;":                             '\U0000041E',
+	"Odblac;":                          '\U00000150',
+	"Ofr;":                             '\U0001D512',
+	"Ograve;":                          '\U000000D2',
+	"Omacr;":                           '\U0000014C',
+	"Omega;":                           '\U000003A9',
+	"Omicron;":                         '\U0000039F',
+	"Oopf;":                            '\U0001D546',
+	"OpenCurlyDoubleQuote;":            '\U0000201C',
+	"OpenCurlyQuote;":                  '\U00002018',
+	"Or;":                              '\U00002A54',
+	"Oscr;":                            '\U0001D4AA',
+	"Oslash;":                          '\U000000D8',
+	"Otilde;":                          '\U000000D5',
+	"Otimes;":                          '\U00002A37',
+	"Ouml;":                            '\U000000D6',
+	"OverBar;":                         '\U0000203E',
+	"OverBrace;":                       '\U000023DE',
+	"OverBracket;":                     '\U000023B4',
+	"OverParenthesis;":                 '\U000023DC',
+	"PartialD;":                        '\U00002202',
+	"Pcy;":                             '\U0000041F',
+	"Pfr;":                             '\U0001D513',
+	"Phi;":                             '\U000003A6',
+	"Pi;":                              '\U000003A0',
+	"PlusMinus;":                       '\U000000B1',
+	"Poincareplane;":                   '\U0000210C',
+	"Popf;":                            '\U00002119',
+	"Pr;":                              '\U00002ABB',
+	"Precedes;":                        '\U0000227A',
+	"PrecedesEqual;":                   '\U00002AAF',
+	"PrecedesSlantEqual;":              '\U0000227C',
+	"PrecedesTilde;":                   '\U0000227E',
+	"Prime;":                           '\U00002033',
+	"Product;":                         '\U0000220F',
+	"Proportion;":                      '\U00002237',
+	"Proportional;":                    '\U0000221D',
+	"Pscr;":                            '\U0001D4AB',
+	"Psi;":                             '\U000003A8',
+	"QUOT;":                            '\U00000022',
+	"Qfr;":                             '\U0001D514',
+	"Qopf;":                            '\U0000211A',
+	"Qscr;":                            '\U0001D4AC',
+	"RBarr;":                           '\U00002910',
+	"REG;":                             '\U000000AE',
+	"Racute;":                          '\U00000154',
+	"Rang;":                            '\U000027EB',
+	"Rarr;":                            '\U000021A0',
+	"Rarrtl;":                          '\U00002916',
+	"Rcaron;":                          '\U00000158',
+	"Rcedil;":                          '\U00000156',
+	"Rcy;":                             '\U00000420',
+	"Re;":                              '\U0000211C',
+	"ReverseElement;":                  '\U0000220B',
+	"ReverseEquilibrium;":              '\U000021CB',
+	"ReverseUpEquilibrium;":            '\U0000296F',
+	"Rfr;":                             '\U0000211C',
+	"Rho;":                             '\U000003A1',
+	"RightAngleBracket;":               '\U000027E9',
+	"RightArrow;":                      '\U00002192',
+	"RightArrowBar;":                   '\U000021E5',
+	"RightArrowLeftArrow;":             '\U000021C4',
+	"RightCeiling;":                    '\U00002309',
+	"RightDoubleBracket;":              '\U000027E7',
+	"RightDownTeeVector;":              '\U0000295D',
+	"RightDownVector;":                 '\U000021C2',
+	"RightDownVectorBar;":              '\U00002955',
+	"RightFloor;":                      '\U0000230B',
+	"RightTee;":                        '\U000022A2',
+	"RightTeeArrow;":                   '\U000021A6',
+	"RightTeeVector;":                  '\U0000295B',
+	"RightTriangle;":                   '\U000022B3',
+	"RightTriangleBar;":                '\U000029D0',
+	"RightTriangleEqual;":              '\U000022B5',
+	"RightUpDownVector;":               '\U0000294F',
+	"RightUpTeeVector;":                '\U0000295C',
+	"RightUpVector;":                   '\U000021BE',
+	"RightUpVectorBar;":                '\U00002954',
+	"RightVector;":                     '\U000021C0',
+	"RightVectorBar;":                  '\U00002953',
+	"Rightarrow;":                      '\U000021D2',
+	"Ropf;":                            '\U0000211D',
+	"RoundImplies;":                    '\U00002970',
+	"Rrightarrow;":                     '\U000021DB',
+	"Rscr;":                            '\U0000211B',
+	"Rsh;":                             '\U000021B1',
+	"RuleDelayed;":                     '\U000029F4',
+	"SHCHcy;":                          '\U00000429',
+	"SHcy;":                            '\U00000428',
+	"SOFTcy;":                          '\U0000042C',
+	"Sacute;":                          '\U0000015A',
+	"Sc;":                              '\U00002ABC',
+	"Scaron;":                          '\U00000160',
+	"Scedil;":                          '\U0000015E',
+	"Scirc;":                           '\U0000015C',
+	"Scy;":                             '\U00000421',
+	"Sfr;":                             '\U0001D516',
+	"ShortDownArrow;":                  '\U00002193',
+	"ShortLeftArrow;":                  '\U00002190',
+	"ShortRightArrow;":                 '\U00002192',
+	"ShortUpArrow;":                    '\U00002191',
+	"Sigma;":                           '\U000003A3',
+	"SmallCircle;":                     '\U00002218',
+	"Sopf;":                            '\U0001D54A',
+	"Sqrt;":                            '\U0000221A',
+	"Square;":                          '\U000025A1',
+	"SquareIntersection;":              '\U00002293',
+	"SquareSubset;":                    '\U0000228F',
+	"SquareSubsetEqual;":               '\U00002291',
+	"SquareSuperset;":                  '\U00002290',
+	"SquareSupersetEqual;":             '\U00002292',
+	"SquareUnion;":                     '\U00002294',
+	"Sscr;":                            '\U0001D4AE',
+	"Star;":                            '\U000022C6',
+	"Sub;":                             '\U000022D0',
+	"Subset;":                          '\U000022D0',
+	"SubsetEqual;":                     '\U00002286',
+	"Succeeds;":                        '\U0000227B',
+	"SucceedsEqual;":                   '\U00002AB0',
+	"SucceedsSlantEqual;":              '\U0000227D',
+	"SucceedsTilde;":                   '\U0000227F',
+	"SuchThat;":                        '\U0000220B',
+	"Sum;":                             '\U00002211',
+	"Sup;":                             '\U000022D1',
+	"Superset;":                        '\U00002283',
+	"SupersetEqual;":                   '\U00002287',
+	"Supset;":                          '\U000022D1',
+	"THORN;":                           '\U000000DE',
+	"TRADE;":                           '\U00002122',
+	"TSHcy;":                           '\U0000040B',
+	"TScy;":                            '\U00000426',
+	"Tab;":                             '\U00000009',
+	"Tau;":                             '\U000003A4',
+	"Tcaron;":                          '\U00000164',
+	"Tcedil;":                          '\U00000162',
+	"Tcy;":                             '\U00000422',
+	"Tfr;":                             '\U0001D517',
+	"Therefore;":                       '\U00002234',
+	"Theta;":                           '\U00000398',
+	"ThinSpace;":                       '\U00002009',
+	"Tilde;":                           '\U0000223C',
+	"TildeEqual;":                      '\U00002243',
+	"TildeFullEqual;":                  '\U00002245',
+	"TildeTilde;":                      '\U00002248',
+	"Topf;":                            '\U0001D54B',
+	"TripleDot;":                       '\U000020DB',
+	"Tscr;":                            '\U0001D4AF',
+	"Tstrok;":                          '\U00000166',
+	"Uacute;":                          '\U000000DA',
+	"Uarr;":                            '\U0000219F',
+	"Uarrocir;":                        '\U00002949',
+	"Ubrcy;":                           '\U0000040E',
+	"Ubreve;":                          '\U0000016C',
+	"Ucirc;":                           '\U000000DB',
+	"Ucy;":                             '\U00000423',
+	"Udblac;":                          '\U00000170',
+	"Ufr;":                             '\U0001D518',
+	"Ugrave;":                          '\U000000D9',
+	"Umacr;":                           '\U0000016A',
+	"UnderBar;":                        '\U0000005F',
+	"UnderBrace;":                      '\U000023DF',
+	"UnderBracket;":                    '\U000023B5',
+	"UnderParenthesis;":                '\U000023DD',
+	"Union;":                           '\U000022C3',
+	"UnionPlus;":                       '\U0000228E',
+	"Uogon;":                           '\U00000172',
+	"Uopf;":                            '\U0001D54C',
+	"UpArrow;":                         '\U00002191',
+	"UpArrowBar;":                      '\U00002912',
+	"UpArrowDownArrow;":                '\U000021C5',
+	"UpDownArrow;":                     '\U00002195',
+	"UpEquilibrium;":                   '\U0000296E',
+	"UpTee;":                           '\U000022A5',
+	"UpTeeArrow;":                      '\U000021A5',
+	"Uparrow;":                         '\U000021D1',
+	"Updownarrow;":                     '\U000021D5',
+	"UpperLeftArrow;":                  '\U00002196',
+	"UpperRightArrow;":                 '\U00002197',
+	"Upsi;":                            '\U000003D2',
+	"Upsilon;":                         '\U000003A5',
+	"Uring;":                           '\U0000016E',
+	"Uscr;":                            '\U0001D4B0',
+	"Utilde;":                          '\U00000168',
+	"Uuml;":                            '\U000000DC',
+	"VDash;":                           '\U000022AB',
+	"Vbar;":                            '\U00002AEB',
+	"Vcy;":                             '\U00000412',
+	"Vdash;":                           '\U000022A9',
+	"Vdashl;":                          '\U00002AE6',
+	"Vee;":                             '\U000022C1',
+	"Verbar;":                          '\U00002016',
+	"Vert;":                            '\U00002016',
+	"VerticalBar;":                     '\U00002223',
+	"VerticalLine;":                    '\U0000007C',
+	"VerticalSeparator;":               '\U00002758',
+	"VerticalTilde;":                   '\U00002240',
+	"VeryThinSpace;":                   '\U0000200A',
+	"Vfr;":                             '\U0001D519',
+	"Vopf;":                            '\U0001D54D',
+	"Vscr;":                            '\U0001D4B1',
+	"Vvdash;":                          '\U000022AA',
+	"Wcirc;":                           '\U00000174',
+	"Wedge;":                           '\U000022C0',
+	"Wfr;":                             '\U0001D51A',
+	"Wopf;":                            '\U0001D54E',
+	"Wscr;":                            '\U0001D4B2',
+	"Xfr;":                             '\U0001D51B',
+	"Xi;":                              '\U0000039E',
+	"Xopf;":                            '\U0001D54F',
+	"Xscr;":                            '\U0001D4B3',
+	"YAcy;":                            '\U0000042F',
+	"YIcy;":                            '\U00000407',
+	"YUcy;":                            '\U0000042E',
+	"Yacute;":                          '\U000000DD',
+	"Ycirc;":                           '\U00000176',
+	"Ycy;":                             '\U0000042B',
+	"Yfr;":                             '\U0001D51C',
+	"Yopf;":                            '\U0001D550',
+	"Yscr;":                            '\U0001D4B4',
+	"Yuml;":                            '\U00000178',
+	"ZHcy;":                            '\U00000416',
+	"Zacute;":                          '\U00000179',
+	"Zcaron;":                          '\U0000017D',
+	"Zcy;":                             '\U00000417',
+	"Zdot;":                            '\U0000017B',
+	"ZeroWidthSpace;":                  '\U0000200B',
+	"Zeta;":                            '\U00000396',
+	"Zfr;":                             '\U00002128',
+	"Zopf;":                            '\U00002124',
+	"Zscr;":                            '\U0001D4B5',
+	"aacute;":                          '\U000000E1',
+	"abreve;":                          '\U00000103',
+	"ac;":                              '\U0000223E',
+	"acd;":                             '\U0000223F',
+	"acirc;":                           '\U000000E2',
+	"acute;":                           '\U000000B4',
+	"acy;":                             '\U00000430',
+	"aelig;":                           '\U000000E6',
+	"af;":                              '\U00002061',
+	"afr;":                             '\U0001D51E',
+	"agrave;":                          '\U000000E0',
+	"alefsym;":                         '\U00002135',
+	"aleph;":                           '\U00002135',
+	"alpha;":                           '\U000003B1',
+	"amacr;":                           '\U00000101',
+	"amalg;":                           '\U00002A3F',
+	"amp;":                             '\U00000026',
+	"and;":                             '\U00002227',
+	"andand;":                          '\U00002A55',
+	"andd;":                            '\U00002A5C',
+	"andslope;":                        '\U00002A58',
+	"andv;":                            '\U00002A5A',
+	"ang;":                             '\U00002220',
+	"ange;":                            '\U000029A4',
+	"angle;":                           '\U00002220',
+	"angmsd;":                          '\U00002221',
+	"angmsdaa;":                        '\U000029A8',
+	"angmsdab;":                        '\U000029A9',
+	"angmsdac;":                        '\U000029AA',
+	"angmsdad;":                        '\U000029AB',
+	"angmsdae;":                        '\U000029AC',
+	"angmsdaf;":                        '\U000029AD',
+	"angmsdag;":                        '\U000029AE',
+	"angmsdah;":                        '\U000029AF',
+	"angrt;":                           '\U0000221F',
+	"angrtvb;":                         '\U000022BE',
+	"angrtvbd;":                        '\U0000299D',
+	"angsph;":                          '\U00002222',
+	"angst;":                           '\U000000C5',
+	"angzarr;":                         '\U0000237C',
+	"aogon;":                           '\U00000105',
+	"aopf;":                            '\U0001D552',
+	"ap;":                              '\U00002248',
+	"apE;":                             '\U00002A70',
+	"apacir;":                          '\U00002A6F',
+	"ape;":                             '\U0000224A',
+	"apid;":                            '\U0000224B',
+	"apos;":                            '\U00000027',
+	"approx;":                          '\U00002248',
+	"approxeq;":                        '\U0000224A',
+	"aring;":                           '\U000000E5',
+	"ascr;":                            '\U0001D4B6',
+	"ast;":                             '\U0000002A',
+	"asymp;":                           '\U00002248',
+	"asympeq;":                         '\U0000224D',
+	"atilde;":                          '\U000000E3',
+	"auml;":                            '\U000000E4',
+	"awconint;":                        '\U00002233',
+	"awint;":                           '\U00002A11',
+	"bNot;":                            '\U00002AED',
+	"backcong;":                        '\U0000224C',
+	"backepsilon;":                     '\U000003F6',
+	"backprime;":                       '\U00002035',
+	"backsim;":                         '\U0000223D',
+	"backsimeq;":                       '\U000022CD',
+	"barvee;":                          '\U000022BD',
+	"barwed;":                          '\U00002305',
+	"barwedge;":                        '\U00002305',
+	"bbrk;":                            '\U000023B5',
+	"bbrktbrk;":                        '\U000023B6',
+	"bcong;":                           '\U0000224C',
+	"bcy;":                             '\U00000431',
+	"bdquo;":                           '\U0000201E',
+	"becaus;":                          '\U00002235',
+	"because;":                         '\U00002235',
+	"bemptyv;":                         '\U000029B0',
+	"bepsi;":                           '\U000003F6',
+	"bernou;":                          '\U0000212C',
+	"beta;":                            '\U000003B2',
+	"beth;":                            '\U00002136',
+	"between;":                         '\U0000226C',
+	"bfr;":                             '\U0001D51F',
+	"bigcap;":                          '\U000022C2',
+	"bigcirc;":                         '\U000025EF',
+	"bigcup;":                          '\U000022C3',
+	"bigodot;":                         '\U00002A00',
+	"bigoplus;":                        '\U00002A01',
+	"bigotimes;":                       '\U00002A02',
+	"bigsqcup;":                        '\U00002A06',
+	"bigstar;":                         '\U00002605',
+	"bigtriangledown;":                 '\U000025BD',
+	"bigtriangleup;":                   '\U000025B3',
+	"biguplus;":                        '\U00002A04',
+	"bigvee;":                          '\U000022C1',
+	"bigwedge;":                        '\U000022C0',
+	"bkarow;":                          '\U0000290D',
+	"blacklozenge;":                    '\U000029EB',
+	"blacksquare;":                     '\U000025AA',
+	"blacktriangle;":                   '\U000025B4',
+	"blacktriangledown;":               '\U000025BE',
+	"blacktriangleleft;":               '\U000025C2',
+	"blacktriangleright;":              '\U000025B8',
+	"blank;":                           '\U00002423',
+	"blk12;":                           '\U00002592',
+	"blk14;":                           '\U00002591',
+	"blk34;":                           '\U00002593',
+	"block;":                           '\U00002588',
+	"bnot;":                            '\U00002310',
+	"bopf;":                            '\U0001D553',
+	"bot;":                             '\U000022A5',
+	"bottom;":                          '\U000022A5',
+	"bowtie;":                          '\U000022C8',
+	"boxDL;":                           '\U00002557',
+	"boxDR;":                           '\U00002554',
+	"boxDl;":                           '\U00002556',
+	"boxDr;":                           '\U00002553',
+	"boxH;":                            '\U00002550',
+	"boxHD;":                           '\U00002566',
+	"boxHU;":                           '\U00002569',
+	"boxHd;":                           '\U00002564',
+	"boxHu;":                           '\U00002567',
+	"boxUL;":                           '\U0000255D',
+	"boxUR;":                           '\U0000255A',
+	"boxUl;":                           '\U0000255C',
+	"boxUr;":                           '\U00002559',
+	"boxV;":                            '\U00002551',
+	"boxVH;":                           '\U0000256C',
+	"boxVL;":                           '\U00002563',
+	"boxVR;":                           '\U00002560',
+	"boxVh;":                           '\U0000256B',
+	"boxVl;":                           '\U00002562',
+	"boxVr;":                           '\U0000255F',
+	"boxbox;":                          '\U000029C9',
+	"boxdL;":                           '\U00002555',
+	"boxdR;":                           '\U00002552',
+	"boxdl;":                           '\U00002510',
+	"boxdr;":                           '\U0000250C',
+	"boxh;":                            '\U00002500',
+	"boxhD;":                           '\U00002565',
+	"boxhU;":                           '\U00002568',
+	"boxhd;":                           '\U0000252C',
+	"boxhu;":                           '\U00002534',
+	"boxminus;":                        '\U0000229F',
+	"boxplus;":                         '\U0000229E',
+	"boxtimes;":                        '\U000022A0',
+	"boxuL;":                           '\U0000255B',
+	"boxuR;":                           '\U00002558',
+	"boxul;":                           '\U00002518',
+	"boxur;":                           '\U00002514',
+	"boxv;":                            '\U00002502',
+	"boxvH;":                           '\U0000256A',
+	"boxvL;":                           '\U00002561',
+	"boxvR;":                           '\U0000255E',
+	"boxvh;":                           '\U0000253C',
+	"boxvl;":                           '\U00002524',
+	"boxvr;":                           '\U0000251C',
+	"bprime;":                          '\U00002035',
+	"breve;":                           '\U000002D8',
+	"brvbar;":                          '\U000000A6',
+	"bscr;":                            '\U0001D4B7',
+	"bsemi;":                           '\U0000204F',
+	"bsim;":                            '\U0000223D',
+	"bsime;":                           '\U000022CD',
+	"bsol;":                            '\U0000005C',
+	"bsolb;":                           '\U000029C5',
+	"bsolhsub;":                        '\U000027C8',
+	"bull;":                            '\U00002022',
+	"bullet;":                          '\U00002022',
+	"bump;":                            '\U0000224E',
+	"bumpE;":                           '\U00002AAE',
+	"bumpe;":                           '\U0000224F',
+	"bumpeq;":                          '\U0000224F',
+	"cacute;":                          '\U00000107',
+	"cap;":                             '\U00002229',
+	"capand;":                          '\U00002A44',
+	"capbrcup;":                        '\U00002A49',
+	"capcap;":                          '\U00002A4B',
+	"capcup;":                          '\U00002A47',
+	"capdot;":                          '\U00002A40',
+	"caret;":                           '\U00002041',
+	"caron;":                           '\U000002C7',
+	"ccaps;":                           '\U00002A4D',
+	"ccaron;":                          '\U0000010D',
+	"ccedil;":                          '\U000000E7',
+	"ccirc;":                           '\U00000109',
+	"ccups;":                           '\U00002A4C',
+	"ccupssm;":                         '\U00002A50',
+	"cdot;":                            '\U0000010B',
+	"cedil;":                           '\U000000B8',
+	"cemptyv;":                         '\U000029B2',
+	"cent;":                            '\U000000A2',
+	"centerdot;":                       '\U000000B7',
+	"cfr;":                             '\U0001D520',
+	"chcy;":                            '\U00000447',
+	"check;":                           '\U00002713',
+	"checkmark;":                       '\U00002713',
+	"chi;":                             '\U000003C7',
+	"cir;":                             '\U000025CB',
+	"cirE;":                            '\U000029C3',
+	"circ;":                            '\U000002C6',
+	"circeq;":                          '\U00002257',
+	"circlearrowleft;":                 '\U000021BA',
+	"circlearrowright;":                '\U000021BB',
+	"circledR;":                        '\U000000AE',
+	"circledS;":                        '\U000024C8',
+	"circledast;":                      '\U0000229B',
+	"circledcirc;":                     '\U0000229A',
+	"circleddash;":                     '\U0000229D',
+	"cire;":                            '\U00002257',
+	"cirfnint;":                        '\U00002A10',
+	"cirmid;":                          '\U00002AEF',
+	"cirscir;":                         '\U000029C2',
+	"clubs;":                           '\U00002663',
+	"clubsuit;":                        '\U00002663',
+	"colon;":                           '\U0000003A',
+	"colone;":                          '\U00002254',
+	"coloneq;":                         '\U00002254',
+	"comma;":                           '\U0000002C',
+	"commat;":                          '\U00000040',
+	"comp;":                            '\U00002201',
+	"compfn;":                          '\U00002218',
+	"complement;":                      '\U00002201',
+	"complexes;":                       '\U00002102',
+	"cong;":                            '\U00002245',
+	"congdot;":                         '\U00002A6D',
+	"conint;":                          '\U0000222E',
+	"copf;":                            '\U0001D554',
+	"coprod;":                          '\U00002210',
+	"copy;":                            '\U000000A9',
+	"copysr;":                          '\U00002117',
+	"crarr;":                           '\U000021B5',
+	"cross;":                           '\U00002717',
+	"cscr;":                            '\U0001D4B8',
+	"csub;":                            '\U00002ACF',
+	"csube;":                           '\U00002AD1',
+	"csup;":                            '\U00002AD0',
+	"csupe;":                           '\U00002AD2',
+	"ctdot;":                           '\U000022EF',
+	"cudarrl;":                         '\U00002938',
+	"cudarrr;":                         '\U00002935',
+	"cuepr;":                           '\U000022DE',
+	"cuesc;":                           '\U000022DF',
+	"cularr;":                          '\U000021B6',
+	"cularrp;":                         '\U0000293D',
+	"cup;":                             '\U0000222A',
+	"cupbrcap;":                        '\U00002A48',
+	"cupcap;":                          '\U00002A46',
+	"cupcup;":                          '\U00002A4A',
+	"cupdot;":                          '\U0000228D',
+	"cupor;":                           '\U00002A45',
+	"curarr;":                          '\U000021B7',
+	"curarrm;":                         '\U0000293C',
+	"curlyeqprec;":                     '\U000022DE',
+	"curlyeqsucc;":                     '\U000022DF',
+	"curlyvee;":                        '\U000022CE',
+	"curlywedge;":                      '\U000022CF',
+	"curren;":                          '\U000000A4',
+	"curvearrowleft;":                  '\U000021B6',
+	"curvearrowright;":                 '\U000021B7',
+	"cuvee;":                           '\U000022CE',
+	"cuwed;":                           '\U000022CF',
+	"cwconint;":                        '\U00002232',
+	"cwint;":                           '\U00002231',
+	"cylcty;":                          '\U0000232D',
+	"dArr;":                            '\U000021D3',
+	"dHar;":                            '\U00002965',
+	"dagger;":                          '\U00002020',
+	"daleth;":                          '\U00002138',
+	"darr;":                            '\U00002193',
+	"dash;":                            '\U00002010',
+	"dashv;":                           '\U000022A3',
+	"dbkarow;":                         '\U0000290F',
+	"dblac;":                           '\U000002DD',
+	"dcaron;":                          '\U0000010F',
+	"dcy;":                             '\U00000434',
+	"dd;":                              '\U00002146',
+	"ddagger;":                         '\U00002021',
+	"ddarr;":                           '\U000021CA',
+	"ddotseq;":                         '\U00002A77',
+	"deg;":                             '\U000000B0',
+	"delta;":                           '\U000003B4',
+	"demptyv;":                         '\U000029B1',
+	"dfisht;":                          '\U0000297F',
+	"dfr;":                             '\U0001D521',
+	"dharl;":                           '\U000021C3',
+	"dharr;":                           '\U000021C2',
+	"diam;":                            '\U000022C4',
+	"diamond;":                         '\U000022C4',
+	"diamondsuit;":                     '\U00002666',
+	"diams;":                           '\U00002666',
+	"die;":                             '\U000000A8',
+	"digamma;":                         '\U000003DD',
+	"disin;":                           '\U000022F2',
+	"div;":                             '\U000000F7',
+	"divide;":                          '\U000000F7',
+	"divideontimes;":                   '\U000022C7',
+	"divonx;":                          '\U000022C7',
+	"djcy;":                            '\U00000452',
+	"dlcorn;":                          '\U0000231E',
+	"dlcrop;":                          '\U0000230D',
+	"dollar;":                          '\U00000024',
+	"dopf;":                            '\U0001D555',
+	"dot;":                             '\U000002D9',
+	"doteq;":                           '\U00002250',
+	"doteqdot;":                        '\U00002251',
+	"dotminus;":                        '\U00002238',
+	"dotplus;":                         '\U00002214',
+	"dotsquare;":                       '\U000022A1',
+	"doublebarwedge;":                  '\U00002306',
+	"downarrow;":                       '\U00002193',
+	"downdownarrows;":                  '\U000021CA',
+	"downharpoonleft;":                 '\U000021C3',
+	"downharpoonright;":                '\U000021C2',
+	"drbkarow;":                        '\U00002910',
+	"drcorn;":                          '\U0000231F',
+	"drcrop;":                          '\U0000230C',
+	"dscr;":                            '\U0001D4B9',
+	"dscy;":                            '\U00000455',
+	"dsol;":                            '\U000029F6',
+	"dstrok;":                          '\U00000111',
+	"dtdot;":                           '\U000022F1',
+	"dtri;":                            '\U000025BF',
+	"dtrif;":                           '\U000025BE',
+	"duarr;":                           '\U000021F5',
+	"duhar;":                           '\U0000296F',
+	"dwangle;":                         '\U000029A6',
+	"dzcy;":                            '\U0000045F',
+	"dzigrarr;":                        '\U000027FF',
+	"eDDot;":                           '\U00002A77',
+	"eDot;":                            '\U00002251',
+	"eacute;":                          '\U000000E9',
+	"easter;":                          '\U00002A6E',
+	"ecaron;":                          '\U0000011B',
+	"ecir;":                            '\U00002256',
+	"ecirc;":                           '\U000000EA',
+	"ecolon;":                          '\U00002255',
+	"ecy;":                             '\U0000044D',
+	"edot;":                            '\U00000117',
+	"ee;":                              '\U00002147',
+	"efDot;":                           '\U00002252',
+	"efr;":                             '\U0001D522',
+	"eg;":                              '\U00002A9A',
+	"egrave;":                          '\U000000E8',
+	"egs;":                             '\U00002A96',
+	"egsdot;":                          '\U00002A98',
+	"el;":                              '\U00002A99',
+	"elinters;":                        '\U000023E7',
+	"ell;":                             '\U00002113',
+	"els;":                             '\U00002A95',
+	"elsdot;":                          '\U00002A97',
+	"emacr;":                           '\U00000113',
+	"empty;":                           '\U00002205',
+	"emptyset;":                        '\U00002205',
+	"emptyv;":                          '\U00002205',
+	"emsp;":                            '\U00002003',
+	"emsp13;":                          '\U00002004',
+	"emsp14;":                          '\U00002005',
+	"eng;":                             '\U0000014B',
+	"ensp;":                            '\U00002002',
+	"eogon;":                           '\U00000119',
+	"eopf;":                            '\U0001D556',
+	"epar;":                            '\U000022D5',
+	"eparsl;":                          '\U000029E3',
+	"eplus;":                           '\U00002A71',
+	"epsi;":                            '\U000003B5',
+	"epsilon;":                         '\U000003B5',
+	"epsiv;":                           '\U000003F5',
+	"eqcirc;":                          '\U00002256',
+	"eqcolon;":                         '\U00002255',
+	"eqsim;":                           '\U00002242',
+	"eqslantgtr;":                      '\U00002A96',
+	"eqslantless;":                     '\U00002A95',
+	"equals;":                          '\U0000003D',
+	"equest;":                          '\U0000225F',
+	"equiv;":                           '\U00002261',
+	"equivDD;":                         '\U00002A78',
+	"eqvparsl;":                        '\U000029E5',
+	"erDot;":                           '\U00002253',
+	"erarr;":                           '\U00002971',
+	"escr;":                            '\U0000212F',
+	"esdot;":                           '\U00002250',
+	"esim;":                            '\U00002242',
+	"eta;":                             '\U000003B7',
+	"eth;":                             '\U000000F0',
+	"euml;":                            '\U000000EB',
+	"euro;":                            '\U000020AC',
+	"excl;":                            '\U00000021',
+	"exist;":                           '\U00002203',
+	"expectation;":                     '\U00002130',
+	"exponentiale;":                    '\U00002147',
+	"fallingdotseq;":                   '\U00002252',
+	"fcy;":                             '\U00000444',
+	"female;":                          '\U00002640',
+	"ffilig;":                          '\U0000FB03',
+	"fflig;":                           '\U0000FB00',
+	"ffllig;":                          '\U0000FB04',
+	"ffr;":                             '\U0001D523',
+	"filig;":                           '\U0000FB01',
+	"flat;":                            '\U0000266D',
+	"fllig;":                           '\U0000FB02',
+	"fltns;":                           '\U000025B1',
+	"fnof;":                            '\U00000192',
+	"fopf;":                            '\U0001D557',
+	"forall;":                          '\U00002200',
+	"fork;":                            '\U000022D4',
+	"forkv;":                           '\U00002AD9',
+	"fpartint;":                        '\U00002A0D',
+	"frac12;":                          '\U000000BD',
+	"frac13;":                          '\U00002153',
+	"frac14;":                          '\U000000BC',
+	"frac15;":                          '\U00002155',
+	"frac16;":                          '\U00002159',
+	"frac18;":                          '\U0000215B',
+	"frac23;":                          '\U00002154',
+	"frac25;":                          '\U00002156',
+	"frac34;":                          '\U000000BE',
+	"frac35;":                          '\U00002157',
+	"frac38;":                          '\U0000215C',
+	"frac45;":                          '\U00002158',
+	"frac56;":                          '\U0000215A',
+	"frac58;":                          '\U0000215D',
+	"frac78;":                          '\U0000215E',
+	"frasl;":                           '\U00002044',
+	"frown;":                           '\U00002322',
+	"fscr;":                            '\U0001D4BB',
+	"gE;":                              '\U00002267',
+	"gEl;":                             '\U00002A8C',
+	"gacute;":                          '\U000001F5',
+	"gamma;":                           '\U000003B3',
+	"gammad;":                          '\U000003DD',
+	"gap;":                             '\U00002A86',
+	"gbreve;":                          '\U0000011F',
+	"gcirc;":                           '\U0000011D',
+	"gcy;":                             '\U00000433',
+	"gdot;":                            '\U00000121',
+	"ge;":                              '\U00002265',
+	"gel;":                             '\U000022DB',
+	"geq;":                             '\U00002265',
+	"geqq;":                            '\U00002267',
+	"geqslant;":                        '\U00002A7E',
+	"ges;":                             '\U00002A7E',
+	"gescc;":                           '\U00002AA9',
+	"gesdot;":                          '\U00002A80',
+	"gesdoto;":                         '\U00002A82',
+	"gesdotol;":                        '\U00002A84',
+	"gesles;":                          '\U00002A94',
+	"gfr;":                             '\U0001D524',
+	"gg;":                              '\U0000226B',
+	"ggg;":                             '\U000022D9',
+	"gimel;":                           '\U00002137',
+	"gjcy;":                            '\U00000453',
+	"gl;":                              '\U00002277',
+	"glE;":                             '\U00002A92',
+	"gla;":                             '\U00002AA5',
+	"glj;":                             '\U00002AA4',
+	"gnE;":                             '\U00002269',
+	"gnap;":                            '\U00002A8A',
+	"gnapprox;":                        '\U00002A8A',
+	"gne;":                             '\U00002A88',
+	"gneq;":                            '\U00002A88',
+	"gneqq;":                           '\U00002269',
+	"gnsim;":                           '\U000022E7',
+	"gopf;":                            '\U0001D558',
+	"grave;":                           '\U00000060',
+	"gscr;":                            '\U0000210A',
+	"gsim;":                            '\U00002273',
+	"gsime;":                           '\U00002A8E',
+	"gsiml;":                           '\U00002A90',
+	"gt;":                              '\U0000003E',
+	"gtcc;":                            '\U00002AA7',
+	"gtcir;":                           '\U00002A7A',
+	"gtdot;":                           '\U000022D7',
+	"gtlPar;":                          '\U00002995',
+	"gtquest;":                         '\U00002A7C',
+	"gtrapprox;":                       '\U00002A86',
+	"gtrarr;":                          '\U00002978',
+	"gtrdot;":                          '\U000022D7',
+	"gtreqless;":                       '\U000022DB',
+	"gtreqqless;":                      '\U00002A8C',
+	"gtrless;":                         '\U00002277',
+	"gtrsim;":                          '\U00002273',
+	"hArr;":                            '\U000021D4',
+	"hairsp;":                          '\U0000200A',
+	"half;":                            '\U000000BD',
+	"hamilt;":                          '\U0000210B',
+	"hardcy;":                          '\U0000044A',
+	"harr;":                            '\U00002194',
+	"harrcir;":                         '\U00002948',
+	"harrw;":                           '\U000021AD',
+	"hbar;":                            '\U0000210F',
+	"hcirc;":                           '\U00000125',
+	"hearts;":                          '\U00002665',
+	"heartsuit;":                       '\U00002665',
+	"hellip;":                          '\U00002026',
+	"hercon;":                          '\U000022B9',
+	"hfr;":                             '\U0001D525',
+	"hksearow;":                        '\U00002925',
+	"hkswarow;":                        '\U00002926',
+	"hoarr;":                           '\U000021FF',
+	"homtht;":                          '\U0000223B',
+	"hookleftarrow;":                   '\U000021A9',
+	"hookrightarrow;":                  '\U000021AA',
+	"hopf;":                            '\U0001D559',
+	"horbar;":                          '\U00002015',
+	"hscr;":                            '\U0001D4BD',
+	"hslash;":                          '\U0000210F',
+	"hstrok;":                          '\U00000127',
+	"hybull;":                          '\U00002043',
+	"hyphen;":                          '\U00002010',
+	"iacute;":                          '\U000000ED',
+	"ic;":                              '\U00002063',
+	"icirc;":                           '\U000000EE',
+	"icy;":                             '\U00000438',
+	"iecy;":                            '\U00000435',
+	"iexcl;":                           '\U000000A1',
+	"iff;":                             '\U000021D4',
+	"ifr;":                             '\U0001D526',
+	"igrave;":                          '\U000000EC',
+	"ii;":                              '\U00002148',
+	"iiiint;":                          '\U00002A0C',
+	"iiint;":                           '\U0000222D',
+	"iinfin;":                          '\U000029DC',
+	"iiota;":                           '\U00002129',
+	"ijlig;":                           '\U00000133',
+	"imacr;":                           '\U0000012B',
+	"image;":                           '\U00002111',
+	"imagline;":                        '\U00002110',
+	"imagpart;":                        '\U00002111',
+	"imath;":                           '\U00000131',
+	"imof;":                            '\U000022B7',
+	"imped;":                           '\U000001B5',
+	"in;":                              '\U00002208',
+	"incare;":                          '\U00002105',
+	"infin;":                           '\U0000221E',
+	"infintie;":                        '\U000029DD',
+	"inodot;":                          '\U00000131',
+	"int;":                             '\U0000222B',
+	"intcal;":                          '\U000022BA',
+	"integers;":                        '\U00002124',
+	"intercal;":                        '\U000022BA',
+	"intlarhk;":                        '\U00002A17',
+	"intprod;":                         '\U00002A3C',
+	"iocy;":                            '\U00000451',
+	"iogon;":                           '\U0000012F',
+	"iopf;":                            '\U0001D55A',
+	"iota;":                            '\U000003B9',
+	"iprod;":                           '\U00002A3C',
+	"iquest;":                          '\U000000BF',
+	"iscr;":                            '\U0001D4BE',
+	"isin;":                            '\U00002208',
+	"isinE;":                           '\U000022F9',
+	"isindot;":                         '\U000022F5',
+	"isins;":                           '\U000022F4',
+	"isinsv;":                          '\U000022F3',
+	"isinv;":                           '\U00002208',
+	"it;":                              '\U00002062',
+	"itilde;":                          '\U00000129',
+	"iukcy;":                           '\U00000456',
+	"iuml;":                            '\U000000EF',
+	"jcirc;":                           '\U00000135',
+	"jcy;":                             '\U00000439',
+	"jfr;":                             '\U0001D527',
+	"jmath;":                           '\U00000237',
+	"jopf;":                            '\U0001D55B',
+	"jscr;":                            '\U0001D4BF',
+	"jsercy;":                          '\U00000458',
+	"jukcy;":                           '\U00000454',
+	"kappa;":                           '\U000003BA',
+	"kappav;":                          '\U000003F0',
+	"kcedil;":                          '\U00000137',
+	"kcy;":                             '\U0000043A',
+	"kfr;":                             '\U0001D528',
+	"kgreen;":                          '\U00000138',
+	"khcy;":                            '\U00000445',
+	"kjcy;":                            '\U0000045C',
+	"kopf;":                            '\U0001D55C',
+	"kscr;":                            '\U0001D4C0',
+	"lAarr;":                           '\U000021DA',
+	"lArr;":                            '\U000021D0',
+	"lAtail;":                          '\U0000291B',
+	"lBarr;":                           '\U0000290E',
+	"lE;":                              '\U00002266',
+	"lEg;":                             '\U00002A8B',
+	"lHar;":                            '\U00002962',
+	"lacute;":                          '\U0000013A',
+	"laemptyv;":                        '\U000029B4',
+	"lagran;":                          '\U00002112',
+	"lambda;":                          '\U000003BB',
+	"lang;":                            '\U000027E8',
+	"langd;":                           '\U00002991',
+	"langle;":                          '\U000027E8',
+	"lap;":                             '\U00002A85',
+	"laquo;":                           '\U000000AB',
+	"larr;":                            '\U00002190',
+	"larrb;":                           '\U000021E4',
+	"larrbfs;":                         '\U0000291F',
+	"larrfs;":                          '\U0000291D',
+	"larrhk;":                          '\U000021A9',
+	"larrlp;":                          '\U000021AB',
+	"larrpl;":                          '\U00002939',
+	"larrsim;":                         '\U00002973',
+	"larrtl;":                          '\U000021A2',
+	"lat;":                             '\U00002AAB',
+	"latail;":                          '\U00002919',
+	"late;":                            '\U00002AAD',
+	"lbarr;":                           '\U0000290C',
+	"lbbrk;":                           '\U00002772',
+	"lbrace;":                          '\U0000007B',
+	"lbrack;":                          '\U0000005B',
+	"lbrke;":                           '\U0000298B',
+	"lbrksld;":                         '\U0000298F',
+	"lbrkslu;":                         '\U0000298D',
+	"lcaron;":                          '\U0000013E',
+	"lcedil;":                          '\U0000013C',
+	"lceil;":                           '\U00002308',
+	"lcub;":                            '\U0000007B',
+	"lcy;":                             '\U0000043B',
+	"ldca;":                            '\U00002936',
+	"ldquo;":                           '\U0000201C',
+	"ldquor;":                          '\U0000201E',
+	"ldrdhar;":                         '\U00002967',
+	"ldrushar;":                        '\U0000294B',
+	"ldsh;":                            '\U000021B2',
+	"le;":                              '\U00002264',
+	"leftarrow;":                       '\U00002190',
+	"leftarrowtail;":                   '\U000021A2',
+	"leftharpoondown;":                 '\U000021BD',
+	"leftharpoonup;":                   '\U000021BC',
+	"leftleftarrows;":                  '\U000021C7',
+	"leftrightarrow;":                  '\U00002194',
+	"leftrightarrows;":                 '\U000021C6',
+	"leftrightharpoons;":               '\U000021CB',
+	"leftrightsquigarrow;":             '\U000021AD',
+	"leftthreetimes;":                  '\U000022CB',
+	"leg;":                             '\U000022DA',
+	"leq;":                             '\U00002264',
+	"leqq;":                            '\U00002266',
+	"leqslant;":                        '\U00002A7D',
+	"les;":                             '\U00002A7D',
+	"lescc;":                           '\U00002AA8',
+	"lesdot;":                          '\U00002A7F',
+	"lesdoto;":                         '\U00002A81',
+	"lesdotor;":                        '\U00002A83',
+	"lesges;":                          '\U00002A93',
+	"lessapprox;":                      '\U00002A85',
+	"lessdot;":                         '\U000022D6',
+	"lesseqgtr;":                       '\U000022DA',
+	"lesseqqgtr;":                      '\U00002A8B',
+	"lessgtr;":                         '\U00002276',
+	"lesssim;":                         '\U00002272',
+	"lfisht;":                          '\U0000297C',
+	"lfloor;":                          '\U0000230A',
+	"lfr;":                             '\U0001D529',
+	"lg;":                              '\U00002276',
+	"lgE;":                             '\U00002A91',
+	"lhard;":                           '\U000021BD',
+	"lharu;":                           '\U000021BC',
+	"lharul;":                          '\U0000296A',
+	"lhblk;":                           '\U00002584',
+	"ljcy;":                            '\U00000459',
+	"ll;":                              '\U0000226A',
+	"llarr;":                           '\U000021C7',
+	"llcorner;":                        '\U0000231E',
+	"llhard;":                          '\U0000296B',
+	"lltri;":                           '\U000025FA',
+	"lmidot;":                          '\U00000140',
+	"lmoust;":                          '\U000023B0',
+	"lmoustache;":                      '\U000023B0',
+	"lnE;":                             '\U00002268',
+	"lnap;":                            '\U00002A89',
+	"lnapprox;":                        '\U00002A89',
+	"lne;":                             '\U00002A87',
+	"lneq;":                            '\U00002A87',
+	"lneqq;":                           '\U00002268',
+	"lnsim;":                           '\U000022E6',
+	"loang;":                           '\U000027EC',
+	"loarr;":                           '\U000021FD',
+	"lobrk;":                           '\U000027E6',
+	"longleftarrow;":                   '\U000027F5',
+	"longleftrightarrow;":              '\U000027F7',
+	"longmapsto;":                      '\U000027FC',
+	"longrightarrow;":                  '\U000027F6',
+	"looparrowleft;":                   '\U000021AB',
+	"looparrowright;":                  '\U000021AC',
+	"lopar;":                           '\U00002985',
+	"lopf;":                            '\U0001D55D',
+	"loplus;":                          '\U00002A2D',
+	"lotimes;":                         '\U00002A34',
+	"lowast;":                          '\U00002217',
+	"lowbar;":                          '\U0000005F',
+	"loz;":                             '\U000025CA',
+	"lozenge;":                         '\U000025CA',
+	"lozf;":                            '\U000029EB',
+	"lpar;":                            '\U00000028',
+	"lparlt;":                          '\U00002993',
+	"lrarr;":                           '\U000021C6',
+	"lrcorner;":                        '\U0000231F',
+	"lrhar;":                           '\U000021CB',
+	"lrhard;":                          '\U0000296D',
+	"lrm;":                             '\U0000200E',
+	"lrtri;":                           '\U000022BF',
+	"lsaquo;":                          '\U00002039',
+	"lscr;":                            '\U0001D4C1',
+	"lsh;":                             '\U000021B0',
+	"lsim;":                            '\U00002272',
+	"lsime;":                           '\U00002A8D',
+	"lsimg;":                           '\U00002A8F',
+	"lsqb;":                            '\U0000005B',
+	"lsquo;":                           '\U00002018',
+	"lsquor;":                          '\U0000201A',
+	"lstrok;":                          '\U00000142',
+	"lt;":                              '\U0000003C',
+	"ltcc;":                            '\U00002AA6',
+	"ltcir;":                           '\U00002A79',
+	"ltdot;":                           '\U000022D6',
+	"lthree;":                          '\U000022CB',
+	"ltimes;":                          '\U000022C9',
+	"ltlarr;":                          '\U00002976',
+	"ltquest;":                         '\U00002A7B',
+	"ltrPar;":                          '\U00002996',
+	"ltri;":                            '\U000025C3',
+	"ltrie;":                           '\U000022B4',
+	"ltrif;":                           '\U000025C2',
+	"lurdshar;":                        '\U0000294A',
+	"luruhar;":                         '\U00002966',
+	"mDDot;":                           '\U0000223A',
+	"macr;":                            '\U000000AF',
+	"male;":                            '\U00002642',
+	"malt;":                            '\U00002720',
+	"maltese;":                         '\U00002720',
+	"map;":                             '\U000021A6',
+	"mapsto;":                          '\U000021A6',
+	"mapstodown;":                      '\U000021A7',
+	"mapstoleft;":                      '\U000021A4',
+	"mapstoup;":                        '\U000021A5',
+	"marker;":                          '\U000025AE',
+	"mcomma;":                          '\U00002A29',
+	"mcy;":                             '\U0000043C',
+	"mdash;":                           '\U00002014',
+	"measuredangle;":                   '\U00002221',
+	"mfr;":                             '\U0001D52A',
+	"mho;":                             '\U00002127',
+	"micro;":                           '\U000000B5',
+	"mid;":                             '\U00002223',
+	"midast;":                          '\U0000002A',
+	"midcir;":                          '\U00002AF0',
+	"middot;":                          '\U000000B7',
+	"minus;":                           '\U00002212',
+	"minusb;":                          '\U0000229F',
+	"minusd;":                          '\U00002238',
+	"minusdu;":                         '\U00002A2A',
+	"mlcp;":                            '\U00002ADB',
+	"mldr;":                            '\U00002026',
+	"mnplus;":                          '\U00002213',
+	"models;":                          '\U000022A7',
+	"mopf;":                            '\U0001D55E',
+	"mp;":                              '\U00002213',
+	"mscr;":                            '\U0001D4C2',
+	"mstpos;":                          '\U0000223E',
+	"mu;":                              '\U000003BC',
+	"multimap;":                        '\U000022B8',
+	"mumap;":                           '\U000022B8',
+	"nLeftarrow;":                      '\U000021CD',
+	"nLeftrightarrow;":                 '\U000021CE',
+	"nRightarrow;":                     '\U000021CF',
+	"nVDash;":                          '\U000022AF',
+	"nVdash;":                          '\U000022AE',
+	"nabla;":                           '\U00002207',
+	"nacute;":                          '\U00000144',
+	"nap;":                             '\U00002249',
+	"napos;":                           '\U00000149',
+	"napprox;":                         '\U00002249',
+	"natur;":                           '\U0000266E',
+	"natural;":                         '\U0000266E',
+	"naturals;":                        '\U00002115',
+	"nbsp;":                            '\U000000A0',
+	"ncap;":                            '\U00002A43',
+	"ncaron;":                          '\U00000148',
+	"ncedil;":                          '\U00000146',
+	"ncong;":                           '\U00002247',
+	"ncup;":                            '\U00002A42',
+	"ncy;":                             '\U0000043D',
+	"ndash;":                           '\U00002013',
+	"ne;":                              '\U00002260',
+	"neArr;":                           '\U000021D7',
+	"nearhk;":                          '\U00002924',
+	"nearr;":                           '\U00002197',
+	"nearrow;":                         '\U00002197',
+	"nequiv;":                          '\U00002262',
+	"nesear;":                          '\U00002928',
+	"nexist;":                          '\U00002204',
+	"nexists;":                         '\U00002204',
+	"nfr;":                             '\U0001D52B',
+	"nge;":                             '\U00002271',
+	"ngeq;":                            '\U00002271',
+	"ngsim;":                           '\U00002275',
+	"ngt;":                             '\U0000226F',
+	"ngtr;":                            '\U0000226F',
+	"nhArr;":                           '\U000021CE',
+	"nharr;":                           '\U000021AE',
+	"nhpar;":                           '\U00002AF2',
+	"ni;":                              '\U0000220B',
+	"nis;":                             '\U000022FC',
+	"nisd;":                            '\U000022FA',
+	"niv;":                             '\U0000220B',
+	"njcy;":                            '\U0000045A',
+	"nlArr;":                           '\U000021CD',
+	"nlarr;":                           '\U0000219A',
+	"nldr;":                            '\U00002025',
+	"nle;":                             '\U00002270',
+	"nleftarrow;":                      '\U0000219A',
+	"nleftrightarrow;":                 '\U000021AE',
+	"nleq;":                            '\U00002270',
+	"nless;":                           '\U0000226E',
+	"nlsim;":                           '\U00002274',
+	"nlt;":                             '\U0000226E',
+	"nltri;":                           '\U000022EA',
+	"nltrie;":                          '\U000022EC',
+	"nmid;":                            '\U00002224',
+	"nopf;":                            '\U0001D55F',
+	"not;":                             '\U000000AC',
+	"notin;":                           '\U00002209',
+	"notinva;":                         '\U00002209',
+	"notinvb;":                         '\U000022F7',
+	"notinvc;":                         '\U000022F6',
+	"notni;":                           '\U0000220C',
+	"notniva;":                         '\U0000220C',
+	"notnivb;":                         '\U000022FE',
+	"notnivc;":                         '\U000022FD',
+	"npar;":                            '\U00002226',
+	"nparallel;":                       '\U00002226',
+	"npolint;":                         '\U00002A14',
+	"npr;":                             '\U00002280',
+	"nprcue;":                          '\U000022E0',
+	"nprec;":                           '\U00002280',
+	"nrArr;":                           '\U000021CF',
+	"nrarr;":                           '\U0000219B',
+	"nrightarrow;":                     '\U0000219B',
+	"nrtri;":                           '\U000022EB',
+	"nrtrie;":                          '\U000022ED',
+	"nsc;":                             '\U00002281',
+	"nsccue;":                          '\U000022E1',
+	"nscr;":                            '\U0001D4C3',
+	"nshortmid;":                       '\U00002224',
+	"nshortparallel;":                  '\U00002226',
+	"nsim;":                            '\U00002241',
+	"nsime;":                           '\U00002244',
+	"nsimeq;":                          '\U00002244',
+	"nsmid;":                           '\U00002224',
+	"nspar;":                           '\U00002226',
+	"nsqsube;":                         '\U000022E2',
+	"nsqsupe;":                         '\U000022E3',
+	"nsub;":                            '\U00002284',
+	"nsube;":                           '\U00002288',
+	"nsubseteq;":                       '\U00002288',
+	"nsucc;":                           '\U00002281',
+	"nsup;":                            '\U00002285',
+	"nsupe;":                           '\U00002289',
+	"nsupseteq;":                       '\U00002289',
+	"ntgl;":                            '\U00002279',
+	"ntilde;":                          '\U000000F1',
+	"ntlg;":                            '\U00002278',
+	"ntriangleleft;":                   '\U000022EA',
+	"ntrianglelefteq;":                 '\U000022EC',
+	"ntriangleright;":                  '\U000022EB',
+	"ntrianglerighteq;":                '\U000022ED',
+	"nu;":                              '\U000003BD',
+	"num;":                             '\U00000023',
+	"numero;":                          '\U00002116',
+	"numsp;":                           '\U00002007',
+	"nvDash;":                          '\U000022AD',
+	"nvHarr;":                          '\U00002904',
+	"nvdash;":                          '\U000022AC',
+	"nvinfin;":                         '\U000029DE',
+	"nvlArr;":                          '\U00002902',
+	"nvrArr;":                          '\U00002903',
+	"nwArr;":                           '\U000021D6',
+	"nwarhk;":                          '\U00002923',
+	"nwarr;":                           '\U00002196',
+	"nwarrow;":                         '\U00002196',
+	"nwnear;":                          '\U00002927',
+	"oS;":                              '\U000024C8',
+	"oacute;":                          '\U000000F3',
+	"oast;":                            '\U0000229B',
+	"ocir;":                            '\U0000229A',
+	"ocirc;":                           '\U000000F4',
+	"ocy;":                             '\U0000043E',
+	"odash;":                           '\U0000229D',
+	"odblac;":                          '\U00000151',
+	"odiv;":                            '\U00002A38',
+	"odot;":                            '\U00002299',
+	"odsold;":                          '\U000029BC',
+	"oelig;":                           '\U00000153',
+	"ofcir;":                           '\U000029BF',
+	"ofr;":                             '\U0001D52C',
+	"ogon;":                            '\U000002DB',
+	"ograve;":                          '\U000000F2',
+	"ogt;":                             '\U000029C1',
+	"ohbar;":                           '\U000029B5',
+	"ohm;":                             '\U000003A9',
+	"oint;":                            '\U0000222E',
+	"olarr;":                           '\U000021BA',
+	"olcir;":                           '\U000029BE',
+	"olcross;":                         '\U000029BB',
+	"oline;":                           '\U0000203E',
+	"olt;":                             '\U000029C0',
+	"omacr;":                           '\U0000014D',
+	"omega;":                           '\U000003C9',
+	"omicron;":                         '\U000003BF',
+	"omid;":                            '\U000029B6',
+	"ominus;":                          '\U00002296',
+	"oopf;":                            '\U0001D560',
+	"opar;":                            '\U000029B7',
+	"operp;":                           '\U000029B9',
+	"oplus;":                           '\U00002295',
+	"or;":                              '\U00002228',
+	"orarr;":                           '\U000021BB',
+	"ord;":                             '\U00002A5D',
+	"order;":                           '\U00002134',
+	"orderof;":                         '\U00002134',
+	"ordf;":                            '\U000000AA',
+	"ordm;":                            '\U000000BA',
+	"origof;":                          '\U000022B6',
+	"oror;":                            '\U00002A56',
+	"orslope;":                         '\U00002A57',
+	"orv;":                             '\U00002A5B',
+	"oscr;":                            '\U00002134',
+	"oslash;":                          '\U000000F8',
+	"osol;":                            '\U00002298',
+	"otilde;":                          '\U000000F5',
+	"otimes;":                          '\U00002297',
+	"otimesas;":                        '\U00002A36',
+	"ouml;":                            '\U000000F6',
+	"ovbar;":                           '\U0000233D',
+	"par;":                             '\U00002225',
+	"para;":                            '\U000000B6',
+	"parallel;":                        '\U00002225',
+	"parsim;":                          '\U00002AF3',
+	"parsl;":                           '\U00002AFD',
+	"part;":                            '\U00002202',
+	"pcy;":                             '\U0000043F',
+	"percnt;":                          '\U00000025',
+	"period;":                          '\U0000002E',
+	"permil;":                          '\U00002030',
+	"perp;":                            '\U000022A5',
+	"pertenk;":                         '\U00002031',
+	"pfr;":                             '\U0001D52D',
+	"phi;":                             '\U000003C6',
+	"phiv;":                            '\U000003D5',
+	"phmmat;":                          '\U00002133',
+	"phone;":                           '\U0000260E',
+	"pi;":                              '\U000003C0',
+	"pitchfork;":                       '\U000022D4',
+	"piv;":                             '\U000003D6',
+	"planck;":                          '\U0000210F',
+	"planckh;":                         '\U0000210E',
+	"plankv;":                          '\U0000210F',
+	"plus;":                            '\U0000002B',
+	"plusacir;":                        '\U00002A23',
+	"plusb;":                           '\U0000229E',
+	"pluscir;":                         '\U00002A22',
+	"plusdo;":                          '\U00002214',
+	"plusdu;":                          '\U00002A25',
+	"pluse;":                           '\U00002A72',
+	"plusmn;":                          '\U000000B1',
+	"plussim;":                         '\U00002A26',
+	"plustwo;":                         '\U00002A27',
+	"pm;":                              '\U000000B1',
+	"pointint;":                        '\U00002A15',
+	"popf;":                            '\U0001D561',
+	"pound;":                           '\U000000A3',
+	"pr;":                              '\U0000227A',
+	"prE;":                             '\U00002AB3',
+	"prap;":                            '\U00002AB7',
+	"prcue;":                           '\U0000227C',
+	"pre;":                             '\U00002AAF',
+	"prec;":                            '\U0000227A',
+	"precapprox;":                      '\U00002AB7',
+	"preccurlyeq;":                     '\U0000227C',
+	"preceq;":                          '\U00002AAF',
+	"precnapprox;":                     '\U00002AB9',
+	"precneqq;":                        '\U00002AB5',
+	"precnsim;":                        '\U000022E8',
+	"precsim;":                         '\U0000227E',
+	"prime;":                           '\U00002032',
+	"primes;":                          '\U00002119',
+	"prnE;":                            '\U00002AB5',
+	"prnap;":                           '\U00002AB9',
+	"prnsim;":                          '\U000022E8',
+	"prod;":                            '\U0000220F',
+	"profalar;":                        '\U0000232E',
+	"profline;":                        '\U00002312',
+	"profsurf;":                        '\U00002313',
+	"prop;":                            '\U0000221D',
+	"propto;":                          '\U0000221D',
+	"prsim;":                           '\U0000227E',
+	"prurel;":                          '\U000022B0',
+	"pscr;":                            '\U0001D4C5',
+	"psi;":                             '\U000003C8',
+	"puncsp;":                          '\U00002008',
+	"qfr;":                             '\U0001D52E',
+	"qint;":                            '\U00002A0C',
+	"qopf;":                            '\U0001D562',
+	"qprime;":                          '\U00002057',
+	"qscr;":                            '\U0001D4C6',
+	"quaternions;":                     '\U0000210D',
+	"quatint;":                         '\U00002A16',
+	"quest;":                           '\U0000003F',
+	"questeq;":                         '\U0000225F',
+	"quot;":                            '\U00000022',
+	"rAarr;":                           '\U000021DB',
+	"rArr;":                            '\U000021D2',
+	"rAtail;":                          '\U0000291C',
+	"rBarr;":                           '\U0000290F',
+	"rHar;":                            '\U00002964',
+	"racute;":                          '\U00000155',
+	"radic;":                           '\U0000221A',
+	"raemptyv;":                        '\U000029B3',
+	"rang;":                            '\U000027E9',
+	"rangd;":                           '\U00002992',
+	"range;":                           '\U000029A5',
+	"rangle;":                          '\U000027E9',
+	"raquo;":                           '\U000000BB',
+	"rarr;":                            '\U00002192',
+	"rarrap;":                          '\U00002975',
+	"rarrb;":                           '\U000021E5',
+	"rarrbfs;":                         '\U00002920',
+	"rarrc;":                           '\U00002933',
+	"rarrfs;":                          '\U0000291E',
+	"rarrhk;":                          '\U000021AA',
+	"rarrlp;":                          '\U000021AC',
+	"rarrpl;":                          '\U00002945',
+	"rarrsim;":                         '\U00002974',
+	"rarrtl;":                          '\U000021A3',
+	"rarrw;":                           '\U0000219D',
+	"ratail;":                          '\U0000291A',
+	"ratio;":                           '\U00002236',
+	"rationals;":                       '\U0000211A',
+	"rbarr;":                           '\U0000290D',
+	"rbbrk;":                           '\U00002773',
+	"rbrace;":                          '\U0000007D',
+	"rbrack;":                          '\U0000005D',
+	"rbrke;":                           '\U0000298C',
+	"rbrksld;":                         '\U0000298E',
+	"rbrkslu;":                         '\U00002990',
+	"rcaron;":                          '\U00000159',
+	"rcedil;":                          '\U00000157',
+	"rceil;":                           '\U00002309',
+	"rcub;":                            '\U0000007D',
+	"rcy;":                             '\U00000440',
+	"rdca;":                            '\U00002937',
+	"rdldhar;":                         '\U00002969',
+	"rdquo;":                           '\U0000201D',
+	"rdquor;":                          '\U0000201D',
+	"rdsh;":                            '\U000021B3',
+	"real;":                            '\U0000211C',
+	"realine;":                         '\U0000211B',
+	"realpart;":                        '\U0000211C',
+	"reals;":                           '\U0000211D',
+	"rect;":                            '\U000025AD',
+	"reg;":                             '\U000000AE',
+	"rfisht;":                          '\U0000297D',
+	"rfloor;":                          '\U0000230B',
+	"rfr;":                             '\U0001D52F',
+	"rhard;":                           '\U000021C1',
+	"rharu;":                           '\U000021C0',
+	"rharul;":                          '\U0000296C',
+	"rho;":                             '\U000003C1',
+	"rhov;":                            '\U000003F1',
+	"rightarrow;":                      '\U00002192',
+	"rightarrowtail;":                  '\U000021A3',
+	"rightharpoondown;":                '\U000021C1',
+	"rightharpoonup;":                  '\U000021C0',
+	"rightleftarrows;":                 '\U000021C4',
+	"rightleftharpoons;":               '\U000021CC',
+	"rightrightarrows;":                '\U000021C9',
+	"rightsquigarrow;":                 '\U0000219D',
+	"rightthreetimes;":                 '\U000022CC',
+	"ring;":                            '\U000002DA',
+	"risingdotseq;":                    '\U00002253',
+	"rlarr;":                           '\U000021C4',
+	"rlhar;":                           '\U000021CC',
+	"rlm;":                             '\U0000200F',
+	"rmoust;":                          '\U000023B1',
+	"rmoustache;":                      '\U000023B1',
+	"rnmid;":                           '\U00002AEE',
+	"roang;":                           '\U000027ED',
+	"roarr;":                           '\U000021FE',
+	"robrk;":                           '\U000027E7',
+	"ropar;":                           '\U00002986',
+	"ropf;":                            '\U0001D563',
+	"roplus;":                          '\U00002A2E',
+	"rotimes;":                         '\U00002A35',
+	"rpar;":                            '\U00000029',
+	"rpargt;":                          '\U00002994',
+	"rppolint;":                        '\U00002A12',
+	"rrarr;":                           '\U000021C9',
+	"rsaquo;":                          '\U0000203A',
+	"rscr;":                            '\U0001D4C7',
+	"rsh;":                             '\U000021B1',
+	"rsqb;":                            '\U0000005D',
+	"rsquo;":                           '\U00002019',
+	"rsquor;":                          '\U00002019',
+	"rthree;":                          '\U000022CC',
+	"rtimes;":                          '\U000022CA',
+	"rtri;":                            '\U000025B9',
+	"rtrie;":                           '\U000022B5',
+	"rtrif;":                           '\U000025B8',
+	"rtriltri;":                        '\U000029CE',
+	"ruluhar;":                         '\U00002968',
+	"rx;":                              '\U0000211E',
+	"sacute;":                          '\U0000015B',
+	"sbquo;":                           '\U0000201A',
+	"sc;":                              '\U0000227B',
+	"scE;":                             '\U00002AB4',
+	"scap;":                            '\U00002AB8',
+	"scaron;":                          '\U00000161',
+	"sccue;":                           '\U0000227D',
+	"sce;":                             '\U00002AB0',
+	"scedil;":                          '\U0000015F',
+	"scirc;":                           '\U0000015D',
+	"scnE;":                            '\U00002AB6',
+	"scnap;":                           '\U00002ABA',
+	"scnsim;":                          '\U000022E9',
+	"scpolint;":                        '\U00002A13',
+	"scsim;":                           '\U0000227F',
+	"scy;":                             '\U00000441',
+	"sdot;":                            '\U000022C5',
+	"sdotb;":                           '\U000022A1',
+	"sdote;":                           '\U00002A66',
+	"seArr;":                           '\U000021D8',
+	"searhk;":                          '\U00002925',
+	"searr;":                           '\U00002198',
+	"searrow;":                         '\U00002198',
+	"sect;":                            '\U000000A7',
+	"semi;":                            '\U0000003B',
+	"seswar;":                          '\U00002929',
+	"setminus;":                        '\U00002216',
+	"setmn;":                           '\U00002216',
+	"sext;":                            '\U00002736',
+	"sfr;":                             '\U0001D530',
+	"sfrown;":                          '\U00002322',
+	"sharp;":                           '\U0000266F',
+	"shchcy;":                          '\U00000449',
+	"shcy;":                            '\U00000448',
+	"shortmid;":                        '\U00002223',
+	"shortparallel;":                   '\U00002225',
+	"shy;":                             '\U000000AD',
+	"sigma;":                           '\U000003C3',
+	"sigmaf;":                          '\U000003C2',
+	"sigmav;":                          '\U000003C2',
+	"sim;":                             '\U0000223C',
+	"simdot;":                          '\U00002A6A',
+	"sime;":                            '\U00002243',
+	"simeq;":                           '\U00002243',
+	"simg;":                            '\U00002A9E',
+	"simgE;":                           '\U00002AA0',
+	"siml;":                            '\U00002A9D',
+	"simlE;":                           '\U00002A9F',
+	"simne;":                           '\U00002246',
+	"simplus;":                         '\U00002A24',
+	"simrarr;":                         '\U00002972',
+	"slarr;":                           '\U00002190',
+	"smallsetminus;":                   '\U00002216',
+	"smashp;":                          '\U00002A33',
+	"smeparsl;":                        '\U000029E4',
+	"smid;":                            '\U00002223',
+	"smile;":                           '\U00002323',
+	"smt;":                             '\U00002AAA',
+	"smte;":                            '\U00002AAC',
+	"softcy;":                          '\U0000044C',
+	"sol;":                             '\U0000002F',
+	"solb;":                            '\U000029C4',
+	"solbar;":                          '\U0000233F',
+	"sopf;":                            '\U0001D564',
+	"spades;":                          '\U00002660',
+	"spadesuit;":                       '\U00002660',
+	"spar;":                            '\U00002225',
+	"sqcap;":                           '\U00002293',
+	"sqcup;":                           '\U00002294',
+	"sqsub;":                           '\U0000228F',
+	"sqsube;":                          '\U00002291',
+	"sqsubset;":                        '\U0000228F',
+	"sqsubseteq;":                      '\U00002291',
+	"sqsup;":                           '\U00002290',
+	"sqsupe;":                          '\U00002292',
+	"sqsupset;":                        '\U00002290',
+	"sqsupseteq;":                      '\U00002292',
+	"squ;":                             '\U000025A1',
+	"square;":                          '\U000025A1',
+	"squarf;":                          '\U000025AA',
+	"squf;":                            '\U000025AA',
+	"srarr;":                           '\U00002192',
+	"sscr;":                            '\U0001D4C8',
+	"ssetmn;":                          '\U00002216',
+	"ssmile;":                          '\U00002323',
+	"sstarf;":                          '\U000022C6',
+	"star;":                            '\U00002606',
+	"starf;":                           '\U00002605',
+	"straightepsilon;":                 '\U000003F5',
+	"straightphi;":                     '\U000003D5',
+	"strns;":                           '\U000000AF',
+	"sub;":                             '\U00002282',
+	"subE;":                            '\U00002AC5',
+	"subdot;":                          '\U00002ABD',
+	"sube;":                            '\U00002286',
+	"subedot;":                         '\U00002AC3',
+	"submult;":                         '\U00002AC1',
+	"subnE;":                           '\U00002ACB',
+	"subne;":                           '\U0000228A',
+	"subplus;":                         '\U00002ABF',
+	"subrarr;":                         '\U00002979',
+	"subset;":                          '\U00002282',
+	"subseteq;":                        '\U00002286',
+	"subseteqq;":                       '\U00002AC5',
+	"subsetneq;":                       '\U0000228A',
+	"subsetneqq;":                      '\U00002ACB',
+	"subsim;":                          '\U00002AC7',
+	"subsub;":                          '\U00002AD5',
+	"subsup;":                          '\U00002AD3',
+	"succ;":                            '\U0000227B',
+	"succapprox;":                      '\U00002AB8',
+	"succcurlyeq;":                     '\U0000227D',
+	"succeq;":                          '\U00002AB0',
+	"succnapprox;":                     '\U00002ABA',
+	"succneqq;":                        '\U00002AB6',
+	"succnsim;":                        '\U000022E9',
+	"succsim;":                         '\U0000227F',
+	"sum;":                             '\U00002211',
+	"sung;":                            '\U0000266A',
+	"sup;":                             '\U00002283',
+	"sup1;":                            '\U000000B9',
+	"sup2;":                            '\U000000B2',
+	"sup3;":                            '\U000000B3',
+	"supE;":                            '\U00002AC6',
+	"supdot;":                          '\U00002ABE',
+	"supdsub;":                         '\U00002AD8',
+	"supe;":                            '\U00002287',
+	"supedot;":                         '\U00002AC4',
+	"suphsol;":                         '\U000027C9',
+	"suphsub;":                         '\U00002AD7',
+	"suplarr;":                         '\U0000297B',
+	"supmult;":                         '\U00002AC2',
+	"supnE;":                           '\U00002ACC',
+	"supne;":                           '\U0000228B',
+	"supplus;":                         '\U00002AC0',
+	"supset;":                          '\U00002283',
+	"supseteq;":                        '\U00002287',
+	"supseteqq;":                       '\U00002AC6',
+	"supsetneq;":                       '\U0000228B',
+	"supsetneqq;":                      '\U00002ACC',
+	"supsim;":                          '\U00002AC8',
+	"supsub;":                          '\U00002AD4',
+	"supsup;":                          '\U00002AD6',
+	"swArr;":                           '\U000021D9',
+	"swarhk;":                          '\U00002926',
+	"swarr;":                           '\U00002199',
+	"swarrow;":                         '\U00002199',
+	"swnwar;":                          '\U0000292A',
+	"szlig;":                           '\U000000DF',
+	"target;":                          '\U00002316',
+	"tau;":                             '\U000003C4',
+	"tbrk;":                            '\U000023B4',
+	"tcaron;":                          '\U00000165',
+	"tcedil;":                          '\U00000163',
+	"tcy;":                             '\U00000442',
+	"tdot;":                            '\U000020DB',
+	"telrec;":                          '\U00002315',
+	"tfr;":                             '\U0001D531',
+	"there4;":                          '\U00002234',
+	"therefore;":                       '\U00002234',
+	"theta;":                           '\U000003B8',
+	"thetasym;":                        '\U000003D1',
+	"thetav;":                          '\U000003D1',
+	"thickapprox;":                     '\U00002248',
+	"thicksim;":                        '\U0000223C',
+	"thinsp;":                          '\U00002009',
+	"thkap;":                           '\U00002248',
+	"thksim;":                          '\U0000223C',
+	"thorn;":                           '\U000000FE',
+	"tilde;":                           '\U000002DC',
+	"times;":                           '\U000000D7',
+	"timesb;":                          '\U000022A0',
+	"timesbar;":                        '\U00002A31',
+	"timesd;":                          '\U00002A30',
+	"tint;":                            '\U0000222D',
+	"toea;":                            '\U00002928',
+	"top;":                             '\U000022A4',
+	"topbot;":                          '\U00002336',
+	"topcir;":                          '\U00002AF1',
+	"topf;":                            '\U0001D565',
+	"topfork;":                         '\U00002ADA',
+	"tosa;":                            '\U00002929',
+	"tprime;":                          '\U00002034',
+	"trade;":                           '\U00002122',
+	"triangle;":                        '\U000025B5',
+	"triangledown;":                    '\U000025BF',
+	"triangleleft;":                    '\U000025C3',
+	"trianglelefteq;":                  '\U000022B4',
+	"triangleq;":                       '\U0000225C',
+	"triangleright;":                   '\U000025B9',
+	"trianglerighteq;":                 '\U000022B5',
+	"tridot;":                          '\U000025EC',
+	"trie;":                            '\U0000225C',
+	"triminus;":                        '\U00002A3A',
+	"triplus;":                         '\U00002A39',
+	"trisb;":                           '\U000029CD',
+	"tritime;":                         '\U00002A3B',
+	"trpezium;":                        '\U000023E2',
+	"tscr;":                            '\U0001D4C9',
+	"tscy;":                            '\U00000446',
+	"tshcy;":                           '\U0000045B',
+	"tstrok;":                          '\U00000167',
+	"twixt;":                           '\U0000226C',
+	"twoheadleftarrow;":                '\U0000219E',
+	"twoheadrightarrow;":               '\U000021A0',
+	"uArr;":                            '\U000021D1',
+	"uHar;":                            '\U00002963',
+	"uacute;":                          '\U000000FA',
+	"uarr;":                            '\U00002191',
+	"ubrcy;":                           '\U0000045E',
+	"ubreve;":                          '\U0000016D',
+	"ucirc;":                           '\U000000FB',
+	"ucy;":                             '\U00000443',
+	"udarr;":                           '\U000021C5',
+	"udblac;":                          '\U00000171',
+	"udhar;":                           '\U0000296E',
+	"ufisht;":                          '\U0000297E',
+	"ufr;":                             '\U0001D532',
+	"ugrave;":                          '\U000000F9',
+	"uharl;":                           '\U000021BF',
+	"uharr;":                           '\U000021BE',
+	"uhblk;":                           '\U00002580',
+	"ulcorn;":                          '\U0000231C',
+	"ulcorner;":                        '\U0000231C',
+	"ulcrop;":                          '\U0000230F',
+	"ultri;":                           '\U000025F8',
+	"umacr;":                           '\U0000016B',
+	"uml;":                             '\U000000A8',
+	"uogon;":                           '\U00000173',
+	"uopf;":                            '\U0001D566',
+	"uparrow;":                         '\U00002191',
+	"updownarrow;":                     '\U00002195',
+	"upharpoonleft;":                   '\U000021BF',
+	"upharpoonright;":                  '\U000021BE',
+	"uplus;":                           '\U0000228E',
+	"upsi;":                            '\U000003C5',
+	"upsih;":                           '\U000003D2',
+	"upsilon;":                         '\U000003C5',
+	"upuparrows;":                      '\U000021C8',
+	"urcorn;":                          '\U0000231D',
+	"urcorner;":                        '\U0000231D',
+	"urcrop;":                          '\U0000230E',
+	"uring;":                           '\U0000016F',
+	"urtri;":                           '\U000025F9',
+	"uscr;":                            '\U0001D4CA',
+	"utdot;":                           '\U000022F0',
+	"utilde;":                          '\U00000169',
+	"utri;":                            '\U000025B5',
+	"utrif;":                           '\U000025B4',
+	"uuarr;":                           '\U000021C8',
+	"uuml;":                            '\U000000FC',
+	"uwangle;":                         '\U000029A7',
+	"vArr;":                            '\U000021D5',
+	"vBar;":                            '\U00002AE8',
+	"vBarv;":                           '\U00002AE9',
+	"vDash;":                           '\U000022A8',
+	"vangrt;":                          '\U0000299C',
+	"varepsilon;":                      '\U000003F5',
+	"varkappa;":                        '\U000003F0',
+	"varnothing;":                      '\U00002205',
+	"varphi;":                          '\U000003D5',
+	"varpi;":                           '\U000003D6',
+	"varpropto;":                       '\U0000221D',
+	"varr;":                            '\U00002195',
+	"varrho;":                          '\U000003F1',
+	"varsigma;":                        '\U000003C2',
+	"vartheta;":                        '\U000003D1',
+	"vartriangleleft;":                 '\U000022B2',
+	"vartriangleright;":                '\U000022B3',
+	"vcy;":                             '\U00000432',
+	"vdash;":                           '\U000022A2',
+	"vee;":                             '\U00002228',
+	"veebar;":                          '\U000022BB',
+	"veeeq;":                           '\U0000225A',
+	"vellip;":                          '\U000022EE',
+	"verbar;":                          '\U0000007C',
+	"vert;":                            '\U0000007C',
+	"vfr;":                             '\U0001D533',
+	"vltri;":                           '\U000022B2',
+	"vopf;":                            '\U0001D567',
+	"vprop;":                           '\U0000221D',
+	"vrtri;":                           '\U000022B3',
+	"vscr;":                            '\U0001D4CB',
+	"vzigzag;":                         '\U0000299A',
+	"wcirc;":                           '\U00000175',
+	"wedbar;":                          '\U00002A5F',
+	"wedge;":                           '\U00002227',
+	"wedgeq;":                          '\U00002259',
+	"weierp;":                          '\U00002118',
+	"wfr;":                             '\U0001D534',
+	"wopf;":                            '\U0001D568',
+	"wp;":                              '\U00002118',
+	"wr;":                              '\U00002240',
+	"wreath;":                          '\U00002240',
+	"wscr;":                            '\U0001D4CC',
+	"xcap;":                            '\U000022C2',
+	"xcirc;":                           '\U000025EF',
+	"xcup;":                            '\U000022C3',
+	"xdtri;":                           '\U000025BD',
+	"xfr;":                             '\U0001D535',
+	"xhArr;":                           '\U000027FA',
+	"xharr;":                           '\U000027F7',
+	"xi;":                              '\U000003BE',
+	"xlArr;":                           '\U000027F8',
+	"xlarr;":                           '\U000027F5',
+	"xmap;":                            '\U000027FC',
+	"xnis;":                            '\U000022FB',
+	"xodot;":                           '\U00002A00',
+	"xopf;":                            '\U0001D569',
+	"xoplus;":                          '\U00002A01',
+	"xotime;":                          '\U00002A02',
+	"xrArr;":                           '\U000027F9',
+	"xrarr;":                           '\U000027F6',
+	"xscr;":                            '\U0001D4CD',
+	"xsqcup;":                          '\U00002A06',
+	"xuplus;":                          '\U00002A04',
+	"xutri;":                           '\U000025B3',
+	"xvee;":                            '\U000022C1',
+	"xwedge;":                          '\U000022C0',
+	"yacute;":                          '\U000000FD',
+	"yacy;":                            '\U0000044F',
+	"ycirc;":                           '\U00000177',
+	"ycy;":                             '\U0000044B',
+	"yen;":                             '\U000000A5',
+	"yfr;":                             '\U0001D536',
+	"yicy;":                            '\U00000457',
+	"yopf;":                            '\U0001D56A',
+	"yscr;":                            '\U0001D4CE',
+	"yucy;":                            '\U0000044E',
+	"yuml;":                            '\U000000FF',
+	"zacute;":                          '\U0000017A',
+	"zcaron;":                          '\U0000017E',
+	"zcy;":                             '\U00000437',
+	"zdot;":                            '\U0000017C',
+	"zeetrf;":                          '\U00002128',
+	"zeta;":                            '\U000003B6',
+	"zfr;":                             '\U0001D537',
+	"zhcy;":                            '\U00000436',
+	"zigrarr;":                         '\U000021DD',
+	"zopf;":                            '\U0001D56B',
+	"zscr;":                            '\U0001D4CF',
+	"zwj;":                             '\U0000200D',
+	"zwnj;":                            '\U0000200C',
+	"AElig":                            '\U000000C6',
+	"AMP":                              '\U00000026',
+	"Aacute":                           '\U000000C1',
+	"Acirc":                            '\U000000C2',
+	"Agrave":                           '\U000000C0',
+	"Aring":                            '\U000000C5',
+	"Atilde":                           '\U000000C3',
+	"Auml":                             '\U000000C4',
+	"COPY":                             '\U000000A9',
+	"Ccedil":                           '\U000000C7',
+	"ETH":                              '\U000000D0',
+	"Eacute":                           '\U000000C9',
+	"Ecirc":                            '\U000000CA',
+	"Egrave":                           '\U000000C8',
+	"Euml":                             '\U000000CB',
+	"GT":                               '\U0000003E',
+	"Iacute":                           '\U000000CD',
+	"Icirc":                            '\U000000CE',
+	"Igrave":                           '\U000000CC',
+	"Iuml":                             '\U000000CF',
+	"LT":                               '\U0000003C',
+	"Ntilde":                           '\U000000D1',
+	"Oacute":                           '\U000000D3',
+	"Ocirc":                            '\U000000D4',
+	"Ograve":                           '\U000000D2',
+	"Oslash":                           '\U000000D8',
+	"Otilde":                           '\U000000D5',
+	"Ouml":                             '\U000000D6',
+	"QUOT":                             '\U00000022',
+	"REG":                              '\U000000AE',
+	"THORN":                            '\U000000DE',
+	"Uacute":                           '\U000000DA',
+	"Ucirc":                            '\U000000DB',
+	"Ugrave":                           '\U000000D9',
+	"Uuml":                             '\U000000DC',
+	"Yacute":                           '\U000000DD',
+	"aacute":                           '\U000000E1',
+	"acirc":                            '\U000000E2',
+	"acute":                            '\U000000B4',
+	"aelig":                            '\U000000E6',
+	"agrave":                           '\U000000E0',
+	"amp":                              '\U00000026',
+	"aring":                            '\U000000E5',
+	"atilde":                           '\U000000E3',
+	"auml":                             '\U000000E4',
+	"brvbar":                           '\U000000A6',
+	"ccedil":                           '\U000000E7',
+	"cedil":                            '\U000000B8',
+	"cent":                             '\U000000A2',
+	"copy":                             '\U000000A9',
+	"curren":                           '\U000000A4',
+	"deg":                              '\U000000B0',
+	"divide":                           '\U000000F7',
+	"eacute":                           '\U000000E9',
+	"ecirc":                            '\U000000EA',
+	"egrave":                           '\U000000E8',
+	"eth":                              '\U000000F0',
+	"euml":                             '\U000000EB',
+	"frac12":                           '\U000000BD',
+	"frac14":                           '\U000000BC',
+	"frac34":                           '\U000000BE',
+	"gt":                               '\U0000003E',
+	"iacute":                           '\U000000ED',
+	"icirc":                            '\U000000EE',
+	"iexcl":                            '\U000000A1',
+	"igrave":                           '\U000000EC',
+	"iquest":                           '\U000000BF',
+	"iuml":                             '\U000000EF',
+	"laquo":                            '\U000000AB',
+	"lt":                               '\U0000003C',
+	"macr":                             '\U000000AF',
+	"micro":                            '\U000000B5',
+	"middot":                           '\U000000B7',
+	"nbsp":                             '\U000000A0',
+	"not":                              '\U000000AC',
+	"ntilde":                           '\U000000F1',
+	"oacute":                           '\U000000F3',
+	"ocirc":                            '\U000000F4',
+	"ograve":                           '\U000000F2',
+	"ordf":                             '\U000000AA',
+	"ordm":                             '\U000000BA',
+	"oslash":                           '\U000000F8',
+	"otilde":                           '\U000000F5',
+	"ouml":                             '\U000000F6',
+	"para":                             '\U000000B6',
+	"plusmn":                           '\U000000B1',
+	"pound":                            '\U000000A3',
+	"quot":                             '\U00000022',
+	"raquo":                            '\U000000BB',
+	"reg":                              '\U000000AE',
+	"sect":                             '\U000000A7',
+	"shy":                              '\U000000AD',
+	"sup1":                             '\U000000B9',
+	"sup2":                             '\U000000B2',
+	"sup3":                             '\U000000B3',
+	"szlig":                            '\U000000DF',
+	"thorn":                            '\U000000FE',
+	"times":                            '\U000000D7',
+	"uacute":                           '\U000000FA',
+	"ucirc":                            '\U000000FB',
+	"ugrave":                           '\U000000F9',
+	"uml":                              '\U000000A8',
+	"uuml":                             '\U000000FC',
+	"yacute":                           '\U000000FD',
+	"yen":                              '\U000000A5',
+	"yuml":                             '\U000000FF',
 }
 
 // HTML entities that are two unicode codepoints.

+ 7 - 9
third_party/code.google.com/p/go.net/html/token.go

@@ -734,7 +734,6 @@ func (z *Tokenizer) readCDATA() bool {
 			brackets = 0
 		}
 	}
-	panic("unreachable")
 }
 
 // startTagIn returns whether the start tag in z.buf[z.data.start:z.data.end]
@@ -934,13 +933,13 @@ func (z *Tokenizer) readTagAttrVal() {
 
 // Next scans the next token and returns its type.
 func (z *Tokenizer) Next() TokenType {
+	z.raw.start = z.raw.end
+	z.data.start = z.raw.end
+	z.data.end = z.raw.end
 	if z.err != nil {
 		z.tt = ErrorToken
 		return z.tt
 	}
-	z.raw.start = z.raw.end
-	z.data.start = z.raw.end
-	z.data.end = z.raw.end
 	if z.rawTag != "" {
 		if z.rawTag == "plaintext" {
 			// Read everything up to EOF.
@@ -1010,12 +1009,11 @@ loop:
 				break loop
 			}
 			if c == '>' {
-				// "</>" does not generate a token at all.
+				// "</>" does not generate a token at all. Generate an empty comment
+				// to allow passthrough clients to pick up the data using Raw.
 				// Reset the tokenizer state and start again.
-				z.raw.start = z.raw.end
-				z.data.start = z.raw.end
-				z.data.end = z.raw.end
-				continue loop
+				z.tt = CommentToken
+				return z.tt
 			}
 			if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' {
 				z.readTag(false)

+ 35 - 16
third_party/code.google.com/p/go.net/html/token_test.go

@@ -63,12 +63,12 @@ var tokenTests = []tokenTest{
 	{
 		"not a tag #2",
 		"</>",
-		"",
+		"<!---->",
 	},
 	{
 		"not a tag #3",
 		"a</>b",
-		"a$b",
+		"a$<!---->$b",
 	},
 	{
 		"not a tag #4",
@@ -469,6 +469,25 @@ loop:
 	}
 }
 
+func TestPassthrough(t *testing.T) {
+	// Accumulating the raw output for each parse event should reconstruct the
+	// original input.
+	for _, test := range tokenTests {
+		z := NewTokenizer(strings.NewReader(test.html))
+		var parsed bytes.Buffer
+		for {
+			tt := z.Next()
+			parsed.Write(z.Raw())
+			if tt == ErrorToken {
+				break
+			}
+		}
+		if got, want := parsed.String(), test.html; got != want {
+			t.Errorf("%s: parsed output:\n got: %q\nwant: %q", test.desc, got, want)
+		}
+	}
+}
+
 func TestBufAPI(t *testing.T) {
 	s := "0<a>1</a>2<b>3<a>4<a>5</a>6</b>7</a>8<a/>9"
 	z := NewTokenizer(bytes.NewBufferString(s))
@@ -510,20 +529,20 @@ func TestConvertNewlines(t *testing.T) {
 		"Mac\rDOS\r\nUnix\n":    "Mac\nDOS\nUnix\n",
 		"Unix\nMac\rDOS\r\n":    "Unix\nMac\nDOS\n",
 		"DOS\r\nDOS\r\nDOS\r\n": "DOS\nDOS\nDOS\n",
-		"":         "",
-		"\n":       "\n",
-		"\n\r":     "\n\n",
-		"\r":       "\n",
-		"\r\n":     "\n",
-		"\r\n\n":   "\n\n",
-		"\r\n\r":   "\n\n",
-		"\r\n\r\n": "\n\n",
-		"\r\r":     "\n\n",
-		"\r\r\n":   "\n\n",
-		"\r\r\n\n": "\n\n\n",
-		"\r\r\r\n": "\n\n\n",
-		"\r \n":    "\n \n",
-		"xyz":      "xyz",
+		"":                      "",
+		"\n":                    "\n",
+		"\n\r":                  "\n\n",
+		"\r":                    "\n",
+		"\r\n":                  "\n",
+		"\r\n\n":                "\n\n",
+		"\r\n\r":                "\n\n",
+		"\r\n\r\n":              "\n\n",
+		"\r\r":                  "\n\n",
+		"\r\r\n":                "\n\n",
+		"\r\r\n\n":              "\n\n\n",
+		"\r\r\r\n":              "\n\n\n",
+		"\r \n":                 "\n \n",
+		"xyz":                   "xyz",
 	}
 	for in, want := range testCases {
 		if got := string(convertNewlines([]byte(in))); got != want {

+ 151 - 0
third_party/code.google.com/p/go.net/ipv6/control_rfc2292_unix.go

@@ -0,0 +1,151 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin
+
+package ipv6
+
+import (
+	"net"
+	"os"
+	"syscall"
+	"unsafe"
+)
+
+const pktinfo = FlagDst | FlagInterface
+
+func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
+	opt.Lock()
+	defer opt.Unlock()
+	if cf&FlagHopLimit != 0 {
+		if err := setIPv6ReceiveHopLimit(fd, on); err != nil {
+			return err
+		}
+		if on {
+			opt.set(FlagHopLimit)
+		} else {
+			opt.clear(FlagHopLimit)
+		}
+	}
+	if cf&pktinfo != 0 {
+		if err := setIPv6ReceivePacketInfo(fd, on); err != nil {
+			return err
+		}
+		if on {
+			opt.set(cf & pktinfo)
+		} else {
+			opt.clear(cf & pktinfo)
+		}
+	}
+	return nil
+}
+
+func newControlMessage(opt *rawOpt) (oob []byte) {
+	opt.Lock()
+	defer opt.Unlock()
+	l, off := 0, 0
+	if opt.isset(FlagHopLimit) {
+		l += syscall.CmsgSpace(4)
+	}
+	if opt.isset(pktinfo) {
+		l += syscall.CmsgSpace(sysSizeofPacketInfo)
+	}
+	if l > 0 {
+		oob = make([]byte, l)
+		if opt.isset(FlagHopLimit) {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockopt2292HopLimit
+			m.SetLen(syscall.CmsgLen(4))
+			off += syscall.CmsgSpace(4)
+		}
+		if opt.isset(pktinfo) {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockopt2292PacketInfo
+			m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
+			off += syscall.CmsgSpace(sysSizeofPacketInfo)
+		}
+	}
+	return
+}
+
+func parseControlMessage(b []byte) (*ControlMessage, error) {
+	if len(b) == 0 {
+		return nil, nil
+	}
+	cmsgs, err := syscall.ParseSocketControlMessage(b)
+	if err != nil {
+		return nil, os.NewSyscallError("parse socket control message", err)
+	}
+	cm := &ControlMessage{}
+	for _, m := range cmsgs {
+		if m.Header.Level != ianaProtocolIPv6 {
+			continue
+		}
+		switch m.Header.Type {
+		case sysSockopt2292HopLimit:
+			cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
+		case sysSockopt2292PacketInfo:
+			pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
+			cm.IfIndex = int(pi.IfIndex)
+			cm.Dst = pi.IP[:]
+		}
+	}
+	return cm, nil
+}
+
+func marshalControlMessage(cm *ControlMessage) (oob []byte) {
+	if cm == nil {
+		return
+	}
+	l, off := 0, 0
+	if cm.HopLimit > 0 {
+		l += syscall.CmsgSpace(4)
+	}
+	pion := false
+	if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
+		pion = true
+		l += syscall.CmsgSpace(sysSizeofPacketInfo)
+	}
+	if len(cm.NextHop) == net.IPv6len {
+		l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
+	}
+	if l > 0 {
+		oob = make([]byte, l)
+		if cm.HopLimit > 0 {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockopt2292HopLimit
+			m.SetLen(syscall.CmsgLen(4))
+			data := oob[off+syscall.CmsgLen(0):]
+			*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
+			off += syscall.CmsgSpace(4)
+		}
+		if pion {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockopt2292PacketInfo
+			m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
+			pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
+			if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
+				copy(pi.IP[:], ip)
+			}
+			if cm.IfIndex != 0 {
+				pi.IfIndex = uint32(cm.IfIndex)
+			}
+			off += syscall.CmsgSpace(sysSizeofPacketInfo)
+		}
+		if len(cm.NextHop) == net.IPv6len {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockopt2292NextHop
+			m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
+			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
+			setSockaddr(sa, cm.NextHop, cm.IfIndex)
+			off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
+		}
+	}
+	return
+}

+ 210 - 0
third_party/code.google.com/p/go.net/ipv6/control_rfc3542_unix.go

@@ -0,0 +1,210 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build freebsd linux netbsd openbsd
+
+package ipv6
+
+import (
+	"net"
+	"os"
+	"syscall"
+	"unsafe"
+)
+
+const pktinfo = FlagDst | FlagInterface
+
+func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
+	opt.Lock()
+	defer opt.Unlock()
+	if cf&FlagTrafficClass != 0 {
+		if err := setIPv6ReceiveTrafficClass(fd, on); err != nil {
+			return err
+		}
+		if on {
+			opt.set(FlagTrafficClass)
+		} else {
+			opt.clear(FlagTrafficClass)
+		}
+	}
+	if cf&FlagHopLimit != 0 {
+		if err := setIPv6ReceiveHopLimit(fd, on); err != nil {
+			return err
+		}
+		if on {
+			opt.set(FlagHopLimit)
+		} else {
+			opt.clear(FlagHopLimit)
+		}
+	}
+	if cf&pktinfo != 0 {
+		if err := setIPv6ReceivePacketInfo(fd, on); err != nil {
+			return err
+		}
+		if on {
+			opt.set(cf & pktinfo)
+		} else {
+			opt.clear(cf & pktinfo)
+		}
+	}
+	if cf&FlagPathMTU != 0 {
+		if err := setIPv6ReceivePathMTU(fd, on); err != nil {
+			return err
+		}
+		if on {
+			opt.set(FlagPathMTU)
+		} else {
+			opt.clear(FlagPathMTU)
+		}
+	}
+	return nil
+}
+
+func newControlMessage(opt *rawOpt) (oob []byte) {
+	opt.Lock()
+	defer opt.Unlock()
+	l, off := 0, 0
+	if opt.isset(FlagTrafficClass) {
+		l += syscall.CmsgSpace(4)
+	}
+	if opt.isset(FlagHopLimit) {
+		l += syscall.CmsgSpace(4)
+	}
+	if opt.isset(pktinfo) {
+		l += syscall.CmsgSpace(sysSizeofPacketInfo)
+	}
+	if opt.isset(FlagPathMTU) {
+		l += syscall.CmsgSpace(sysSizeofMTUInfo)
+	}
+	if l > 0 {
+		oob = make([]byte, l)
+		if opt.isset(FlagTrafficClass) {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockoptReceiveTrafficClass
+			m.SetLen(syscall.CmsgLen(4))
+			off += syscall.CmsgSpace(4)
+		}
+		if opt.isset(FlagHopLimit) {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockoptReceiveHopLimit
+			m.SetLen(syscall.CmsgLen(4))
+			off += syscall.CmsgSpace(4)
+		}
+		if opt.isset(pktinfo) {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockoptReceivePacketInfo
+			m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
+			off += syscall.CmsgSpace(sysSizeofPacketInfo)
+		}
+		if opt.isset(FlagPathMTU) {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockoptReceivePathMTU
+			m.SetLen(syscall.CmsgLen(sysSizeofMTUInfo))
+			off += syscall.CmsgSpace(sysSizeofMTUInfo)
+		}
+	}
+	return
+}
+
+func parseControlMessage(b []byte) (*ControlMessage, error) {
+	if len(b) == 0 {
+		return nil, nil
+	}
+	cmsgs, err := syscall.ParseSocketControlMessage(b)
+	if err != nil {
+		return nil, os.NewSyscallError("parse socket control message", err)
+	}
+	cm := &ControlMessage{}
+	for _, m := range cmsgs {
+		if m.Header.Level != ianaProtocolIPv6 {
+			continue
+		}
+		switch m.Header.Type {
+		case sysSockoptTrafficClass:
+			cm.TrafficClass = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
+		case sysSockoptHopLimit:
+			cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
+		case sysSockoptPacketInfo:
+			pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
+			cm.Dst = pi.IP[:]
+			cm.IfIndex = int(pi.IfIndex)
+		case sysSockoptPathMTU:
+			mi := (*sysMTUInfo)(unsafe.Pointer(&m.Data[0]))
+			cm.Dst = mi.Addr.Addr[:]
+			cm.IfIndex = int(mi.Addr.Scope_id)
+			cm.MTU = int(mi.MTU)
+		}
+	}
+	return cm, nil
+}
+
+func marshalControlMessage(cm *ControlMessage) (oob []byte) {
+	if cm == nil {
+		return
+	}
+	l, off := 0, 0
+	if cm.TrafficClass > 0 {
+		l += syscall.CmsgSpace(4)
+	}
+	if cm.HopLimit > 0 {
+		l += syscall.CmsgSpace(4)
+	}
+	pion := false
+	if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
+		pion = true
+		l += syscall.CmsgSpace(sysSizeofPacketInfo)
+	}
+	if len(cm.NextHop) == net.IPv6len {
+		l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
+	}
+	if l > 0 {
+		oob = make([]byte, l)
+		if cm.TrafficClass > 0 {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockoptTrafficClass
+			m.SetLen(syscall.CmsgLen(4))
+			data := oob[off+syscall.CmsgLen(0):]
+			*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.TrafficClass)
+			off += syscall.CmsgSpace(4)
+		}
+		if cm.HopLimit > 0 {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockoptHopLimit
+			m.SetLen(syscall.CmsgLen(4))
+			data := oob[off+syscall.CmsgLen(0):]
+			*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
+			off += syscall.CmsgSpace(4)
+		}
+		if pion {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockoptPacketInfo
+			m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
+			pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
+			if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
+				copy(pi.IP[:], ip)
+			}
+			if cm.IfIndex != 0 {
+				pi.IfIndex = uint32(cm.IfIndex)
+			}
+			off += syscall.CmsgSpace(sysSizeofPacketInfo)
+		}
+		if len(cm.NextHop) == net.IPv6len {
+			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
+			m.Level = ianaProtocolIPv6
+			m.Type = sysSockoptNextHop
+			m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
+			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
+			setSockaddr(sa, cm.NextHop, cm.IfIndex)
+			off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
+		}
+	}
+	return
+}

+ 18 - 0
third_party/code.google.com/p/go.net/ipv6/icmp_test.go

@@ -14,6 +14,24 @@ import (
 	"testing"
 )
 
+var icmpStringTests = []struct {
+	in  ipv6.ICMPType
+	out string
+}{
+	{ipv6.ICMPTypeDestinationUnreachable, "destination unreachable"},
+
+	{256, "<nil>"},
+}
+
+func TestICMPString(t *testing.T) {
+	for _, tt := range icmpStringTests {
+		s := tt.in.String()
+		if s != tt.out {
+			t.Errorf("got %s; expected %s", s, tt.out)
+		}
+	}
+}
+
 func TestICMPFilter(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9", "windows":

+ 0 - 22
third_party/code.google.com/p/go.net/ipv6/mocktransponder_test.go

@@ -86,25 +86,3 @@ func acceptor(t *testing.T, ln net.Listener, done chan<- bool) {
 	}
 	c.Close()
 }
-
-func transponder(t *testing.T, ln net.Listener, done chan<- bool) {
-	defer func() { done <- true }()
-
-	c, err := ln.Accept()
-	if err != nil {
-		t.Errorf("net.Listener.Accept failed: %v", err)
-		return
-	}
-	defer c.Close()
-
-	b := make([]byte, 128)
-	n, err := c.Read(b)
-	if err != nil {
-		t.Errorf("net.Conn.Read failed: %v", err)
-		return
-	}
-	if _, err := c.Write(b[:n]); err != nil {
-		t.Errorf("net.Conn.Write failed: %v", err)
-		return
-	}
-}

+ 21 - 11
third_party/code.google.com/p/go.net/ipv6/multicast_test.go

@@ -5,6 +5,7 @@
 package ipv6_test
 
 import (
+	"bytes"
 	"code.google.com/p/go.net/ipv6"
 	"net"
 	"os"
@@ -64,24 +65,30 @@ func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
 
 	cm := ipv6.ControlMessage{
 		TrafficClass: DiffServAF11 | CongestionExperienced,
+		Src:          net.IPv6loopback,
 		IfIndex:      ifi.Index,
 	}
-	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
+	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
+	wb := []byte("HELLO-R-U-THERE")
 
 	for i, toggle := range []bool{true, false, true} {
 		if err := p.SetControlMessage(cf, toggle); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
 		}
-		if err := p.SetDeadline(time.Now().Add(time.Millisecond * 200)); err != nil {
+		if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
 		}
 		cm.HopLimit = i + 1
-		if _, err := p.WriteTo([]byte("HELLO-R-U-THERE"), &cm, dst); err != nil {
+		if n, err := p.WriteTo(wb, &cm, dst); err != nil {
 			t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
+		} else if n != len(wb) {
+			t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
 		}
-		b := make([]byte, 128)
-		if _, cm, _, err := p.ReadFrom(b); err != nil {
+		rb := make([]byte, 128)
+		if n, cm, _, err := p.ReadFrom(rb); err != nil {
 			t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
+		} else if !bytes.Equal(rb[:n], wb) {
+			t.Fatalf("got %v; expected %v", rb[:n], wb)
 		} else {
 			t.Logf("rcvd cmsg: %v", cm)
 		}
@@ -136,9 +143,10 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
 
 	cm := ipv6.ControlMessage{
 		TrafficClass: DiffServAF11 | CongestionExperienced,
+		Src:          net.IPv6loopback,
 		IfIndex:      ifi.Index,
 	}
-	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
+	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
 
 	var f ipv6.ICMPFilter
 	f.SetAll(true)
@@ -173,19 +181,21 @@ func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
 		if err := p.SetControlMessage(cf, toggle); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
 		}
-		if err := p.SetDeadline(time.Now().Add(time.Millisecond * 200)); err != nil {
+		if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetDeadline failed: %v", err)
 		}
 		cm.HopLimit = i + 1
-		if _, err := p.WriteTo(wb, &cm, dst); err != nil {
+		if n, err := p.WriteTo(wb, &cm, dst); err != nil {
 			t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
+		} else if n != len(wb) {
+			t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
 		}
-		b := make([]byte, 128)
-		if n, cm, _, err := p.ReadFrom(b); err != nil {
+		rb := make([]byte, 128)
+		if n, cm, _, err := p.ReadFrom(rb); err != nil {
 			t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
 		} else {
 			t.Logf("rcvd cmsg: %v", cm)
-			if m, err := parseICMPMessage(b[:n]); err != nil {
+			if m, err := parseICMPMessage(rb[:n]); err != nil {
 				t.Fatalf("parseICMPMessage failed: %v", err)
 			} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
 				t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)

+ 168 - 0
third_party/code.google.com/p/go.net/ipv6/readwrite_test.go

@@ -0,0 +1,168 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6_test
+
+import (
+	"bytes"
+	"code.google.com/p/go.net/ipv6"
+	"net"
+	"runtime"
+	"sync"
+	"testing"
+)
+
+func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
+	c, err := net.ListenPacket("udp6", "[::1]:0")
+	if err != nil {
+		return nil, nil, err
+	}
+	dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
+	if err != nil {
+		c.Close()
+		return nil, nil, err
+	}
+	return c, dst, nil
+}
+
+func BenchmarkReadWriteNetUDP(b *testing.B) {
+	c, dst, err := benchmarkUDPListener()
+	if err != nil {
+		b.Fatalf("benchmarkUDPListener failed: %v", err)
+	}
+	defer c.Close()
+
+	wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
+	}
+}
+
+func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
+	if _, err := c.WriteTo(wb, dst); err != nil {
+		b.Fatalf("net.PacketConn.WriteTo failed: %v", err)
+	}
+	if _, _, err := c.ReadFrom(rb); err != nil {
+		b.Fatalf("net.PacketConn.ReadFrom failed: %v", err)
+	}
+}
+
+func BenchmarkReadWriteIPv6UDP(b *testing.B) {
+	c, dst, err := benchmarkUDPListener()
+	if err != nil {
+		b.Fatalf("benchmarkUDPListener failed: %v", err)
+	}
+	defer c.Close()
+
+	p := ipv6.NewPacketConn(c)
+	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
+	if err := p.SetControlMessage(cf, true); err != nil {
+		b.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
+	}
+	ifi := loopbackInterface()
+
+	wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
+	}
+}
+
+func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
+	cm := ipv6.ControlMessage{
+		TrafficClass: DiffServAF11 | CongestionExperienced,
+		HopLimit:     1,
+	}
+	if ifi != nil {
+		cm.IfIndex = ifi.Index
+	}
+	if n, err := p.WriteTo(wb, &cm, dst); err != nil {
+		b.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
+	} else if n != len(wb) {
+		b.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
+	}
+	if _, _, _, err := p.ReadFrom(rb); err != nil {
+		b.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
+	}
+}
+
+func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("not supported on %q", runtime.GOOS)
+	}
+	if !supportsIPv6 {
+		t.Skip("ipv6 is not supported")
+	}
+
+	c, err := net.ListenPacket("udp6", "[::1]:0")
+	if err != nil {
+		t.Fatalf("net.ListenPacket failed: %v", err)
+	}
+	defer c.Close()
+	p := ipv6.NewPacketConn(c)
+	defer p.Close()
+
+	dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
+	if err != nil {
+		t.Fatalf("net.ResolveUDPAddr failed: %v", err)
+	}
+
+	ifi := loopbackInterface()
+	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
+	wb := []byte("HELLO-R-U-THERE")
+
+	var wg sync.WaitGroup
+	reader := func() {
+		defer wg.Done()
+		rb := make([]byte, 128)
+		if n, cm, _, err := p.ReadFrom(rb); err != nil {
+			t.Errorf("ipv6.PacketConn.ReadFrom failed: %v", err)
+			return
+		} else if !bytes.Equal(rb[:n], wb) {
+			t.Errorf("got %v; expected %v", rb[:n], wb)
+			return
+		} else {
+			t.Logf("rcvd cmsg: %v", cm)
+		}
+	}
+	writer := func(toggle bool) {
+		defer wg.Done()
+		cm := ipv6.ControlMessage{
+			TrafficClass: DiffServAF11 | CongestionExperienced,
+			Src:          net.IPv6loopback,
+			Dst:          net.IPv6loopback,
+		}
+		if ifi != nil {
+			cm.IfIndex = ifi.Index
+		}
+		if err := p.SetControlMessage(cf, toggle); err != nil {
+			t.Errorf("ipv6.PacketConn.SetControlMessage failed: %v", err)
+			return
+		}
+		if n, err := p.WriteTo(wb, &cm, dst); err != nil {
+			t.Errorf("ipv6.PacketConn.WriteTo failed: %v", err)
+			return
+		} else if n != len(wb) {
+			t.Errorf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
+			return
+		}
+	}
+
+	const N = 10
+	wg.Add(N)
+	for i := 0; i < N; i++ {
+		go reader()
+	}
+	wg.Add(2 * N)
+	for i := 0; i < 2*N; i++ {
+		go writer(i%2 != 0)
+	}
+	wg.Add(N)
+	for i := 0; i < N; i++ {
+		go reader()
+	}
+	wg.Wait()
+}

+ 73 - 0
third_party/code.google.com/p/go.net/ipv6/sockopt_rfc2292_unix.go

@@ -0,0 +1,73 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin
+
+package ipv6
+
+import (
+	"os"
+	"unsafe"
+)
+
+func ipv6ReceiveTrafficClass(fd int) (bool, error) {
+	return false, errNotSupported
+}
+
+func setIPv6ReceiveTrafficClass(fd int, v bool) error {
+	return errNotSupported
+}
+
+func ipv6ReceiveHopLimit(fd int) (bool, error) {
+	var v int32
+	l := sysSockoptLen(4)
+	if err := getsockopt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
+		return false, os.NewSyscallError("getsockopt", err)
+	}
+	return v == 1, nil
+}
+
+func setIPv6ReceiveHopLimit(fd int, v bool) error {
+	vv := int32(boolint(v))
+	return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, uintptr(unsafe.Pointer(&vv)), 4))
+}
+
+func ipv6ReceivePacketInfo(fd int) (bool, error) {
+	var v int32
+	l := sysSockoptLen(4)
+	if err := getsockopt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, uintptr(unsafe.Pointer(&v)), &l); err != nil {
+		return false, os.NewSyscallError("getsockopt", err)
+	}
+	return v == 1, nil
+}
+
+func setIPv6ReceivePacketInfo(fd int, v bool) error {
+	vv := int32(boolint(v))
+	return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, uintptr(unsafe.Pointer(&vv)), 4))
+}
+
+func ipv6PathMTU(fd int) (int, error) {
+	return 0, errNotSupported
+}
+
+func ipv6ReceivePathMTU(fd int) (bool, error) {
+	return false, errNotSupported
+}
+
+func setIPv6ReceivePathMTU(fd int, v bool) error {
+	return errNotSupported
+}
+
+func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
+	var v ICMPFilter
+	l := sysSockoptLen(sysSizeofICMPFilter)
+	if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&v.sysICMPFilter)), &l); err != nil {
+		return nil, os.NewSyscallError("getsockopt", err)
+	}
+	return &v, nil
+}
+
+func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
+	return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(unsafe.Pointer(&f.sysICMPFilter)), sysSizeofICMPFilter))
+}

+ 23 - 0
third_party/code.google.com/p/go.net/ipv6/sys.go

@@ -0,0 +1,23 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+type sysSockoptLen uint32
+
+const (
+	sysSizeofPacketInfo   = 0x14
+	sysSizeofMulticastReq = 0x14
+	sysSizeofICMPFilter   = 0x20
+)
+
+type sysPacketInfo struct {
+	IP      [16]byte
+	IfIndex uint32
+}
+
+type sysMulticastReq struct {
+	IP      [16]byte
+	IfIndex uint32
+}

+ 48 - 0
third_party/code.google.com/p/go.net/ipv6/sys_bsd.go

@@ -0,0 +1,48 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build freebsd netbsd openbsd
+
+package ipv6
+
+import (
+	"net"
+	"syscall"
+)
+
+// RFC 3493 options
+const (
+	// See /usr/include/netinet6/in6.h.
+	sysSockoptUnicastHopLimit    = 0x4
+	sysSockoptMulticastHopLimit  = 0xa
+	sysSockoptMulticastInterface = 0x9
+	sysSockoptMulticastLoopback  = 0xb
+	sysSockoptJoinGroup          = 0xc
+	sysSockoptLeaveGroup         = 0xd
+)
+
+// RFC 3542 options
+const (
+	// See /usr/include/netinet6/in6.h.
+	sysSockoptReceiveTrafficClass = 0x39
+	sysSockoptTrafficClass        = 0x3d
+	sysSockoptReceiveHopLimit     = 0x25
+	sysSockoptHopLimit            = 0x2f
+	sysSockoptReceivePacketInfo   = 0x24
+	sysSockoptPacketInfo          = 0x2e
+	sysSockoptReceivePathMTU      = 0x2b
+	sysSockoptPathMTU             = 0x2c
+	sysSockoptNextHop             = 0x30
+	sysSockoptChecksum            = 0x1a
+
+	// See /usr/include/netinet6/in6.h.
+	sysSockoptICMPFilter = 0x12
+)
+
+func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
+	sa.Len = syscall.SizeofSockaddrInet6
+	sa.Family = syscall.AF_INET6
+	copy(sa.Addr[:], ip)
+	sa.Scope_id = uint32(ifindex)
+}

+ 54 - 0
third_party/code.google.com/p/go.net/ipv6/sys_darwin.go

@@ -0,0 +1,54 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+	"net"
+	"syscall"
+)
+
+// RFC 2292 options
+const (
+	// See /usr/include/netinet6/in6.h.
+	sysSockopt2292HopLimit   = 0x14
+	sysSockopt2292PacketInfo = 0x13
+	sysSockopt2292NextHop    = 0x15
+)
+
+// RFC 3493 options
+const (
+	// See /usr/include/netinet6/in6.h.
+	sysSockoptUnicastHopLimit    = 0x4
+	sysSockoptMulticastHopLimit  = 0xa
+	sysSockoptMulticastInterface = 0x9
+	sysSockoptMulticastLoopback  = 0xb
+	sysSockoptJoinGroup          = 0xc
+	sysSockoptLeaveGroup         = 0xd
+)
+
+// RFC 3542 options
+const (
+	// See /usr/include/netinet6/in6.h.
+	sysSockoptReceiveTrafficClass = 0x23
+	sysSockoptTrafficClass        = 0x24
+	sysSockoptReceiveHopLimit     = 0x25
+	sysSockoptHopLimit            = 0x2f
+	sysSockoptReceivePacketInfo   = 0x3d
+	sysSockoptPacketInfo          = 0x2e
+	sysSockoptReceivePathMTU      = 0x2b
+	sysSockoptPathMTU             = 0x2c
+	sysSockoptNextHop             = 0x30
+	sysSockoptChecksum            = 0x1a
+
+	// See /usr/include/netinet6/in6.h.
+	sysSockoptICMPFilter = 0x12
+)
+
+func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
+	sa.Len = syscall.SizeofSockaddrInet6
+	sa.Family = syscall.AF_INET6
+	copy(sa.Addr[:], ip)
+	sa.Scope_id = uint32(ifindex)
+}

+ 45 - 0
third_party/code.google.com/p/go.net/ipv6/sys_linux.go

@@ -0,0 +1,45 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+	"net"
+	"syscall"
+)
+
+// RFC 3493 options
+const (
+	// See /usr/include/linux/in6.h.
+	sysSockoptUnicastHopLimit    = 0x10
+	sysSockoptMulticastHopLimit  = 0x12
+	sysSockoptMulticastInterface = 0x11
+	sysSockoptMulticastLoopback  = 0x13
+	sysSockoptJoinGroup          = 0x14
+	sysSockoptLeaveGroup         = 0x15
+)
+
+// RFC 3542 options
+const (
+	// See /usr/include/linux/ipv6.h,in6.h.
+	sysSockoptReceiveTrafficClass = 0x42
+	sysSockoptTrafficClass        = 0x43
+	sysSockoptReceiveHopLimit     = 0x33
+	sysSockoptHopLimit            = 0x34
+	sysSockoptReceivePacketInfo   = 0x31
+	sysSockoptPacketInfo          = 0x32
+	sysSockoptReceivePathMTU      = 0x3c
+	sysSockoptPathMTU             = 0x3d
+	sysSockoptNextHop             = 0x9
+	sysSockoptChecksum            = 0x7
+
+	// See /usr/include/linux/icmpv6.h.
+	sysSockoptICMPFilter = 0x1
+)
+
+func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
+	sa.Family = syscall.AF_INET6
+	copy(sa.Addr[:], ip)
+	sa.Scope_id = uint32(ifindex)
+}

+ 16 - 0
third_party/code.google.com/p/go.net/ipv6/sys_unix.go

@@ -0,0 +1,16 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd linux netbsd openbsd
+
+package ipv6
+
+import "syscall"
+
+const sysSizeofMTUInfo = 0x20
+
+type sysMTUInfo struct {
+	Addr syscall.RawSockaddrInet6
+	MTU  uint32
+}

+ 33 - 0
third_party/code.google.com/p/go.net/ipv6/sys_windows.go

@@ -0,0 +1,33 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ipv6
+
+import (
+	"net"
+	"syscall"
+)
+
+// RFC 3493 options
+const (
+	// See ws2tcpip.h.
+	sysSockoptUnicastHopLimit    = 0x4
+	sysSockoptMulticastHopLimit  = 0xa
+	sysSockoptMulticastInterface = 0x9
+	sysSockoptMulticastLoopback  = 0xb
+	sysSockoptJoinGroup          = 0xc
+	sysSockoptLeaveGroup         = 0xd
+)
+
+// RFC 3542 options
+const (
+	// See ws2tcpip.h.
+	sysSockoptPacketInfo = 0x13
+)
+
+func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
+	sa.Family = syscall.AF_INET6
+	copy(sa.Addr[:], ip)
+	sa.Scope_id = uint32(ifindex)
+}

+ 42 - 0
third_party/code.google.com/p/go.net/ipv6/syscall_linux_386.go

@@ -0,0 +1,42 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code is a duplicate of syscall/syscall_linux_386.go with small
+// modifications.
+
+package ipv6
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+// On x86 Linux, all the socket calls go through an extra indirection,
+// I think because the 5-register system call interface can't handle
+// the 6-argument calls like sendto and recvfrom. Instead the
+// arguments to the underlying system call are the number below and a
+// pointer to an array of uintptr. We hide the pointer in the
+// socketcall assembly to avoid allocation on every system call.
+
+const (
+	// See /usr/include/linux/net.h.
+	_SETSOCKOPT = 14
+	_GETSOCKOPT = 15
+)
+
+var socketcall func(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
+
+func getsockopt(fd int, level int, name int, v uintptr, l *sysSockoptLen) error {
+	if _, errno := socketcall(_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
+		return error(errno)
+	}
+	return nil
+}
+
+func setsockopt(fd int, level int, name int, v uintptr, l uintptr) error {
+	if _, errno := socketcall(_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), v, l, 0); errno != 0 {
+		return error(errno)
+	}
+	return nil
+}

+ 56 - 0
third_party/code.google.com/p/go.net/ipv6/syscall_linux_386.s

@@ -0,0 +1,56 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code is a duplicate of syscall/syscall_linux_386.s with small
+// modifications.
+
+#define SYS_SOCKETCALL	102	// from zsysnum_linux_386.go
+
+// func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
+// Kernel interface gets call sub-number and pointer to a0 for Go 1.1.
+TEXT ·socketcallnosplit7(SB),7,$0
+	CALL	runtime·entersyscall(SB)
+	MOVL	$SYS_SOCKETCALL, AX	// syscall entry
+	MOVL	4(SP), BX		// socket call number
+	LEAL	8(SP), CX		// pointer to call arguments
+	MOVL	$0, DX
+	MOVL	$0, SI
+	MOVL	$0, DI
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	ok1
+	MOVL	$-1, 32(SP)		// n
+	NEGL	AX
+	MOVL	AX, 36(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok1:
+	MOVL	AX, 32(SP)		// n
+	MOVL	$0, 36(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+// func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
+// Kernel interface gets call sub-number and pointer to a0 for Go 1.2.
+TEXT ·socketcallnosplit4(SB),4,$0-40
+	CALL	runtime·entersyscall(SB)
+	MOVL	$SYS_SOCKETCALL, AX	// syscall entry
+	MOVL	4(SP), BX		// socket call number
+	LEAL	8(SP), CX		// pointer to call arguments
+	MOVL	$0, DX
+	MOVL	$0, SI
+	MOVL	$0, DI
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	ok2
+	MOVL	$-1, 32(SP)		// n
+	NEGL	AX
+	MOVL	AX, 36(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok2:
+	MOVL	AX, 32(SP)		// n
+	MOVL	$0, 36(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET

+ 15 - 0
third_party/code.google.com/p/go.net/ipv6/syscall_nosplit4_linux_386.go

@@ -0,0 +1,15 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.2
+
+package ipv6
+
+import "syscall"
+
+func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
+
+func init() {
+	socketcall = socketcallnosplit4
+}

+ 15 - 0
third_party/code.google.com/p/go.net/ipv6/syscall_nosplit7_linux_386.go

@@ -0,0 +1,15 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.1,!go1.2
+
+package ipv6
+
+import "syscall"
+
+func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
+
+func init() {
+	socketcall = socketcallnosplit7
+}

+ 26 - 0
third_party/code.google.com/p/go.net/ipv6/syscall_unix.go

@@ -0,0 +1,26 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd linux,amd64 linux,arm netbsd openbsd
+
+package ipv6
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func getsockopt(fd int, level, name int, v uintptr, l *sysSockoptLen) error {
+	if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
+		return error(errno)
+	}
+	return nil
+}
+
+func setsockopt(fd int, level int, name int, v uintptr, l uintptr) error {
+	if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
+		return error(errno)
+	}
+	return nil
+}

+ 32 - 91
third_party/code.google.com/p/go.net/ipv6/unicast_test.go

@@ -5,6 +5,7 @@
 package ipv6_test
 
 import (
+	"bytes"
 	"code.google.com/p/go.net/ipv6"
 	"net"
 	"os"
@@ -13,79 +14,6 @@ import (
 	"time"
 )
 
-func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
-	c, err := net.ListenPacket("udp6", "[::1]:0")
-	if err != nil {
-		return nil, nil, err
-	}
-	dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
-	if err != nil {
-		c.Close()
-		return nil, nil, err
-	}
-	return c, dst, nil
-}
-
-func BenchmarkReadWriteNetUDP(b *testing.B) {
-	c, dst, err := benchmarkUDPListener()
-	if err != nil {
-		b.Fatalf("benchmarkUDPListener failed: %v", err)
-	}
-	defer c.Close()
-
-	wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
-	}
-}
-
-func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
-	if _, err := c.WriteTo(wb, dst); err != nil {
-		b.Fatalf("net.PacketConn.WriteTo failed: %v", err)
-	}
-	if _, _, err := c.ReadFrom(rb); err != nil {
-		b.Fatalf("net.PacketConn.ReadFrom failed: %v", err)
-	}
-}
-
-func BenchmarkReadWriteIPv6UDP(b *testing.B) {
-	c, dst, err := benchmarkUDPListener()
-	if err != nil {
-		b.Fatalf("benchmarkUDPListener failed: %v", err)
-	}
-	defer c.Close()
-
-	p := ipv6.NewPacketConn(c)
-	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
-	if err := p.SetControlMessage(cf, true); err != nil {
-		b.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
-	}
-	ifi := loopbackInterface()
-
-	wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
-	}
-}
-
-func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
-	cm := ipv6.ControlMessage{
-		TrafficClass: DiffServAF11 | CongestionExperienced,
-		HopLimit:     1,
-	}
-	if ifi != nil {
-		cm.IfIndex = ifi.Index
-	}
-	if _, err := p.WriteTo(wb, &cm, dst); err != nil {
-		b.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
-	}
-	if _, _, _, err := p.ReadFrom(rb); err != nil {
-		b.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
-	}
-}
-
 func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
 	switch runtime.GOOS {
 	case "plan9", "windows":
@@ -100,40 +28,47 @@ func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
 		t.Fatalf("net.ListenPacket failed: %v", err)
 	}
 	defer c.Close()
+	p := ipv6.NewPacketConn(c)
+	defer p.Close()
 
 	dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
 	if err != nil {
 		t.Fatalf("net.ResolveUDPAddr failed: %v", err)
 	}
 
-	p := ipv6.NewPacketConn(c)
-	defer p.Close()
 	cm := ipv6.ControlMessage{
 		TrafficClass: DiffServAF11 | CongestionExperienced,
+		Src:          net.IPv6loopback,
+		Dst:          net.IPv6loopback,
 	}
-	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
+	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
 	ifi := loopbackInterface()
 	if ifi != nil {
 		cm.IfIndex = ifi.Index
 	}
+	wb := []byte("HELLO-R-U-THERE")
 
 	for i, toggle := range []bool{true, false, true} {
 		if err := p.SetControlMessage(cf, toggle); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
 		}
 		cm.HopLimit = i + 1
-		if err := p.SetWriteDeadline(time.Now().Add(time.Millisecond * 100)); err != nil {
+		if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
 		}
-		if _, err := p.WriteTo([]byte("HELLO-R-U-THERE"), &cm, dst); err != nil {
+		if n, err := p.WriteTo(wb, &cm, dst); err != nil {
 			t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
+		} else if n != len(wb) {
+			t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
 		}
-		b := make([]byte, 128)
-		if err := p.SetReadDeadline(time.Now().Add(time.Millisecond * 100)); err != nil {
+		rb := make([]byte, 128)
+		if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetReadDeadline failed: %v", err)
 		}
-		if _, cm, _, err := p.ReadFrom(b); err != nil {
+		if n, cm, _, err := p.ReadFrom(rb); err != nil {
 			t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
+		} else if !bytes.Equal(rb[:n], wb) {
+			t.Fatalf("got %v; expected %v", rb[:n], wb)
 		} else {
 			t.Logf("rcvd cmsg: %v", cm)
 		}
@@ -157,6 +92,8 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
 		t.Fatalf("net.ListenPacket failed: %v", err)
 	}
 	defer c.Close()
+	p := ipv6.NewPacketConn(c)
+	defer p.Close()
 
 	dst, err := net.ResolveIPAddr("ip6", "::1")
 	if err != nil {
@@ -164,10 +101,12 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
 	}
 
 	pshicmp := ipv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP, ianaProtocolIPv6ICMP)
-	p := ipv6.NewPacketConn(c)
-	defer p.Close()
-	cm := ipv6.ControlMessage{TrafficClass: DiffServAF11 | CongestionExperienced}
-	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagInterface | ipv6.FlagPathMTU
+	cm := ipv6.ControlMessage{
+		TrafficClass: DiffServAF11 | CongestionExperienced,
+		Src:          net.IPv6loopback,
+		Dst:          net.IPv6loopback,
+	}
+	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
 	ifi := loopbackInterface()
 	if ifi != nil {
 		cm.IfIndex = ifi.Index
@@ -207,21 +146,23 @@ func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
 			t.Fatalf("ipv6.PacketConn.SetControlMessage failed: %v", err)
 		}
 		cm.HopLimit = i + 1
-		if err := p.SetWriteDeadline(time.Now().Add(time.Millisecond * 100)); err != nil {
+		if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetWriteDeadline failed: %v", err)
 		}
-		if _, err := p.WriteTo(wb, &cm, dst); err != nil {
+		if n, err := p.WriteTo(wb, &cm, dst); err != nil {
 			t.Fatalf("ipv6.PacketConn.WriteTo failed: %v", err)
+		} else if n != len(wb) {
+			t.Fatalf("ipv6.PacketConn.WriteTo failed: short write: %v", n)
 		}
-		b := make([]byte, 128)
-		if err := p.SetReadDeadline(time.Now().Add(time.Millisecond * 100)); err != nil {
+		rb := make([]byte, 128)
+		if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
 			t.Fatalf("ipv6.PacketConn.SetReadDeadline failed: %v", err)
 		}
-		if n, cm, _, err := p.ReadFrom(b); err != nil {
+		if n, cm, _, err := p.ReadFrom(rb); err != nil {
 			t.Fatalf("ipv6.PacketConn.ReadFrom failed: %v", err)
 		} else {
 			t.Logf("rcvd cmsg: %v", cm)
-			if m, err := parseICMPMessage(b[:n]); err != nil {
+			if m, err := parseICMPMessage(rb[:n]); err != nil {
 				t.Fatalf("parseICMPMessage failed: %v", err)
 			} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
 				t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)

+ 9 - 9
third_party/code.google.com/p/go.net/spdy/spdy_test.go

@@ -39,9 +39,9 @@ func TestCreateParseSynStreamFrameCompressionDisable(t *testing.T) {
 	// Fixture framer for no compression test.
 	framer := &Framer{
 		headerCompressionDisabled: true,
-		w:         buffer,
-		headerBuf: new(bytes.Buffer),
-		r:         buffer,
+		w:                         buffer,
+		headerBuf:                 new(bytes.Buffer),
+		r:                         buffer,
 	}
 	synStreamFrame := SynStreamFrame{
 		CFHeader: ControlFrameHeader{
@@ -101,9 +101,9 @@ func TestCreateParseSynReplyFrameCompressionDisable(t *testing.T) {
 	buffer := new(bytes.Buffer)
 	framer := &Framer{
 		headerCompressionDisabled: true,
-		w:         buffer,
-		headerBuf: new(bytes.Buffer),
-		r:         buffer,
+		w:                         buffer,
+		headerBuf:                 new(bytes.Buffer),
+		r:                         buffer,
 	}
 	synReplyFrame := SynReplyFrame{
 		CFHeader: ControlFrameHeader{
@@ -302,9 +302,9 @@ func TestCreateParseHeadersFrame(t *testing.T) {
 	buffer := new(bytes.Buffer)
 	framer := &Framer{
 		headerCompressionDisabled: true,
-		w:         buffer,
-		headerBuf: new(bytes.Buffer),
-		r:         buffer,
+		w:                         buffer,
+		headerBuf:                 new(bytes.Buffer),
+		r:                         buffer,
 	}
 	headersFrame := HeadersFrame{
 		CFHeader: ControlFrameHeader{

+ 2 - 0
third_party/code.google.com/p/goprotobuf/README

@@ -2,6 +2,8 @@ Go support for Protocol Buffers - Google's data interchange format
 Copyright 2010 The Go Authors.
 http://code.google.com/p/goprotobuf/
 
+This package and the code it generates requires at least Go 1.1.
+
 This software implements Go bindings for protocol buffers.  For
 information about protocol buffers themselves, see
 	http://code.google.com/apis/protocolbuffers/

+ 1 - 1
third_party/code.google.com/p/goprotobuf/lib/codereview/codereview.cfg

@@ -1,2 +1,2 @@
-defaultcc: golang-dev@googlegroups.com
+defaultcc: golang-codereviews@googlegroups.com
 contributors: http://go.googlecode.com/hg/CONTRIBUTORS

+ 58 - 3
third_party/github.com/BurntSushi/toml/README.md

@@ -1,6 +1,10 @@
-# TOML parser for Go with reflection
+# TOML parser and encoder for Go with reflection
 
-TOML stands for Tom's Obvious, Minimal Language.
+TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
+reflection interface similar to Go's standard library `json` and `xml` 
+packages. This package also supports the `encoding.TextUnmarshaler` and
+`encoding.TextMarshaler` interfaces so that you can define custom data 
+representations. (There is an example of this below.)
 
 Spec: https://github.com/mojombo/toml
 
@@ -26,7 +30,8 @@ tomlv some-toml-file.toml
 ## Testing
 
 This package passes all tests in
-[toml-test](https://github.com/BurntSushi/toml-test).
+[toml-test](https://github.com/BurntSushi/toml-test) for both the decoder
+and the encoder.
 
 ## Examples
 
@@ -78,6 +83,56 @@ type TOML struct {
 }
 ```
 
+## Using the `encoding.TextUnmarshaler` interface
+
+Here's an example that automatically parses duration strings into 
+`time.Duration` values:
+
+```toml
+[[song]]
+name = "Thunder Road"
+duration = "4m49s"
+
+[[song]]
+name = "Stairway to Heaven"
+duration = "8m03s"
+```
+
+Which can be decoded with:
+
+```go
+type song struct {
+  Name     string
+  Duration duration
+}
+type songs struct {
+  Song []song
+}
+var favorites songs
+if _, err := Decode(blob, &favorites); err != nil {
+  log.Fatal(err)
+}
+
+for _, s := range favorites.Song {
+  fmt.Printf("%s (%s)\n", s.Name, s.Duration)
+}
+```
+
+And you'll also need a `duration` type that satisfies the 
+`encoding.TextUnmarshaler` interface:
+
+```go
+type duration struct {
+	time.Duration
+}
+
+func (d *duration) UnmarshalText(text []byte) error {
+	var err error
+	d.Duration, err = time.ParseDuration(string(text))
+	return err
+}
+```
+
 ## More complex usage
 
 Here's an example of how to load the example from the official spec page:

+ 138 - 23
third_party/github.com/BurntSushi/toml/decode.go

@@ -1,6 +1,7 @@
 package toml
 
 import (
+	"encoding"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -43,11 +44,62 @@ func PrimitiveDecode(primValue Primitive, v interface{}) error {
 // TOML hashes correspond to Go structs or maps. (Dealer's choice. They can be
 // used interchangeably.)
 //
+// TOML arrays of tables correspond to either a slice of structs or a slice
+// of maps.
+//
 // TOML datetimes correspond to Go `time.Time` values.
 //
 // All other TOML types (float, string, int, bool and array) correspond
 // to the obvious Go types.
 //
+// An exception to the above rules is if a type implements the
+// encoding.TextUnmarshaler interface. In this case, any primitive TOML value
+// (floats, strings, integers, booleans and datetimes) will be converted to
+// a byte string and given to the value's UnmarshalText method. Here's an
+// example for parsing durations:
+//
+//	type duration struct {
+//		time.Duration
+//	}
+//
+//	func (d *duration) UnmarshalText(text []byte) error {
+//		var err error
+//		d.Duration, err = time.ParseDuration(string(text))
+//		return err
+//	}
+//
+//	func ExampleUnmarshaler() {
+//		blob := `
+//	[[song]]
+//	name = "Thunder Road"
+//	duration = "4m49s"
+//
+//	[[song]]
+//	name = "Stairway to Heaven"
+//	duration = "8m03s"
+//	`
+//		type song struct {
+//			Name     string
+//			Duration duration
+//		}
+//		type songs struct {
+//			Song []song
+//		}
+//		var favorites songs
+//		if _, err := Decode(blob, &favorites); err != nil {
+//			log.Fatal(err)
+//		}
+//
+//		for _, s := range favorites.Song {
+//			fmt.Printf("%s (%s)\n", s.Name, s.Duration)
+//		}
+//		// Output:
+//		// Thunder Road (4m49s)
+//		// Stairway to Heaven (8m3s)
+//	}
+//
+// Key mapping
+//
 // TOML keys can map to either keys in a Go map or field names in a Go
 // struct. The special `toml` struct tag may be used to map TOML keys to
 // struct fields that don't match the key name exactly. (See the example.)
@@ -100,11 +152,17 @@ func unify(data interface{}, rv reflect.Value) error {
 		return unifyAnything(data, rv)
 	}
 
-	// Special case. Go's `time.Time` is a struct, which we don't want
-	// to confuse with a user struct.
-	if rv.Type().AssignableTo(rvalue(time.Time{}).Type()) {
-		return unifyDatetime(data, rv)
+	// Special case. Look for a value satisfying the TextUnmarshaler interface.
+	if v, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
+		return unifyText(data, v)
 	}
+	// BUG(burntsushi)
+	// The behavior here is incorrect whenever a Go type satisfies the
+	// encoding.TextUnmarshaler interface but also corresponds to a TOML
+	// hash or array. In particular, the unmarshaler should only be applied
+	// to primitive TOML values. But at this point, it will be applied to
+	// all kinds of values and produce an incorrect error whenever those values
+	// are hashes or arrays (including arrays of tables).
 
 	k := rv.Kind()
 
@@ -151,29 +209,41 @@ func unifyStruct(mapping interface{}, rv reflect.Value) error {
 		return mismatch(rv, "map", mapping)
 	}
 
-	rt := rv.Type()
-	for i := 0; i < rt.NumField(); i++ {
-		// A little tricky. We want to use the special `toml` name in the
-		// struct tag if it exists. In particular, we need to make sure that
-		// this struct field is in the current map before trying to unify it.
-		sft := rt.Field(i)
-		kname := sft.Tag.Get("toml")
-		if len(kname) == 0 {
-			kname = sft.Name
+	for key, datum := range tmap {
+		var f *field
+		fields := cachedTypeFields(rv.Type())
+		for i := range fields {
+			ff := &fields[i]
+			if ff.name == key {
+				f = ff
+				break
+			}
+			if f == nil && strings.EqualFold(ff.name, key) {
+				f = ff
+			}
 		}
-		if datum, ok := insensitiveGet(tmap, kname); ok {
-			sf := indirect(rv.Field(i))
+		if f != nil {
+			subv := rv
+			for _, i := range f.index {
+				if subv.Kind() == reflect.Ptr {
+					if subv.IsNil() {
+						subv.Set(reflect.New(subv.Type().Elem()))
+					}
+					subv = subv.Elem()
+				}
+				subv = subv.Field(i)
+			}
+			sf := indirect(subv)
 
-			// Don't try to mess with unexported types and other such things.
-			if sf.CanSet() {
+			if isUnifiable(sf) {
 				if err := unify(datum, sf); err != nil {
 					return e("Type mismatch for '%s.%s': %s",
-						rt.String(), sft.Name, err)
+						rv.Type().String(), f.name, err)
 				}
-			} else if len(sft.Tag.Get("toml")) > 0 {
+			} else if f.name != "" {
 				// Bad user! No soup for you!
 				return e("Field '%s.%s' is unexported, and therefore cannot "+
-					"be loaded with reflection.", rt.String(), sft.Name)
+					"be loaded with reflection.", rv.Type().String(), f.name)
 			}
 		}
 	}
@@ -287,7 +357,7 @@ func unifyBool(data interface{}, rv reflect.Value) error {
 		rv.SetBool(b)
 		return nil
 	}
-	return badtype("integer", data)
+	return badtype("boolean", data)
 }
 
 func unifyAnything(data interface{}, rv reflect.Value) error {
@@ -296,6 +366,34 @@ func unifyAnything(data interface{}, rv reflect.Value) error {
 	return nil
 }
 
+func unifyText(data interface{}, v encoding.TextUnmarshaler) error {
+	var s string
+	switch sdata := data.(type) {
+	case encoding.TextMarshaler:
+		text, err := sdata.MarshalText()
+		if err != nil {
+			return err
+		}
+		s = string(text)
+	case fmt.Stringer:
+		s = sdata.String()
+	case string:
+		s = sdata
+	case bool:
+		s = fmt.Sprintf("%v", sdata)
+	case int64:
+		s = fmt.Sprintf("%d", sdata)
+	case float64:
+		s = fmt.Sprintf("%f", sdata)
+	default:
+		return badtype("primitive (string-like)", data)
+	}
+	if err := v.UnmarshalText([]byte(s)); err != nil {
+		return err
+	}
+	return nil
+}
+
 // rvalue returns a reflect.Value of `v`. All pointers are resolved.
 func rvalue(v interface{}) reflect.Value {
 	return indirect(reflect.ValueOf(v))
@@ -304,8 +402,17 @@ func rvalue(v interface{}) reflect.Value {
 // indirect returns the value pointed to by a pointer.
 // Pointers are followed until the value is not a pointer.
 // New values are allocated for each nil pointer.
+//
+// An exception to this rule is if the value satisfies an interface of
+// interest to us (like encoding.TextUnmarshaler).
 func indirect(v reflect.Value) reflect.Value {
 	if v.Kind() != reflect.Ptr {
+		if v.CanAddr() {
+			pv := v.Addr()
+			if _, ok := pv.Interface().(encoding.TextUnmarshaler); ok {
+				return pv
+			}
+		}
 		return v
 	}
 	if v.IsNil() {
@@ -314,6 +421,16 @@ func indirect(v reflect.Value) reflect.Value {
 	return indirect(reflect.Indirect(v))
 }
 
+func isUnifiable(rv reflect.Value) bool {
+	if rv.CanSet() {
+		return true
+	}
+	if _, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
+		return true
+	}
+	return false
+}
+
 func tstring(rv reflect.Value) string {
 	return rv.Type().String()
 }
@@ -344,8 +461,6 @@ func insensitiveGet(
 // MetaData allows access to meta information about TOML data that may not
 // be inferrable via reflection. In particular, whether a key has been defined
 // and the TOML type of a key.
-//
-// (XXX: If TOML gets NULL values, that information will be added here too.)
 type MetaData struct {
 	mapping map[string]interface{}
 	types   map[string]tomlType

+ 91 - 6
third_party/github.com/BurntSushi/toml/decode_test.go

@@ -1,6 +1,7 @@
 package toml
 
 import (
+	"encoding/json"
 	"fmt"
 	"log"
 	"reflect"
@@ -63,6 +64,53 @@ func TestDecode(t *testing.T) {
 	testf("%v\n", val)
 }
 
+func TestDecodeEmbedded(t *testing.T) {
+	type Dog struct{ Name string }
+
+	tests := map[string]struct {
+		input       string
+		decodeInto  interface{}
+		wantDecoded interface{}
+	}{
+		"embedded struct": {
+			input:       `Name = "milton"`,
+			decodeInto:  &struct{ Dog }{},
+			wantDecoded: &struct{ Dog }{Dog{"milton"}},
+		},
+		"embedded non-nil pointer to struct": {
+			input:       `Name = "milton"`,
+			decodeInto:  &struct{ *Dog }{},
+			wantDecoded: &struct{ *Dog }{&Dog{"milton"}},
+		},
+		"embedded nil pointer to struct": {
+			input:       ``,
+			decodeInto:  &struct{ *Dog }{},
+			wantDecoded: &struct{ *Dog }{nil},
+		},
+	}
+
+	for label, test := range tests {
+		_, err := Decode(test.input, test.decodeInto)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		want, got := jsonstr(test.wantDecoded), jsonstr(test.decodeInto)
+		if want != got {
+			t.Errorf("%s: want decoded == %+v, got %+v", label, want, got)
+		}
+	}
+}
+
+// jsonstr allows comparison of deeply nested structs with pointer members.
+func jsonstr(o interface{}) string {
+	s, err := json.MarshalIndent(o, "", "  ")
+	if err != nil {
+		panic(err.Error())
+	}
+	return string(s)
+}
+
 var tomlTableArrays = `
 [[albums]]
 name = "Born to Run"
@@ -124,8 +172,6 @@ tOpdate = 2006-01-02T15:04:05Z
 tOparray = [ "array" ]
 Match = "i should be in Match only"
 MatcH = "i should be in MatcH only"
-Field = "neat"
-FielD = "messy"
 once = "just once"
 [nEst.eD]
 nEstedString = "another string"
@@ -140,7 +186,6 @@ type Insensitive struct {
 	TopArray  []string
 	Match     string
 	MatcH     string
-	Field     string
 	Once      string
 	OncE      string
 	Nest      InsensitiveNest
@@ -168,9 +213,8 @@ func TestCase(t *testing.T) {
 		TopArray:  []string{"array"},
 		MatcH:     "i should be in MatcH only",
 		Match:     "i should be in Match only",
-		Field:     "neat", // encoding/json would store "messy" here
 		Once:      "just once",
-		OncE:      "just once", // wait, what?
+		OncE:      "",
 		Nest: InsensitiveNest{
 			Ed: InsensitiveEd{NestedString: "another string"},
 		},
@@ -335,9 +379,50 @@ ip = "10.0.0.2"
 		fmt.Printf("Ports: %v\n", s.Config.Ports)
 	}
 
-	// // Output:
+	// Output:
 	// Server: alpha (ip: 10.0.0.1) in Toronto created on 1987-07-05
 	// Ports: [8001 8002]
 	// Server: beta (ip: 10.0.0.2) in New Jersey created on 1887-01-05
 	// Ports: [9001 9002]
 }
+
+type duration struct {
+	time.Duration
+}
+
+func (d *duration) UnmarshalText(text []byte) error {
+	var err error
+	d.Duration, err = time.ParseDuration(string(text))
+	return err
+}
+
+// Example Unmarshaler blah blah.
+func ExampleUnmarshaler() {
+	blob := `
+[[song]]
+name = "Thunder Road"
+duration = "4m49s"
+
+[[song]]
+name = "Stairway to Heaven"
+duration = "8m03s"
+`
+	type song struct {
+		Name     string
+		Duration duration
+	}
+	type songs struct {
+		Song []song
+	}
+	var favorites songs
+	if _, err := Decode(blob, &favorites); err != nil {
+		log.Fatal(err)
+	}
+
+	for _, s := range favorites.Song {
+		fmt.Printf("%s (%s)\n", s.Name, s.Duration)
+	}
+	// Output:
+	// Thunder Road (4m49s)
+	// Stairway to Heaven (8m3s)
+}

+ 460 - 29
third_party/github.com/BurntSushi/toml/encode.go

@@ -15,27 +15,41 @@ package toml
 
 import (
 	"bufio"
+	"encoding"
+	"errors"
 	"fmt"
 	"io"
 	"reflect"
+	"sort"
+	"strconv"
 	"strings"
 )
 
-type encoder struct {
+var (
+	ErrArrayMixedElementTypes = errors.New(
+		"can't encode array with mixed element types")
+	ErrArrayNilElement = errors.New(
+		"can't encode array with nil element")
+)
+
+type Encoder struct {
 	// A single indentation level. By default it is two spaces.
 	Indent string
 
 	w *bufio.Writer
+
+	// hasWritten is whether we have written any output to w yet.
+	hasWritten bool
 }
 
-func newEncoder(w io.Writer) *encoder {
-	return &encoder{
+func NewEncoder(w io.Writer) *Encoder {
+	return &Encoder{
 		w:      bufio.NewWriter(w),
 		Indent: "  ",
 	}
 }
 
-func (enc *encoder) Encode(v interface{}) error {
+func (enc *Encoder) Encode(v interface{}) error {
 	rv := eindirect(reflect.ValueOf(v))
 	if err := enc.encode(Key([]string{}), rv); err != nil {
 		return err
@@ -43,49 +57,466 @@ func (enc *encoder) Encode(v interface{}) error {
 	return enc.w.Flush()
 }
 
-func (enc *encoder) encode(key Key, rv reflect.Value) error {
+func (enc *Encoder) encode(key Key, rv reflect.Value) error {
+	// Special case. If we can marshal the type to text, then we used that.
+	if _, ok := rv.Interface().(encoding.TextMarshaler); ok {
+		err := enc.eKeyEq(key)
+		if err != nil {
+			return err
+		}
+		return enc.eElement(rv)
+	}
+
 	k := rv.Kind()
 	switch k {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
+		reflect.Uint64,
+		reflect.Float32, reflect.Float64,
+		reflect.String, reflect.Bool:
+		err := enc.eKeyEq(key)
+		if err != nil {
+			return err
+		}
+		return enc.eElement(rv)
+	case reflect.Array, reflect.Slice:
+		return enc.eArrayOrSlice(key, rv)
+	case reflect.Interface:
+		if rv.IsNil() {
+			return nil
+		}
+		return enc.encode(key, rv.Elem())
+	case reflect.Map:
+		if rv.IsNil() {
+			return nil
+		}
+		return enc.eTable(key, rv)
+	case reflect.Ptr:
+		if rv.IsNil() {
+			return nil
+		}
+		return enc.encode(key, rv.Elem())
 	case reflect.Struct:
-		return enc.eStruct(key, rv)
-	case reflect.String:
-		return enc.eString(key, rv)
+		return enc.eTable(key, rv)
 	}
 	return e("Unsupported type for key '%s': %s", key, k)
 }
 
-func (enc *encoder) eStruct(key Key, rv reflect.Value) error {
-	rt := rv.Type()
-	for i := 0; i < rt.NumField(); i++ {
-		sft := rt.Field(i)
-		sf := rv.Field(i)
-		if err := enc.encode(key.add(sft.Name), sf); err != nil {
+// eElement encodes any value that can be an array element (primitives and
+// arrays).
+func (enc *Encoder) eElement(rv reflect.Value) error {
+	ws := func(s string) error {
+		_, err := io.WriteString(enc.w, s)
+		return err
+	}
+	// By the TOML spec, all floats must have a decimal with at least one
+	// number on either side.
+	floatAddDecimal := func(fstr string) string {
+		if !strings.Contains(fstr, ".") {
+			return fstr + ".0"
+		}
+		return fstr
+	}
+
+	// Special case. Use text marshaler if it's available for this value.
+	if v, ok := rv.Interface().(encoding.TextMarshaler); ok {
+		s, err := v.MarshalText()
+		if err != nil {
+			return err
+		}
+		return ws(string(s))
+	}
+
+	var err error
+	k := rv.Kind()
+	switch k {
+	case reflect.Bool:
+		err = ws(strconv.FormatBool(rv.Bool()))
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		err = ws(strconv.FormatInt(rv.Int(), 10))
+	case reflect.Uint, reflect.Uint8, reflect.Uint16,
+		reflect.Uint32, reflect.Uint64:
+		err = ws(strconv.FormatUint(rv.Uint(), 10))
+	case reflect.Float32:
+		err = ws(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 32)))
+	case reflect.Float64:
+		err = ws(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 64)))
+	case reflect.Array, reflect.Slice:
+		return enc.eArrayOrSliceElement(rv)
+	case reflect.Interface:
+		return enc.eElement(rv.Elem())
+	case reflect.String:
+		s := rv.String()
+		s = strings.NewReplacer(
+			"\t", "\\t",
+			"\n", "\\n",
+			"\r", "\\r",
+			"\"", "\\\"",
+			"\\", "\\\\",
+		).Replace(s)
+		err = ws("\"" + s + "\"")
+	default:
+		return e("Unexpected primitive type: %s", k)
+	}
+	return err
+}
+
+func (enc *Encoder) eArrayOrSlice(key Key, rv reflect.Value) error {
+	// Determine whether this is an array of tables or of primitives.
+	elemV := reflect.ValueOf(nil)
+	if rv.Len() > 0 {
+		elemV = rv.Index(0)
+	}
+	isTableType, err := isTOMLTableType(rv.Type().Elem(), elemV)
+	if err != nil {
+		return err
+	}
+
+	if len(key) > 0 && isTableType {
+		return enc.eArrayOfTables(key, rv)
+	}
+
+	err = enc.eKeyEq(key)
+	if err != nil {
+		return err
+	}
+	return enc.eArrayOrSliceElement(rv)
+}
+
+func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) error {
+	if _, err := enc.w.Write([]byte{'['}); err != nil {
+		return err
+	}
+
+	length := rv.Len()
+	if length > 0 {
+		arrayElemType, isNil := tomlTypeName(rv.Index(0))
+		if isNil {
+			return ErrArrayNilElement
+		}
+
+		for i := 0; i < length; i++ {
+			elem := rv.Index(i)
+
+			// Ensure that the array's elements each have the same TOML type.
+			elemType, isNil := tomlTypeName(elem)
+			if isNil {
+				return ErrArrayNilElement
+			}
+			if elemType != arrayElemType {
+				return ErrArrayMixedElementTypes
+			}
+
+			if err := enc.eElement(elem); err != nil {
+				return err
+			}
+			if i != length-1 {
+				if _, err := enc.w.Write([]byte(", ")); err != nil {
+					return err
+				}
+			}
+		}
+	}
+
+	if _, err := enc.w.Write([]byte{']'}); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) error {
+	if enc.hasWritten {
+		_, err := enc.w.Write([]byte{'\n'})
+		if err != nil {
 			return err
 		}
 	}
+
+	for i := 0; i < rv.Len(); i++ {
+		trv := rv.Index(i)
+		if isNil(trv) {
+			continue
+		}
+
+		_, err := fmt.Fprintf(enc.w, "%s[[%s]]\n",
+			strings.Repeat(enc.Indent, len(key)-1), key.String())
+		if err != nil {
+			return err
+		}
+
+		err = enc.eMapOrStruct(key, trv)
+		if err != nil {
+			return err
+		}
+
+		if i != rv.Len()-1 {
+			if _, err := enc.w.Write([]byte("\n\n")); err != nil {
+				return err
+			}
+		}
+		enc.hasWritten = true
+	}
 	return nil
 }
 
-func (enc *encoder) eString(key Key, rv reflect.Value) error {
-	s := rv.String()
-	s = strings.NewReplacer(
-		"\t", "\\t",
-		"\n", "\\n",
-		"\r", "\\r",
-		"\"", "\\\"",
-		"\\", "\\\\",
-	).Replace(s)
-	s = "\"" + s + "\""
-	if err := enc.eKeyVal(key, s); err != nil {
+func isStructOrMap(rv reflect.Value) bool {
+	switch rv.Kind() {
+	case reflect.Interface, reflect.Ptr:
+		return isStructOrMap(rv.Elem())
+	case reflect.Map, reflect.Struct:
+		return true
+	default:
+		return false
+	}
+}
+
+func (enc *Encoder) eTable(key Key, rv reflect.Value) error {
+	if enc.hasWritten {
+		_, err := enc.w.Write([]byte{'\n'})
+		if err != nil {
+			return err
+		}
+	}
+	if len(key) > 0 {
+		_, err := fmt.Fprintf(enc.w, "%s[%s]\n",
+			strings.Repeat(enc.Indent, len(key)-1), key.String())
+		if err != nil {
+			return err
+		}
+	}
+	return enc.eMapOrStruct(key, rv)
+}
+
+func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value) error {
+	switch rv.Kind() {
+	case reflect.Map:
+		return enc.eMap(key, rv)
+	case reflect.Struct:
+		return enc.eStruct(key, rv)
+	case reflect.Ptr, reflect.Interface:
+		return enc.eMapOrStruct(key, rv.Elem())
+	default:
+		panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String())
+	}
+}
+
+func (enc *Encoder) eMap(key Key, rv reflect.Value) error {
+	rt := rv.Type()
+	if rt.Key().Kind() != reflect.String {
+		return errors.New("can't encode a map with non-string key type")
+	}
+
+	// Sort keys so that we have deterministic output. And write keys directly
+	// underneath this key first, before writing sub-structs or sub-maps.
+	var mapKeysDirect, mapKeysSub []string
+	for _, mapKey := range rv.MapKeys() {
+		k := mapKey.String()
+		mrv := rv.MapIndex(mapKey)
+		if isStructOrMap(mrv) {
+			mapKeysSub = append(mapKeysSub, k)
+		} else {
+			mapKeysDirect = append(mapKeysDirect, k)
+		}
+	}
+
+	var writeMapKeys = func(mapKeys []string) error {
+		sort.Strings(mapKeys)
+		for i, mapKey := range mapKeys {
+			mrv := rv.MapIndex(reflect.ValueOf(mapKey))
+			if isNil(mrv) {
+				// Don't write anything for nil fields.
+				continue
+			}
+			if err := enc.encode(key.add(mapKey), mrv); err != nil {
+				return err
+			}
+
+			if i != len(mapKeys)-1 {
+				if _, err := enc.w.Write([]byte{'\n'}); err != nil {
+					return err
+				}
+			}
+			enc.hasWritten = true
+		}
+
+		return nil
+	}
+
+	err := writeMapKeys(mapKeysDirect)
+	if err != nil {
+		return err
+	}
+	err = writeMapKeys(mapKeysSub)
+	if err != nil {
 		return err
 	}
 	return nil
 }
 
-func (enc *encoder) eKeyVal(key Key, value string) error {
-	out := fmt.Sprintf("%s%s = %s",
-		strings.Repeat(enc.Indent, len(key)-1), key[len(key)-1], value)
-	if _, err := fmt.Fprintln(enc.w, out); err != nil {
+func (enc *Encoder) eStruct(key Key, rv reflect.Value) error {
+	// Write keys for fields directly under this key first, because if we write
+	// a field that creates a new table, then all keys under it will be in that
+	// table (not the one we're writing here).
+	rt := rv.Type()
+	var fieldsDirect, fieldsSub [][]int
+	var addFields func(rt reflect.Type, rv reflect.Value, start []int)
+	addFields = func(rt reflect.Type, rv reflect.Value, start []int) {
+		for i := 0; i < rt.NumField(); i++ {
+			f := rt.Field(i)
+			frv := rv.Field(i)
+			if f.Anonymous {
+				t := frv.Type()
+				if t.Kind() == reflect.Ptr {
+					t = t.Elem()
+					frv = frv.Elem()
+				}
+				addFields(t, frv, f.Index)
+			} else if isStructOrMap(frv) {
+				fieldsSub = append(fieldsSub, append(start, f.Index...))
+			} else {
+				fieldsDirect = append(fieldsDirect, append(start, f.Index...))
+			}
+		}
+	}
+	addFields(rt, rv, nil)
+
+	var writeFields = func(fields [][]int) error {
+		for i, fieldIndex := range fields {
+			sft := rt.FieldByIndex(fieldIndex)
+			sf := rv.FieldByIndex(fieldIndex)
+			if isNil(sf) {
+				// Don't write anything for nil fields.
+				continue
+			}
+
+			keyName := sft.Tag.Get("toml")
+			if keyName == "-" {
+				continue
+			}
+			if keyName == "" {
+				keyName = sft.Name
+			}
+
+			if err := enc.encode(key.add(keyName), sf); err != nil {
+				return err
+			}
+
+			if i != len(fields)-1 {
+				if _, err := enc.w.Write([]byte{'\n'}); err != nil {
+					return err
+				}
+			}
+			enc.hasWritten = true
+		}
+		return nil
+	}
+
+	err := writeFields(fieldsDirect)
+	if err != nil {
+		return err
+	}
+	if len(fieldsDirect) > 0 && len(fieldsSub) > 0 {
+		_, err = enc.w.Write([]byte{'\n'})
+		if err != nil {
+			return err
+		}
+	}
+	err = writeFields(fieldsSub)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// tomlTypeName returns the TOML type name of the Go value's type. It is used to
+// determine whether the types of array elements are mixed (which is forbidden).
+// If the Go value is nil, then it is illegal for it to be an array element, and
+// valueIsNil is returned as true.
+func tomlTypeName(rv reflect.Value) (typeName string, valueIsNil bool) {
+	if isNil(rv) {
+		return "", true
+	}
+	k := rv.Kind()
+	switch k {
+	case reflect.Bool:
+		return "bool", false
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
+		reflect.Uint64:
+		return "integer", false
+	case reflect.Float32, reflect.Float64:
+		return "float", false
+	case reflect.Array, reflect.Slice:
+		return "array", false
+	case reflect.Ptr, reflect.Interface:
+		return tomlTypeName(rv.Elem())
+	case reflect.String:
+		return "string", false
+	case reflect.Map, reflect.Struct:
+		return "table", false
+	default:
+		panic("unexpected reflect.Kind: " + k.String())
+	}
+}
+
+// isTOMLTableType returns whether this type and value represents a TOML table
+// type (true) or element type (false). Both rt and rv are needed to determine
+// this, in case the Go type is interface{} or in case rv is nil. If there is
+// some other impossible situation detected, an error is returned.
+func isTOMLTableType(rt reflect.Type, rv reflect.Value) (bool, error) {
+	k := rt.Kind()
+	switch k {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
+		reflect.Uint64,
+		reflect.Float32, reflect.Float64,
+		reflect.String, reflect.Bool:
+		return false, nil
+	case reflect.Array, reflect.Slice:
+		// Make sure that these eventually contain an underlying non-table type
+		// element.
+		elemV := reflect.ValueOf(nil)
+		if rv.Len() > 0 {
+			elemV = rv.Index(0)
+		}
+		hasUnderlyingTableType, err := isTOMLTableType(rt.Elem(), elemV)
+		if err != nil {
+			return false, err
+		}
+		if hasUnderlyingTableType {
+			return true, errors.New("TOML array element can't contain a table")
+		}
+		return false, nil
+	case reflect.Ptr:
+		return isTOMLTableType(rt.Elem(), rv.Elem())
+	case reflect.Interface:
+		if rv.Kind() == reflect.Interface {
+			return false, nil
+		}
+		return isTOMLTableType(rv.Type(), rv)
+	case reflect.Map, reflect.Struct:
+		return true, nil
+	default:
+		panic("unexpected reflect.Kind: " + k.String())
+	}
+}
+
+func isNil(rv reflect.Value) bool {
+	switch rv.Kind() {
+	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return rv.IsNil()
+	default:
+		return false
+	}
+}
+
+func (enc *Encoder) eKeyEq(key Key) error {
+	_, err := io.WriteString(enc.w, strings.Repeat(enc.Indent, len(key)-1))
+	if err != nil {
+		return err
+	}
+	_, err = io.WriteString(enc.w, key[len(key)-1]+" = ")
+	if err != nil {
 		return err
 	}
 	return nil

+ 271 - 14
third_party/github.com/BurntSushi/toml/encode_test.go

@@ -5,21 +5,278 @@ import (
 	"testing"
 )
 
-type encodeSimple struct {
-	Location string
-	// Ages []int
-	// DOB time.Time
-}
-
+// XXX(burntsushi)
+// I think these tests probably should be removed. They are good, but they
+// ought to be obsolete by toml-test.
 func TestEncode(t *testing.T) {
-	v := encodeSimple{
-		Location: "Westborough, MA",
+	tests := map[string]struct {
+		input      interface{}
+		wantOutput string
+		wantError  error
+	}{
+		"bool field": {
+			input: struct {
+				BoolTrue  bool
+				BoolFalse bool
+			}{true, false},
+			wantOutput: "BoolTrue = true\nBoolFalse = false",
+		},
+		"int fields": {
+			input: struct {
+				Int   int
+				Int8  int8
+				Int16 int16
+				Int32 int32
+				Int64 int64
+			}{1, 2, 3, 4, 5},
+			wantOutput: "Int = 1\nInt8 = 2\nInt16 = 3\nInt32 = 4\nInt64 = 5",
+		},
+		"uint fields": {
+			input: struct {
+				Uint   uint
+				Uint8  uint8
+				Uint16 uint16
+				Uint32 uint32
+				Uint64 uint64
+			}{1, 2, 3, 4, 5},
+			wantOutput: "Uint = 1\nUint8 = 2\nUint16 = 3\nUint32 = 4" +
+				"\nUint64 = 5",
+		},
+		"float fields": {
+			input: struct {
+				Float32 float32
+				Float64 float64
+			}{1.5, 2.5},
+			wantOutput: "Float32 = 1.5\nFloat64 = 2.5",
+		},
+		"string field": {
+			input:      struct{ String string }{"foo"},
+			wantOutput: `String = "foo"`,
+		},
+		"array fields": {
+			input: struct {
+				IntArray0 [0]int
+				IntArray3 [3]int
+			}{[0]int{}, [3]int{1, 2, 3}},
+			wantOutput: "IntArray0 = []\nIntArray3 = [1, 2, 3]",
+		},
+		"slice fields": {
+			input: struct{ IntSliceNil, IntSlice0, IntSlice3 []int }{
+				nil, []int{}, []int{1, 2, 3},
+			},
+			wantOutput: "IntSlice0 = []\nIntSlice3 = [1, 2, 3]",
+		},
+		"nested arrays and slices": {
+			input: struct {
+				SliceOfArrays         [][2]int
+				ArrayOfSlices         [2][]int
+				SliceOfArraysOfSlices [][2][]int
+				ArrayOfSlicesOfArrays [2][][2]int
+				SliceOfMixedArrays    [][2]interface{}
+				ArrayOfMixedSlices    [2][]interface{}
+			}{
+				[][2]int{[2]int{1, 2}, [2]int{3, 4}},
+				[2][]int{[]int{1, 2}, []int{3, 4}},
+				[][2][]int{
+					[2][]int{
+						[]int{1, 2}, []int{3, 4},
+					},
+					[2][]int{
+						[]int{5, 6}, []int{7, 8},
+					},
+				},
+				[2][][2]int{
+					[][2]int{
+						[2]int{1, 2}, [2]int{3, 4},
+					},
+					[][2]int{
+						[2]int{5, 6}, [2]int{7, 8},
+					},
+				},
+				[][2]interface{}{
+					[2]interface{}{1, 2}, [2]interface{}{"a", "b"},
+				},
+				[2][]interface{}{
+					[]interface{}{1, 2}, []interface{}{"a", "b"},
+				},
+			},
+			wantOutput: `SliceOfArrays = [[1, 2], [3, 4]]
+ArrayOfSlices = [[1, 2], [3, 4]]
+SliceOfArraysOfSlices = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
+ArrayOfSlicesOfArrays = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
+SliceOfMixedArrays = [[1, 2], ["a", "b"]]
+ArrayOfMixedSlices = [[1, 2], ["a", "b"]]`,
+		},
+		"(error) slice with element type mismatch (string and integer)": {
+			input:     struct{ Mixed []interface{} }{[]interface{}{1, "a"}},
+			wantError: ErrArrayMixedElementTypes,
+		},
+		"(error) slice with element type mismatch (integer and float)": {
+			input:     struct{ Mixed []interface{} }{[]interface{}{1, 2.5}},
+			wantError: ErrArrayMixedElementTypes,
+		},
+		"slice with elems of differing Go types, same TOML types": {
+			input: struct {
+				MixedInts   []interface{}
+				MixedFloats []interface{}
+			}{
+				[]interface{}{
+					int(1), int8(2), int16(3), int32(4), int64(5),
+					uint(1), uint8(2), uint16(3), uint32(4), uint64(5),
+				},
+				[]interface{}{float32(1.5), float64(2.5)},
+			},
+			wantOutput: "MixedInts = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]\n" +
+				"MixedFloats = [1.5, 2.5]",
+		},
+		"(error) slice w/ element type mismatch (one is nested array)": {
+			input: struct{ Mixed []interface{} }{
+				[]interface{}{1, []interface{}{2}},
+			},
+			wantError: ErrArrayMixedElementTypes,
+		},
+		"(error) slice with 1 nil element": {
+			input:     struct{ NilElement1 []interface{} }{[]interface{}{nil}},
+			wantError: ErrArrayNilElement,
+		},
+		"(error) slice with 1 nil element (and other non-nil elements)": {
+			input: struct{ NilElement []interface{} }{
+				[]interface{}{1, nil},
+			},
+			wantError: ErrArrayNilElement,
+		},
+		"simple map": {
+			input:      map[string]int{"a": 1, "b": 2},
+			wantOutput: "a = 1\nb = 2",
+		},
+		"map with interface{} value type": {
+			input:      map[string]interface{}{"a": 1, "b": "c"},
+			wantOutput: "a = 1\nb = \"c\"",
+		},
+		"map with interface{} value type, some of which are structs": {
+			input: map[string]interface{}{
+				"a": struct{ Int int }{2},
+				"b": 1,
+			},
+			wantOutput: "b = 1\n[a]\n  Int = 2",
+		},
+		"nested map": {
+			input: map[string]map[string]int{
+				"a": map[string]int{"b": 1},
+				"c": map[string]int{"d": 2},
+			},
+			wantOutput: "[a]\n  b = 1\n\n[c]\n  d = 2",
+		},
+		"nested struct": {
+			input: struct{ Struct struct{ Int int } }{
+				struct{ Int int }{1},
+			},
+			wantOutput: "[Struct]\n  Int = 1",
+		},
+		"nested struct and non-struct field": {
+			input: struct {
+				Struct struct{ Int int }
+				Bool   bool
+			}{struct{ Int int }{1}, true},
+			wantOutput: "Bool = true\n\n[Struct]\n  Int = 1",
+		},
+		"2 nested structs": {
+			input: struct{ Struct1, Struct2 struct{ Int int } }{
+				struct{ Int int }{1}, struct{ Int int }{2},
+			},
+			wantOutput: "[Struct1]\n  Int = 1\n\n[Struct2]\n  Int = 2",
+		},
+		"deeply nested structs": {
+			input: struct {
+				Struct1, Struct2 struct{ Struct3 *struct{ Int int } }
+			}{
+				struct{ Struct3 *struct{ Int int } }{&struct{ Int int }{1}},
+				struct{ Struct3 *struct{ Int int } }{nil},
+			},
+			wantOutput: "[Struct1]\n  [Struct1.Struct3]\n    Int = 1" +
+				"\n\n[Struct2]\n",
+		},
+		"nested struct with nil struct elem": {
+			input: struct {
+				Struct struct{ Inner *struct{ Int int } }
+			}{
+				struct{ Inner *struct{ Int int } }{nil},
+			},
+			wantOutput: "[Struct]\n",
+		},
+		"nested struct with no fields": {
+			input: struct {
+				Struct struct{ Inner struct{} }
+			}{
+				struct{ Inner struct{} }{struct{}{}},
+			},
+			wantOutput: "[Struct]\n  [Struct.Inner]\n",
+		},
+		"struct with tags": {
+			input: struct {
+				Struct struct {
+					Int int `toml:"_int"`
+				} `toml:"_struct"`
+				Bool bool `toml:"_bool"`
+			}{
+				struct {
+					Int int `toml:"_int"`
+				}{1}, true,
+			},
+			wantOutput: "_bool = true\n\n[_struct]\n  _int = 1",
+		},
+		"embedded struct": {
+			input:      struct{ Embedded }{Embedded{1}},
+			wantOutput: "_int = 1",
+		},
+		"embedded *struct": {
+			input:      struct{ *Embedded }{&Embedded{1}},
+			wantOutput: "_int = 1",
+		},
+		"nested embedded struct": {
+			input: struct {
+				Struct struct{ Embedded } `toml:"_struct"`
+			}{struct{ Embedded }{Embedded{1}}},
+			wantOutput: "[_struct]\n  _int = 1",
+		},
+		"nested embedded *struct": {
+			input: struct {
+				Struct struct{ *Embedded } `toml:"_struct"`
+			}{struct{ *Embedded }{&Embedded{1}}},
+			wantOutput: "[_struct]\n  _int = 1",
+		},
+		"array of tables": {
+			input: struct {
+				Structs []*struct{ Int int } `toml:"struct"`
+			}{
+				[]*struct{ Int int }{
+					{1}, nil, {3},
+				},
+			},
+			wantOutput: "[[struct]]\n  Int = 1\n\n[[struct]]\n  Int = 3",
+		},
 	}
-
-	buf := new(bytes.Buffer)
-	e := newEncoder(buf)
-	if err := e.Encode(v); err != nil {
-		t.Fatal(err)
+	for label, test := range tests {
+		var buf bytes.Buffer
+		e := NewEncoder(&buf)
+		err := e.Encode(test.input)
+		if err != test.wantError {
+			if test.wantError != nil {
+				t.Errorf("%s: want Encode error %v, got %v",
+					label, test.wantError, err)
+			} else {
+				t.Errorf("%s: Encode failed: %s", label, err)
+			}
+		}
+		if err != nil {
+			continue
+		}
+		if got := buf.String(); test.wantOutput != got {
+			t.Errorf("%s: want %q, got %q", label, test.wantOutput, got)
+		}
 	}
-	testf(buf.String())
+}
+
+type Embedded struct {
+	Int int `toml:"_int"`
 }

+ 36 - 7
third_party/github.com/BurntSushi/toml/parse.go

@@ -159,6 +159,8 @@ func (p *parser) value(it item) (interface{}, tomlType) {
 	case itemInteger:
 		num, err := strconv.ParseInt(it.val, 10, 64)
 		if err != nil {
+			// See comment below for floats describing why we make a
+			// distinction between a bug and a user error.
 			if e, ok := err.(*strconv.NumError); ok &&
 				e.Err == strconv.ErrRange {
 
@@ -172,6 +174,13 @@ func (p *parser) value(it item) (interface{}, tomlType) {
 	case itemFloat:
 		num, err := strconv.ParseFloat(it.val, 64)
 		if err != nil {
+			// Distinguish float values. Normally, it'd be a bug if the lexer
+			// provides an invalid float, but it's possible that the float is
+			// out of range of valid values (which the lexer cannot determine).
+			// So mark the former as a bug but the latter as a legitimate user
+			// error.
+			//
+			// This is also true for integers.
 			if e, ok := err.(*strconv.NumError); ok &&
 				e.Err == strconv.ErrRange {
 
@@ -209,7 +218,8 @@ func (p *parser) value(it item) (interface{}, tomlType) {
 }
 
 // establishContext sets the current context of the parser,
-// where the context is the hash currently in scope.
+// where the context is either a hash or an array of hashes. Which one is
+// set depends on the value of the `array` parameter.
 //
 // Establishing the context also makes sure that the key isn't a duplicate, and
 // will create implicit hashes automatically.
@@ -248,10 +258,15 @@ func (p *parser) establishContext(key Key, array bool) {
 
 	p.context = keyContext
 	if array {
+		// If this is the first element for this array, then allocate a new
+		// list of tables for it.
 		k := key[len(key)-1]
 		if _, ok := hashContext[k]; !ok {
 			hashContext[k] = make([]map[string]interface{}, 0, 5)
 		}
+
+		// Add a new table. But make sure the key hasn't already been used
+		// for something else.
 		if hash, ok := hashContext[k].([]map[string]interface{}); ok {
 			hashContext[k] = append(hash, make(map[string]interface{}))
 		} else {
@@ -280,6 +295,8 @@ func (p *parser) setValue(key string, value interface{}) {
 		}
 		switch t := tmpHash.(type) {
 		case []map[string]interface{}:
+			// The context is a table of hashes. Pick the most recent table
+			// defined as the current hash.
 			hash = t[len(t)-1]
 		case map[string]interface{}:
 			hash = t
@@ -291,9 +308,17 @@ func (p *parser) setValue(key string, value interface{}) {
 	keyContext = append(keyContext, key)
 
 	if _, ok := hash[key]; ok {
-		// We need to do some fancy footwork here. If `hash[key]` was implcitly
-		// created AND `value` is a hash, then let this go through and stop
-		// tagging this table as implicit.
+		// Typically, if the given key has already been set, then we have
+		// to raise an error since duplicate keys are disallowed. However,
+		// it's possible that a key was previously defined implicitly. In this
+		// case, it is allowed to be redefined concretely. (See the
+		// `tests/valid/implicit-and-explicit-after.toml` test in `toml-test`.)
+		//
+		// But we have to make sure to stop marking it as an implicit. (So that
+		// another redefinition provokes an error.)
+		//
+		// Note that since it has already been defined (as a hash), we don't
+		// want to overwrite it. So our business is done.
 		if p.isImplicit(keyContext) {
 			p.removeImplicit(keyContext)
 			return
@@ -308,6 +333,9 @@ func (p *parser) setValue(key string, value interface{}) {
 
 // setType sets the type of a particular value at a given key.
 // It should be called immediately AFTER setValue.
+//
+// Note that if `key` is empty, then the type given will be applied to the
+// current context (which is either a table or an array of tables).
 func (p *parser) setType(key string, typ tomlType) {
 	keyContext := make(Key, 0, len(p.context)+1)
 	for _, k := range p.context {
@@ -377,9 +405,10 @@ func (p *parser) asciiEscapeToUnicode(s string) string {
 			"lexer claims it's OK: %s", s, err)
 	}
 
-	// I honestly don't understand how this works. I can't seem to find
-	// a way to make this fail. I figured this would fail on invalid UTF-8
-	// characters like U+DCFF, but it doesn't.
+	// BUG(burntsushi)
+	// I honestly don't understand how this works. I can't seem
+	// to find a way to make this fail. I figured this would fail on invalid
+	// UTF-8 characters like U+DCFF, but it doesn't.
 	r := string(rune(hex))
 	if !utf8.ValidString(r) {
 		p.panic("Escaped character '\\u%s' is not valid UTF-8.", s)

+ 14 - 0
third_party/github.com/BurntSushi/toml/toml-test-encoder/COPYING

@@ -0,0 +1,14 @@
+            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+                    Version 2, December 2004
+
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. You just DO WHAT THE FUCK YOU WANT TO.
+

+ 14 - 0
third_party/github.com/BurntSushi/toml/toml-test-encoder/README.md

@@ -0,0 +1,14 @@
+# Implements the TOML test suite interface for TOML encoders
+
+This is an implementation of the interface expected by
+[toml-test](https://github.com/BurntSushi/toml-test) for the
+[TOML encoder](https://github.com/BurntSushi/toml).
+In particular, it maps JSON data on `stdin` to a TOML format on `stdout`.
+
+
+Compatible with TOML version
+[v0.2.0](https://github.com/mojombo/toml/blob/master/versions/toml-v0.2.0.md)
+
+Compatible with `toml-test` version
+[v0.2.0](https://github.com/BurntSushi/toml-test/tree/v0.2.0)
+

+ 129 - 0
third_party/github.com/BurntSushi/toml/toml-test-encoder/main.go

@@ -0,0 +1,129 @@
+package main
+
+import (
+	"encoding/json"
+	"flag"
+	"log"
+	"os"
+	"path"
+	"strconv"
+	"time"
+
+	"github.com/BurntSushi/toml"
+)
+
+func init() {
+	log.SetFlags(0)
+
+	flag.Usage = usage
+	flag.Parse()
+}
+
+func usage() {
+	log.Printf("Usage: %s < json-file\n", path.Base(os.Args[0]))
+	flag.PrintDefaults()
+
+	os.Exit(1)
+}
+
+func main() {
+	if flag.NArg() != 0 {
+		flag.Usage()
+	}
+
+	var tmp interface{}
+	if err := json.NewDecoder(os.Stdin).Decode(&tmp); err != nil {
+		log.Fatalf("Error decoding JSON: %s", err)
+	}
+
+	tomlData := translate(tmp)
+	if err := toml.NewEncoder(os.Stdout).Encode(tomlData); err != nil {
+		log.Fatalf("Error encoding TOML: %s", err)
+	}
+}
+
+func translate(typedJson interface{}) interface{} {
+	switch v := typedJson.(type) {
+	case map[string]interface{}:
+		if len(v) == 2 && in("type", v) && in("value", v) {
+			return untag(v)
+		}
+		m := make(map[string]interface{}, len(v))
+		for k, v2 := range v {
+			m[k] = translate(v2)
+		}
+		return m
+	case []interface{}:
+		tabArray := make([]map[string]interface{}, len(v))
+		for i := range v {
+			if m, ok := translate(v[i]).(map[string]interface{}); ok {
+				tabArray[i] = m
+			} else {
+				log.Fatalf("JSON arrays may only contain objects. This "+
+					"corresponds to only tables being allowed in "+
+					"TOML table arrays.")
+			}
+		}
+		return tabArray
+	}
+	log.Fatalf("Unrecognized JSON format '%T'.", typedJson)
+	panic("unreachable")
+}
+
+func untag(typed map[string]interface{}) interface{} {
+	t := typed["type"].(string)
+	v := typed["value"]
+	switch t {
+	case "string":
+		return v.(string)
+	case "integer":
+		v := v.(string)
+		n, err := strconv.Atoi(v)
+		if err != nil {
+			log.Fatalf("Could not parse '%s' as integer: %s", v, err)
+		}
+		return n
+	case "float":
+		v := v.(string)
+		f, err := strconv.ParseFloat(v, 64)
+		if err != nil {
+			log.Fatalf("Could not parse '%s' as float64: %s", v, err)
+		}
+		return f
+	case "datetime":
+		v := v.(string)
+		t, err := time.Parse("2006-01-02T15:04:05Z", v)
+		if err != nil {
+			log.Fatalf("Could not parse '%s' as a datetime: %s", v, err)
+		}
+		return t
+	case "bool":
+		v := v.(string)
+		switch v {
+		case "true":
+			return true
+		case "false":
+			return false
+		}
+		log.Fatalf("Could not parse '%s' as a boolean.", v)
+	case "array":
+		v := v.([]interface{})
+		array := make([]interface{}, len(v))
+		for i := range v {
+			if m, ok := v[i].(map[string]interface{}); ok {
+				array[i] = untag(m)
+			} else {
+				log.Fatalf("Arrays may only contain other arrays or "+
+					"primitive values, but found a '%T'.", m)
+			}
+		}
+		return array
+	}
+	log.Fatalf("Unrecognized tag type '%s'.", t)
+	panic("unreachable")
+}
+
+func in(key string, m map[string]interface{}) bool {
+	_, ok := m[key]
+	return ok
+}

+ 0 - 1
third_party/github.com/BurntSushi/toml/toml-test-go/main.go

@@ -43,7 +43,6 @@ func main() {
 }
 
 func translate(tomlData interface{}) interface{} {
-
 	switch orig := tomlData.(type) {
 	case map[string]interface{}:
 		typed := make(map[string]interface{}, len(orig))

+ 0 - 0
third_party/github.com/BurntSushi/toml/type-check.go → third_party/github.com/BurntSushi/toml/type_check.go


+ 241 - 0
third_party/github.com/BurntSushi/toml/type_fields.go

@@ -0,0 +1,241 @@
+package toml
+
+// Struct field handling is adapted from code in encoding/json:
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import (
+	"reflect"
+	"sort"
+	"sync"
+)
+
+// A field represents a single field found in a struct.
+type field struct {
+	name  string       // the name of the field (`toml` tag included)
+	tag   bool         // whether field has a `toml` tag
+	index []int        // represents the depth of an anonymous field
+	typ   reflect.Type // the type of the field
+}
+
+// byName sorts field by name, breaking ties with depth,
+// then breaking ties with "name came from toml tag", then
+// breaking ties with index sequence.
+type byName []field
+
+func (x byName) Len() int { return len(x) }
+
+func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x byName) Less(i, j int) bool {
+	if x[i].name != x[j].name {
+		return x[i].name < x[j].name
+	}
+	if len(x[i].index) != len(x[j].index) {
+		return len(x[i].index) < len(x[j].index)
+	}
+	if x[i].tag != x[j].tag {
+		return x[i].tag
+	}
+	return byIndex(x).Less(i, j)
+}
+
+// byIndex sorts field by index sequence.
+type byIndex []field
+
+func (x byIndex) Len() int { return len(x) }
+
+func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x byIndex) Less(i, j int) bool {
+	for k, xik := range x[i].index {
+		if k >= len(x[j].index) {
+			return false
+		}
+		if xik != x[j].index[k] {
+			return xik < x[j].index[k]
+		}
+	}
+	return len(x[i].index) < len(x[j].index)
+}
+
+// typeFields returns a list of fields that TOML should recognize for the given
+// type. The algorithm is breadth-first search over the set of structs to
+// include - the top struct and then any reachable anonymous structs.
+func typeFields(t reflect.Type) []field {
+	// Anonymous fields to explore at the current level and the next.
+	current := []field{}
+	next := []field{{typ: t}}
+
+	// Count of queued names for current level and the next.
+	count := map[reflect.Type]int{}
+	nextCount := map[reflect.Type]int{}
+
+	// Types already visited at an earlier level.
+	visited := map[reflect.Type]bool{}
+
+	// Fields found.
+	var fields []field
+
+	for len(next) > 0 {
+		current, next = next, current[:0]
+		count, nextCount = nextCount, map[reflect.Type]int{}
+
+		for _, f := range current {
+			if visited[f.typ] {
+				continue
+			}
+			visited[f.typ] = true
+
+			// Scan f.typ for fields to include.
+			for i := 0; i < f.typ.NumField(); i++ {
+				sf := f.typ.Field(i)
+				if sf.PkgPath != "" { // unexported
+					continue
+				}
+				name := sf.Tag.Get("toml")
+				if name == "-" {
+					continue
+				}
+				index := make([]int, len(f.index)+1)
+				copy(index, f.index)
+				index[len(f.index)] = i
+
+				ft := sf.Type
+				if ft.Name() == "" && ft.Kind() == reflect.Ptr {
+					// Follow pointer.
+					ft = ft.Elem()
+				}
+
+				// Record found field and index sequence.
+				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
+					tagged := name != ""
+					if name == "" {
+						name = sf.Name
+					}
+					fields = append(fields, field{name, tagged, index, ft})
+					if count[f.typ] > 1 {
+						// If there were multiple instances, add a second,
+						// so that the annihilation code will see a duplicate.
+						// It only cares about the distinction between 1 or 2,
+						// so don't bother generating any more copies.
+						fields = append(fields, fields[len(fields)-1])
+					}
+					continue
+				}
+
+				// Record new anonymous struct to explore in next round.
+				nextCount[ft]++
+				if nextCount[ft] == 1 {
+					f := field{name: ft.Name(), index: index, typ: ft}
+					next = append(next, f)
+				}
+			}
+		}
+	}
+
+	sort.Sort(byName(fields))
+
+	// Delete all fields that are hidden by the Go rules for embedded fields,
+	// except that fields with TOML tags are promoted.
+
+	// The fields are sorted in primary order of name, secondary order
+	// of field index length. Loop over names; for each name, delete
+	// hidden fields by choosing the one dominant field that survives.
+	out := fields[:0]
+	for advance, i := 0, 0; i < len(fields); i += advance {
+		// One iteration per name.
+		// Find the sequence of fields with the name of this first field.
+		fi := fields[i]
+		name := fi.name
+		for advance = 1; i+advance < len(fields); advance++ {
+			fj := fields[i+advance]
+			if fj.name != name {
+				break
+			}
+		}
+		if advance == 1 { // Only one field with this name
+			out = append(out, fi)
+			continue
+		}
+		dominant, ok := dominantField(fields[i : i+advance])
+		if ok {
+			out = append(out, dominant)
+		}
+	}
+
+	fields = out
+	sort.Sort(byIndex(fields))
+
+	return fields
+}
+
+// dominantField looks through the fields, all of which are known to
+// have the same name, to find the single field that dominates the
+// others using Go's embedding rules, modified by the presence of
+// TOML tags. If there are multiple top-level fields, the boolean
+// will be false: This condition is an error in Go and we skip all
+// the fields.
+func dominantField(fields []field) (field, bool) {
+	// The fields are sorted in increasing index-length order. The winner
+	// must therefore be one with the shortest index length. Drop all
+	// longer entries, which is easy: just truncate the slice.
+	length := len(fields[0].index)
+	tagged := -1 // Index of first tagged field.
+	for i, f := range fields {
+		if len(f.index) > length {
+			fields = fields[:i]
+			break
+		}
+		if f.tag {
+			if tagged >= 0 {
+				// Multiple tagged fields at the same level: conflict.
+				// Return no field.
+				return field{}, false
+			}
+			tagged = i
+		}
+	}
+	if tagged >= 0 {
+		return fields[tagged], true
+	}
+	// All remaining fields have the same length. If there's more than one,
+	// we have a conflict (two fields named "X" at the same level) and we
+	// return no field.
+	if len(fields) > 1 {
+		return field{}, false
+	}
+	return fields[0], true
+}
+
+var fieldCache struct {
+	sync.RWMutex
+	m map[reflect.Type][]field
+}
+
+// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
+func cachedTypeFields(t reflect.Type) []field {
+	fieldCache.RLock()
+	f := fieldCache.m[t]
+	fieldCache.RUnlock()
+	if f != nil {
+		return f
+	}
+
+	// Compute fields without lock.
+	// Might duplicate effort but won't hold other computations back.
+	f = typeFields(t)
+	if f == nil {
+		f = []field{}
+	}
+
+	fieldCache.Lock()
+	if fieldCache.m == nil {
+		fieldCache.m = map[reflect.Type][]field{}
+	}
+	fieldCache.m[t] = f
+	fieldCache.Unlock()
+	return f
+}

+ 2 - 2
third_party/github.com/coreos/go-etcd/etcd/add_child_test.go

@@ -9,7 +9,7 @@ func TestAddChild(t *testing.T) {
 		c.Delete("nonexistentDir", true)
 	}()
 
-	c.SetDir("fooDir", 5)
+	c.CreateDir("fooDir", 5)
 
 	_, err := c.AddChild("fooDir", "v0", 5)
 	if err != nil {
@@ -44,7 +44,7 @@ func TestAddChildDir(t *testing.T) {
 		c.Delete("nonexistentDir", true)
 	}()
 
-	c.SetDir("fooDir", 5)
+	c.CreateDir("fooDir", 5)
 
 	_, err := c.AddChildDir("fooDir", 5)
 	if err != nil {

+ 27 - 7
third_party/github.com/coreos/go-etcd/etcd/client.go

@@ -2,6 +2,7 @@ package etcd
 
 import (
 	"crypto/tls"
+	"crypto/x509"
 	"encoding/json"
 	"errors"
 	"io"
@@ -41,6 +42,7 @@ type Cluster struct {
 type Config struct {
 	CertFile    string        `json:"certFile"`
 	KeyFile     string        `json:"keyFile"`
+	CaCertFile  string        `json:"caCertFile"`
 	Scheme      string        `json:"scheme"`
 	Timeout     time.Duration `json:"timeout"`
 	Consistency string        `json: "consistency"`
@@ -131,7 +133,7 @@ func NewClientReader(reader io.Reader) (*Client, error) {
 
 func setupHttpClient(client *Client) error {
 	if client.config.CertFile != "" && client.config.KeyFile != "" {
-		err := client.SetCertAndKey(client.config.CertFile, client.config.KeyFile)
+		err := client.SetCertAndKey(client.config.CertFile, client.config.KeyFile, client.config.CaCertFile)
 		if err != nil {
 			return err
 		}
@@ -229,7 +231,7 @@ func (c *Client) saveConfig() error {
 	return nil
 }
 
-func (c *Client) SetCertAndKey(cert string, key string) error {
+func (c *Client) SetCertAndKey(cert string, key string, caCert string) error {
 	if cert != "" && key != "" {
 		tlsCert, err := tls.LoadX509KeyPair(cert, key)
 
@@ -237,12 +239,30 @@ func (c *Client) SetCertAndKey(cert string, key string) error {
 			return err
 		}
 
+		tlsConfig := &tls.Config{
+			Certificates: []tls.Certificate{tlsCert},
+		}
+
+		if caCert != "" {
+			caCertPool := x509.NewCertPool()
+
+			certBytes, err := ioutil.ReadFile(caCert)
+			if err != nil {
+				return err
+			}
+
+			if !caCertPool.AppendCertsFromPEM(certBytes) {
+				return errors.New("Unable to load caCert")
+			}
+
+			tlsConfig.RootCAs = caCertPool
+		} else {
+			tlsConfig.InsecureSkipVerify = true
+		}
+
 		tr := &http.Transport{
-			TLSClientConfig: &tls.Config{
-				Certificates:       []tls.Certificate{tlsCert},
-				InsecureSkipVerify: true,
-			},
-			Dial: dialTimeout,
+			TLSClientConfig: tlsConfig,
+			Dial:            dialTimeout,
 		}
 
 		c.httpClient = &http.Client{Transport: tr}

+ 12 - 6
third_party/github.com/coreos/go-etcd/etcd/compare_and_swap_test.go

@@ -17,11 +17,14 @@ func TestCompareAndSwap(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	if !(resp.Node.Value == "bar2" && resp.Node.PrevValue == "bar" &&
-		resp.Node.Key == "/foo" && resp.Node.TTL == 5) {
+	if !(resp.Node.Value == "bar2" && resp.Node.Key == "/foo" && resp.Node.TTL == 5) {
 		t.Fatalf("CompareAndSwap 1 failed: %#v", resp)
 	}
 
+	if !(resp.PrevNode.Value == "bar" && resp.PrevNode.Key == "/foo" && resp.PrevNode.TTL == 5) {
+		t.Fatalf("CompareAndSwap 1 prevNode failed: %#v", resp)
+	}
+
 	// This should fail because it gives an incorrect prevValue
 	resp, err = c.CompareAndSwap("foo", "bar3", 5, "xxx", 0)
 	if err == nil {
@@ -38,14 +41,17 @@ func TestCompareAndSwap(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	if !(resp.Node.Value == "bar2" && resp.Node.PrevValue == "bar" &&
-		resp.Node.Key == "/foo" && resp.Node.TTL == 5) {
-		t.Fatalf("CompareAndSwap 1 failed: %#v", resp)
+	if !(resp.Node.Value == "bar2" && resp.Node.Key == "/foo" && resp.Node.TTL == 5) {
+		t.Fatalf("CompareAndSwap 3 failed: %#v", resp)
+	}
+
+	if !(resp.PrevNode.Value == "bar" && resp.PrevNode.Key == "/foo" && resp.PrevNode.TTL == 5) {
+		t.Fatalf("CompareAndSwap 3 prevNode failed: %#v", resp)
 	}
 
 	// This should fail because it gives an incorrect prevIndex
 	resp, err = c.CompareAndSwap("foo", "bar3", 5, "", 29817514)
 	if err == nil {
-		t.Fatalf("CompareAndSwap 2 should have failed.  The response is: %#v", resp)
+		t.Fatalf("CompareAndSwap 4 should have failed.  The response is: %#v", resp)
 	}
 }

+ 21 - 7
third_party/github.com/coreos/go-etcd/etcd/delete.go

@@ -1,14 +1,16 @@
 package etcd
 
 // Delete deletes the given key.
-// When recursive set to false If the key points to a
-// directory, the method will fail.
+//
+// When recursive set to false, if the key points to a
+// directory the method will fail.
+//
 // When recursive set to true, if the key points to a file,
-// the file will be deleted.  If the key points
-// to a directory, then everything under the directory, including
-// all child directories, will be deleted.
+// the file will be deleted; if the key points to a directory,
+// then everything under the directory (including all child directories)
+// will be deleted.
 func (c *Client) Delete(key string, recursive bool) (*Response, error) {
-	raw, err := c.DeleteRaw(key, recursive)
+	raw, err := c.DeleteRaw(key, recursive, false)
 
 	if err != nil {
 		return nil, err
@@ -17,9 +19,21 @@ func (c *Client) Delete(key string, recursive bool) (*Response, error) {
 	return raw.toResponse()
 }
 
-func (c *Client) DeleteRaw(key string, recursive bool) (*RawResponse, error) {
+// DeleteDir deletes an empty directory or a key value pair
+func (c *Client) DeleteDir(key string) (*Response, error) {
+	raw, err := c.DeleteRaw(key, false, true)
+
+	if err != nil {
+		return nil, err
+	}
+
+	return raw.toResponse()
+}
+
+func (c *Client) DeleteRaw(key string, recursive bool, dir bool) (*RawResponse, error) {
 	ops := options{
 		"recursive": recursive,
+		"dir":       dir,
 	}
 
 	return c.delete(key, ops)

+ 25 - 8
third_party/github.com/coreos/go-etcd/etcd/delete_test.go

@@ -16,9 +16,12 @@ func TestDelete(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if !(resp.Node.PrevValue == "bar" && resp.Node.Value == "") {
-		t.Fatalf("Delete failed with %s %s", resp.Node.PrevValue,
-			resp.Node.Value)
+	if !(resp.Node.Value == "") {
+		t.Fatalf("Delete failed with %s", resp.Node.Value)
+	}
+
+	if !(resp.PrevNode.Value == "bar") {
+		t.Fatalf("Delete PrevNode failed with %s", resp.Node.Value)
 	}
 
 	resp, err = c.Delete("foo", false)
@@ -35,27 +38,41 @@ func TestDeleteAll(t *testing.T) {
 		c.Delete("fooDir", true)
 	}()
 
-	c.Set("foo", "bar", 5)
-	resp, err := c.Delete("foo", true)
+	c.SetDir("foo", 5)
+	// test delete an empty dir
+	resp, err := c.DeleteDir("foo")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if !(resp.Node.PrevValue == "bar" && resp.Node.Value == "") {
+	if !(resp.Node.Value == "") {
 		t.Fatalf("DeleteAll 1 failed: %#v", resp)
 	}
 
-	c.SetDir("fooDir", 5)
+	if !(resp.PrevNode.Dir == true && resp.PrevNode.Value == "") {
+		t.Fatalf("DeleteAll 1 PrevNode failed: %#v", resp)
+	}
+
+	c.CreateDir("fooDir", 5)
 	c.Set("fooDir/foo", "bar", 5)
+	_, err = c.DeleteDir("fooDir")
+	if err == nil {
+		t.Fatal("should not able to delete a non-empty dir with deletedir")
+	}
+
 	resp, err = c.Delete("fooDir", true)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if !(resp.Node.PrevValue == "" && resp.Node.Value == "") {
+	if !(resp.Node.Value == "") {
 		t.Fatalf("DeleteAll 2 failed: %#v", resp)
 	}
 
+	if !(resp.PrevNode.Dir == true && resp.PrevNode.Value == "") {
+		t.Fatalf("DeleteAll 2 PrevNode failed: %#v", resp)
+	}
+
 	resp, err = c.Delete("foo", true)
 	if err == nil {
 		t.Fatalf("DeleteAll should have failed because the key foo did not exist.  "+

+ 21 - 1
third_party/github.com/coreos/go-etcd/etcd/error.go

@@ -5,14 +5,34 @@ import (
 	"fmt"
 )
 
+const (
+	ErrCodeEtcdNotReachable = 501
+)
+
+var (
+	errorMap = map[int]string{
+		ErrCodeEtcdNotReachable: "All the given peers are not reachable",
+	}
+)
+
 type EtcdError struct {
 	ErrorCode int    `json:"errorCode"`
 	Message   string `json:"message"`
 	Cause     string `json:"cause,omitempty"`
+	Index     uint64 `json:"index"`
 }
 
 func (e EtcdError) Error() string {
-	return fmt.Sprintf("%d: %s (%s)", e.ErrorCode, e.Message, e.Cause)
+	return fmt.Sprintf("%v: %v (%v) [%v]", e.ErrorCode, e.Message, e.Cause, e.Index)
+}
+
+func newError(errorCode int, cause string, index uint64) *EtcdError {
+	return &EtcdError{
+		ErrorCode: errorCode,
+		Message:   errorMap[errorCode],
+		Cause:     cause,
+		Index:     index,
+	}
 }
 
 func handleError(b []byte) error {

+ 25 - 12
third_party/github.com/coreos/go-etcd/etcd/get_test.go

@@ -35,7 +35,7 @@ func TestGetAll(t *testing.T) {
 		c.Delete("fooDir", true)
 	}()
 
-	c.SetDir("fooDir", 5)
+	c.CreateDir("fooDir", 5)
 	c.Set("fooDir/k0", "v0", 5)
 	c.Set("fooDir/k1", "v1", 5)
 
@@ -73,7 +73,7 @@ func TestGetAll(t *testing.T) {
 	}
 
 	// Test the `recursive` option
-	c.SetDir("fooDir/childDir", 5)
+	c.CreateDir("fooDir/childDir", 5)
 	c.Set("fooDir/childDir/k2", "v2", 5)
 
 	// Return kv-pairs in sorted order
@@ -83,6 +83,11 @@ func TestGetAll(t *testing.T) {
 	result.Node.Expiration = nil
 	for i, _ := range result.Node.Nodes {
 		result.Node.Nodes[i].Expiration = nil
+		if result.Node.Nodes[i].Nodes != nil {
+			for j, _ := range result.Node.Nodes[i].Nodes {
+				result.Node.Nodes[i].Nodes[j].Expiration = nil
+			}
+		}
 	}
 
 	if err != nil {
@@ -95,22 +100,30 @@ func TestGetAll(t *testing.T) {
 			Dir: true,
 			Nodes: Nodes{
 				Node{
-					Key:   "/fooDir/childDir/k2",
-					Value: "v2",
-					TTL:   5,
+					Key:           "/fooDir/childDir/k2",
+					Value:         "v2",
+					TTL:           5,
+					ModifiedIndex: 34,
+					CreatedIndex:  34,
 				},
 			},
-			TTL: 5,
+			TTL:           5,
+			ModifiedIndex: 33,
+			CreatedIndex:  33,
 		},
 		Node{
-			Key:   "/fooDir/k0",
-			Value: "v0",
-			TTL:   5,
+			Key:           "/fooDir/k0",
+			Value:         "v0",
+			TTL:           5,
+			ModifiedIndex: 31,
+			CreatedIndex:  31,
 		},
 		Node{
-			Key:   "/fooDir/k1",
-			Value: "v1",
-			TTL:   5,
+			Key:           "/fooDir/k1",
+			Value:         "v1",
+			TTL:           5,
+			ModifiedIndex: 32,
+			CreatedIndex:  32,
 		},
 	}
 

+ 2 - 0
third_party/github.com/coreos/go-etcd/etcd/options.go

@@ -28,12 +28,14 @@ var (
 		"prevValue": reflect.String,
 		"prevIndex": reflect.Uint64,
 		"prevExist": reflect.Bool,
+		"dir":       reflect.Bool,
 	}
 
 	VALID_POST_OPTIONS = validOptions{}
 
 	VALID_DELETE_OPTIONS = validOptions{
 		"recursive": reflect.Bool,
+		"dir":       reflect.Bool,
 	}
 )
 

+ 23 - 9
third_party/github.com/coreos/go-etcd/etcd/requests.go

@@ -14,8 +14,8 @@ import (
 // get issues a GET request
 func (c *Client) get(key string, options options) (*RawResponse, error) {
 	logger.Debugf("get %s [%s]", key, c.cluster.Leader)
+	p := keyToPath(key)
 
-	p := path.Join("keys", key)
 	// If consistency level is set to STRONG, append
 	// the `consistent` query string.
 	if c.config.Consistency == STRONG_CONSISTENCY {
@@ -42,7 +42,7 @@ func (c *Client) put(key string, value string, ttl uint64,
 	options options) (*RawResponse, error) {
 
 	logger.Debugf("put %s, %s, ttl: %d, [%s]", key, value, ttl, c.cluster.Leader)
-	p := path.Join("keys", key)
+	p := keyToPath(key)
 
 	str, err := options.toParameters(VALID_PUT_OPTIONS)
 	if err != nil {
@@ -62,7 +62,7 @@ func (c *Client) put(key string, value string, ttl uint64,
 // post issues a POST request
 func (c *Client) post(key string, value string, ttl uint64) (*RawResponse, error) {
 	logger.Debugf("post %s, %s, ttl: %d, [%s]", key, value, ttl, c.cluster.Leader)
-	p := path.Join("keys", key)
+	p := keyToPath(key)
 
 	resp, err := c.sendRequest("POST", p, buildValues(value, ttl))
 
@@ -76,8 +76,7 @@ func (c *Client) post(key string, value string, ttl uint64) (*RawResponse, error
 // delete issues a DELETE request
 func (c *Client) delete(key string, options options) (*RawResponse, error) {
 	logger.Debugf("delete %s [%s]", key, c.cluster.Leader)
-
-	p := path.Join("keys", key)
+	p := keyToPath(key)
 
 	str, err := options.toParameters(VALID_DELETE_OPTIONS)
 	if err != nil {
@@ -111,7 +110,8 @@ func (c *Client) sendRequest(method string, relativePath string,
 		trial++
 		logger.Debug("begin trail ", trial)
 		if trial > 2*len(c.cluster.Machines) {
-			return nil, fmt.Errorf("Cannot reach servers after %v time", trial)
+			return nil, newError(ErrCodeEtcdNotReachable,
+				"Tried to connect to each peer twice and failed", 0)
 		}
 
 		if method == "GET" && c.config.Consistency == WEAK_CONSISTENCY {
@@ -203,9 +203,7 @@ func (c *Client) handleResp(resp *http.Response) (bool, []byte) {
 	} else if code == http.StatusInternalServerError {
 		time.Sleep(time.Millisecond * 200)
 
-	} else if code == http.StatusOK ||
-		code == http.StatusCreated ||
-		code == http.StatusBadRequest {
+	} else if validHttpStatusCode[code] {
 		b, err := ioutil.ReadAll(resp.Body)
 
 		if err != nil {
@@ -249,3 +247,19 @@ func buildValues(value string, ttl uint64) url.Values {
 
 	return v
 }
+
+// convert key string to http path exclude version
+// for example: key[foo] -> path[keys/foo]
+// key[/] -> path[keys/]
+func keyToPath(key string) string {
+	p := path.Join("keys", key)
+
+	// corner case: if key is "/" or "//" ect
+	// path join will clear the tailing "/"
+	// we need to add it back
+	if p == "keys" {
+		p = "keys/"
+	}
+
+	return p
+}

+ 24 - 4
third_party/github.com/coreos/go-etcd/etcd/response.go

@@ -3,6 +3,7 @@ package etcd
 import (
 	"encoding/json"
 	"net/http"
+	"strconv"
 	"time"
 )
 
@@ -19,8 +20,19 @@ type RawResponse struct {
 	Header     http.Header
 }
 
+var (
+	validHttpStatusCode = map[int]bool{
+		http.StatusCreated:            true,
+		http.StatusOK:                 true,
+		http.StatusBadRequest:         true,
+		http.StatusNotFound:           true,
+		http.StatusPreconditionFailed: true,
+		http.StatusForbidden:          true,
+	}
+)
+
 func (rr *RawResponse) toResponse() (*Response, error) {
-	if rr.StatusCode == http.StatusBadRequest {
+	if rr.StatusCode != http.StatusOK && rr.StatusCode != http.StatusCreated {
 		return nil, handleError(rr.Body)
 	}
 
@@ -32,17 +44,25 @@ func (rr *RawResponse) toResponse() (*Response, error) {
 		return nil, err
 	}
 
+	// attach index and term to response
+	resp.EtcdIndex, _ = strconv.ParseUint(rr.Header.Get("X-Etcd-Index"), 10, 64)
+	resp.RaftIndex, _ = strconv.ParseUint(rr.Header.Get("X-Raft-Index"), 10, 64)
+	resp.RaftTerm, _ = strconv.ParseUint(rr.Header.Get("X-Raft-Term"), 10, 64)
+
 	return resp, nil
 }
 
 type Response struct {
-	Action string `json:"action"`
-	Node   *Node  `json:"node,omitempty"`
+	Action    string `json:"action"`
+	Node      *Node  `json:"node"`
+	PrevNode  *Node  `json:"prevNode,omitempty"`
+	EtcdIndex uint64 `json:"etcdIndex"`
+	RaftIndex uint64 `json:"raftIndex"`
+	RaftTerm  uint64 `json:"raftTerm"`
 }
 
 type Node struct {
 	Key           string     `json:"key, omitempty"`
-	PrevValue     string     `json:"prevValue,omitempty"`
 	Value         string     `json:"value,omitempty"`
 	Dir           bool       `json:"dir,omitempty"`
 	Expiration    *time.Time `json:"expiration,omitempty"`

+ 33 - 23
third_party/github.com/coreos/go-etcd/etcd/set_update_create.go

@@ -1,8 +1,10 @@
 package etcd
 
-// SetDir sets the given key to a directory.
-func (c *Client) SetDir(key string, ttl uint64) (*Response, error) {
-	raw, err := c.RawSetDir(key, ttl)
+// Set sets the given key to the given value.
+// It will create a new key value pair or replace the old one.
+// It will not replace a existing directory.
+func (c *Client) Set(key string, value string, ttl uint64) (*Response, error) {
+	raw, err := c.RawSet(key, value, ttl)
 
 	if err != nil {
 		return nil, err
@@ -11,10 +13,11 @@ func (c *Client) SetDir(key string, ttl uint64) (*Response, error) {
 	return raw.toResponse()
 }
 
-// UpdateDir updates the given key to a directory.  It succeeds only if the
-// given key already exists.
-func (c *Client) UpdateDir(key string, ttl uint64) (*Response, error) {
-	raw, err := c.RawUpdateDir(key, ttl)
+// Set sets the given key to a directory.
+// It will create a new directory or replace the old key value pair by a directory.
+// It will not replace a existing directory.
+func (c *Client) SetDir(key string, ttl uint64) (*Response, error) {
+	raw, err := c.RawSetDir(key, ttl)
 
 	if err != nil {
 		return nil, err
@@ -23,7 +26,7 @@ func (c *Client) UpdateDir(key string, ttl uint64) (*Response, error) {
 	return raw.toResponse()
 }
 
-// UpdateDir creates a directory under the given key.  It succeeds only if
+// CreateDir creates a directory. It succeeds only if
 // the given key does not yet exist.
 func (c *Client) CreateDir(key string, ttl uint64) (*Response, error) {
 	raw, err := c.RawCreateDir(key, ttl)
@@ -35,9 +38,10 @@ func (c *Client) CreateDir(key string, ttl uint64) (*Response, error) {
 	return raw.toResponse()
 }
 
-// Set sets the given key to the given value.
-func (c *Client) Set(key string, value string, ttl uint64) (*Response, error) {
-	raw, err := c.RawSet(key, value, ttl)
+// UpdateDir updates the given directory. It succeeds only if the
+// given key already exists.
+func (c *Client) UpdateDir(key string, ttl uint64) (*Response, error) {
+	raw, err := c.RawUpdateDir(key, ttl)
 
 	if err != nil {
 		return nil, err
@@ -46,10 +50,10 @@ func (c *Client) Set(key string, value string, ttl uint64) (*Response, error) {
 	return raw.toResponse()
 }
 
-// Update updates the given key to the given value.  It succeeds only if the
-// given key already exists.
-func (c *Client) Update(key string, value string, ttl uint64) (*Response, error) {
-	raw, err := c.RawUpdate(key, value, ttl)
+// Create creates a file with the given value under the given key.  It succeeds
+// only if the given key does not yet exist.
+func (c *Client) Create(key string, value string, ttl uint64) (*Response, error) {
+	raw, err := c.RawCreate(key, value, ttl)
 
 	if err != nil {
 		return nil, err
@@ -58,10 +62,10 @@ func (c *Client) Update(key string, value string, ttl uint64) (*Response, error)
 	return raw.toResponse()
 }
 
-// Create creates a file with the given value under the given key.  It succeeds
-// only if the given key does not yet exist.
-func (c *Client) Create(key string, value string, ttl uint64) (*Response, error) {
-	raw, err := c.RawCreate(key, value, ttl)
+// Update updates the given key to the given value.  It succeeds only if the
+// given key already exists.
+func (c *Client) Update(key string, value string, ttl uint64) (*Response, error) {
+	raw, err := c.RawUpdate(key, value, ttl)
 
 	if err != nil {
 		return nil, err
@@ -70,13 +74,10 @@ func (c *Client) Create(key string, value string, ttl uint64) (*Response, error)
 	return raw.toResponse()
 }
 
-func (c *Client) RawSetDir(key string, ttl uint64) (*RawResponse, error) {
-	return c.put(key, "", ttl, nil)
-}
-
 func (c *Client) RawUpdateDir(key string, ttl uint64) (*RawResponse, error) {
 	ops := options{
 		"prevExist": true,
+		"dir":       true,
 	}
 
 	return c.put(key, "", ttl, ops)
@@ -85,6 +86,7 @@ func (c *Client) RawUpdateDir(key string, ttl uint64) (*RawResponse, error) {
 func (c *Client) RawCreateDir(key string, ttl uint64) (*RawResponse, error) {
 	ops := options{
 		"prevExist": false,
+		"dir":       true,
 	}
 
 	return c.put(key, "", ttl, ops)
@@ -94,6 +96,14 @@ func (c *Client) RawSet(key string, value string, ttl uint64) (*RawResponse, err
 	return c.put(key, value, ttl, nil)
 }
 
+func (c *Client) RawSetDir(key string, ttl uint64) (*RawResponse, error) {
+	ops := options{
+		"dir": true,
+	}
+
+	return c.put(key, "", ttl, ops)
+}
+
 func (c *Client) RawUpdate(key string, value string, ttl uint64) (*RawResponse, error) {
 	ops := options{
 		"prevExist": true,

+ 34 - 12
third_party/github.com/coreos/go-etcd/etcd/set_update_create_test.go

@@ -17,15 +17,20 @@ func TestSet(t *testing.T) {
 	if resp.Node.Key != "/foo" || resp.Node.Value != "bar" || resp.Node.TTL != 5 {
 		t.Fatalf("Set 1 failed: %#v", resp)
 	}
+	if resp.PrevNode != nil {
+		t.Fatalf("Set 1 PrevNode failed: %#v", resp)
+	}
 
 	resp, err = c.Set("foo", "bar2", 5)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if !(resp.Node.Key == "/foo" && resp.Node.Value == "bar2" &&
-		resp.Node.PrevValue == "bar" && resp.Node.TTL == 5) {
+	if !(resp.Node.Key == "/foo" && resp.Node.Value == "bar2" && resp.Node.TTL == 5) {
 		t.Fatalf("Set 2 failed: %#v", resp)
 	}
+	if resp.PrevNode.Key != "/foo" || resp.PrevNode.Value != "bar" || resp.Node.TTL != 5 {
+		t.Fatalf("Set 2 PrevNode failed: %#v", resp)
+	}
 }
 
 func TestUpdate(t *testing.T) {
@@ -47,10 +52,12 @@ func TestUpdate(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if !(resp.Action == "update" && resp.Node.Key == "/foo" &&
-		resp.Node.PrevValue == "bar" && resp.Node.TTL == 5) {
+	if !(resp.Action == "update" && resp.Node.Key == "/foo" && resp.Node.TTL == 5) {
 		t.Fatalf("Update 1 failed: %#v", resp)
 	}
+	if !(resp.PrevNode.Key == "/foo" && resp.PrevNode.Value == "bar" && resp.Node.TTL == 5) {
+		t.Fatalf("Update 1 prevValue failed: %#v", resp)
+	}
 
 	// This should fail because the key does not exist.
 	resp, err = c.Update("nonexistent", "whatever", 5)
@@ -76,9 +83,12 @@ func TestCreate(t *testing.T) {
 	}
 
 	if !(resp.Action == "create" && resp.Node.Key == newKey &&
-		resp.Node.Value == newValue && resp.Node.PrevValue == "" && resp.Node.TTL == 5) {
+		resp.Node.Value == newValue && resp.Node.TTL == 5) {
 		t.Fatalf("Create 1 failed: %#v", resp)
 	}
+	if resp.PrevNode != nil {
+		t.Fatalf("Create 1 PrevNode failed: %#v", resp)
+	}
 
 	// This should fail, because the key is already there
 	resp, err = c.Create(newKey, newValue, 5)
@@ -95,16 +105,19 @@ func TestSetDir(t *testing.T) {
 		c.Delete("fooDir", true)
 	}()
 
-	resp, err := c.SetDir("fooDir", 5)
+	resp, err := c.CreateDir("fooDir", 5)
 	if err != nil {
 		t.Fatal(err)
 	}
 	if !(resp.Node.Key == "/fooDir" && resp.Node.Value == "" && resp.Node.TTL == 5) {
 		t.Fatalf("SetDir 1 failed: %#v", resp)
 	}
+	if resp.PrevNode != nil {
+		t.Fatalf("SetDir 1 PrevNode failed: %#v", resp)
+	}
 
 	// This should fail because /fooDir already points to a directory
-	resp, err = c.SetDir("/fooDir", 5)
+	resp, err = c.CreateDir("/fooDir", 5)
 	if err == nil {
 		t.Fatalf("fooDir already points to a directory, so SetDir should have failed."+
 			"The response was: %#v", resp)
@@ -116,12 +129,15 @@ func TestSetDir(t *testing.T) {
 	}
 
 	// This should succeed
+	// It should replace the key
 	resp, err = c.SetDir("foo", 5)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if !(resp.Node.Key == "/foo" && resp.Node.Value == "" &&
-		resp.Node.PrevValue == "bar" && resp.Node.TTL == 5) {
+	if !(resp.Node.Key == "/foo" && resp.Node.Value == "" && resp.Node.TTL == 5) {
+		t.Fatalf("SetDir 2 failed: %#v", resp)
+	}
+	if !(resp.PrevNode.Key == "/foo" && resp.PrevNode.Value == "bar" && resp.PrevNode.TTL == 5) {
 		t.Fatalf("SetDir 2 failed: %#v", resp)
 	}
 }
@@ -132,7 +148,7 @@ func TestUpdateDir(t *testing.T) {
 		c.Delete("fooDir", true)
 	}()
 
-	resp, err := c.SetDir("fooDir", 5)
+	resp, err := c.CreateDir("fooDir", 5)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -144,9 +160,12 @@ func TestUpdateDir(t *testing.T) {
 	}
 
 	if !(resp.Action == "update" && resp.Node.Key == "/fooDir" &&
-		resp.Node.Value == "" && resp.Node.PrevValue == "" && resp.Node.TTL == 5) {
+		resp.Node.Value == "" && resp.Node.TTL == 5) {
 		t.Fatalf("UpdateDir 1 failed: %#v", resp)
 	}
+	if !(resp.PrevNode.Key == "/fooDir" && resp.PrevNode.Dir == true && resp.PrevNode.TTL == 5) {
+		t.Fatalf("UpdateDir 1 PrevNode failed: %#v", resp)
+	}
 
 	// This should fail because the key does not exist.
 	resp, err = c.UpdateDir("nonexistentDir", 5)
@@ -169,9 +188,12 @@ func TestCreateDir(t *testing.T) {
 	}
 
 	if !(resp.Action == "create" && resp.Node.Key == "/fooDir" &&
-		resp.Node.Value == "" && resp.Node.PrevValue == "" && resp.Node.TTL == 5) {
+		resp.Node.Value == "" && resp.Node.TTL == 5) {
 		t.Fatalf("CreateDir 1 failed: %#v", resp)
 	}
+	if resp.PrevNode != nil {
+		t.Fatalf("CreateDir 1 PrevNode failed: %#v", resp)
+	}
 
 	// This should fail, because the key is already there
 	resp, err = c.CreateDir("fooDir", 5)

+ 13 - 15
third_party/github.com/coreos/go-log/log/commands.go

@@ -1,4 +1,5 @@
 package log
+
 // Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,7 +43,6 @@ func (logger *Logger) Logf(priority Priority, format string, v ...interface{}) {
 	logger.Log(priority, fmt.Sprintf(format, v...))
 }
 
-
 func (logger *Logger) Emergency(v ...interface{}) {
 	logger.Log(PriEmerg, v...)
 }
@@ -99,7 +99,6 @@ func (logger *Logger) Debugf(format string, v ...interface{}) {
 	logger.Log(PriDebug, fmt.Sprintf(format, v...))
 }
 
-
 func Emergency(v ...interface{}) {
 	defaultLogger.Log(PriEmerg, v...)
 }
@@ -158,57 +157,56 @@ func Debugf(format string, v ...interface{}) {
 
 // Standard library log functions
 
-func (logger *Logger)Fatalln (v ...interface{}) {
+func (logger *Logger) Fatalln(v ...interface{}) {
 	logger.Log(PriCrit, v...)
 	os.Exit(1)
 }
-func (logger *Logger)Fatalf (format string, v ...interface{}) {
+func (logger *Logger) Fatalf(format string, v ...interface{}) {
 	logger.Logf(PriCrit, format, v...)
 	os.Exit(1)
 }
 
-func (logger *Logger)Panicln (v ...interface{}) {
+func (logger *Logger) Panicln(v ...interface{}) {
 	s := fmt.Sprint(v...)
 	logger.Log(PriErr, s)
 	panic(s)
 }
-func (logger *Logger)Panicf (format string, v ...interface{}) {
+func (logger *Logger) Panicf(format string, v ...interface{}) {
 	s := fmt.Sprintf(format, v...)
 	logger.Log(PriErr, s)
 	panic(s)
 }
 
-func (logger *Logger)Println (v ...interface{}) {
+func (logger *Logger) Println(v ...interface{}) {
 	logger.Log(PriInfo, v...)
 }
-func (logger *Logger)Printf (format string, v ...interface{}) {
+func (logger *Logger) Printf(format string, v ...interface{}) {
 	logger.Logf(PriInfo, format, v...)
 }
 
-
-func Fatalln (v ...interface{}) {
+func Fatalln(v ...interface{}) {
 	defaultLogger.Log(PriCrit, v...)
 	os.Exit(1)
 }
-func Fatalf (format string, v ...interface{}) {
+func Fatalf(format string, v ...interface{}) {
 	defaultLogger.Logf(PriCrit, format, v...)
 	os.Exit(1)
 }
 
-func Panicln (v ...interface{}) {
+func Panicln(v ...interface{}) {
 	s := fmt.Sprint(v...)
 	defaultLogger.Log(PriErr, s)
 	panic(s)
 }
-func Panicf (format string, v ...interface{}) {
+func Panicf(format string, v ...interface{}) {
 	s := fmt.Sprintf(format, v...)
 	defaultLogger.Log(PriErr, s)
 	panic(s)
 }
 
-func Println (v ...interface{}) {
+func Println(v ...interface{}) {
 	defaultLogger.Log(PriInfo, v...)
 }
-func Printf (format string, v ...interface{}) {
+func Printf(format string, v ...interface{}) {
 	defaultLogger.Logf(PriInfo, format, v...)
 }

+ 1 - 0
third_party/github.com/coreos/go-log/log/fields.go

@@ -1,4 +1,5 @@
 package log
+
 // Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");

+ 1 - 0
third_party/github.com/coreos/go-log/log/logger.go

@@ -1,4 +1,5 @@
 package log
+
 // Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");

+ 1 - 0
third_party/github.com/coreos/go-log/log/priority.go

@@ -1,4 +1,5 @@
 package log
+
 // Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");

+ 1 - 0
third_party/github.com/coreos/go-log/log/sinks.go

@@ -1,4 +1,5 @@
 package log
+
 // Copyright 2013, CoreOS, Inc. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");

+ 5 - 0
third_party/github.com/coreos/go-systemd/README.md

@@ -1,3 +1,8 @@
 # go-systemd
 
 Go bindings to systemd socket activation, journal and D-BUS APIs.
+
+## Socket Activation
+
+See an example in `examples/activation/httpserver.go`. For easy debugging use
+`/usr/lib/systemd/systemd-activate`

+ 1 - 1
third_party/github.com/coreos/go-systemd/activation/files.go

@@ -29,7 +29,7 @@ func Files(unsetEnv bool) []*os.File {
 	if err != nil || nfds == 0 {
 		return nil
 	}
-	files := []*os.File(nil)
+	var files []*os.File
 	for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ {
 		syscall.CloseOnExec(fd)
 		files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd)))

+ 68 - 0
third_party/github.com/coreos/go-systemd/activation/files_test.go

@@ -0,0 +1,68 @@
+package activation
+
+import (
+	"bytes"
+	"io"
+	"os"
+	"os/exec"
+	"testing"
+)
+
+// correctStringWritten fails the text if the correct string wasn't written
+// to the other side of the pipe.
+func correctStringWritten(t *testing.T, r *os.File, expected string) bool {
+	bytes := make([]byte, len(expected))
+	io.ReadAtLeast(r, bytes, len(expected))
+
+	if string(bytes) != expected {
+		t.Fatalf("Unexpected string %s", string(bytes))
+	}
+
+	return true
+}
+
+// TestActivation forks out a copy of activation.go example and reads back two
+// strings from the pipes that are passed in.
+func TestActivation(t *testing.T) {
+	cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+
+	r1, w1, _ := os.Pipe()
+	r2, w2, _ := os.Pipe()
+	cmd.ExtraFiles = []*os.File{
+		w1,
+		w2,
+	}
+
+	cmd.Env = os.Environ()
+	cmd.Env = append(cmd.Env, "LISTEN_FDS=2", "FIX_LISTEN_PID=1")
+
+	err := cmd.Run()
+	if err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	correctStringWritten(t, r1, "Hello world")
+	correctStringWritten(t, r2, "Goodbye world")
+}
+
+func TestActivationNoFix(t *testing.T) {
+	cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+	cmd.Env = os.Environ()
+	cmd.Env = append(cmd.Env, "LISTEN_FDS=2")
+
+	out, _ := cmd.CombinedOutput()
+	if bytes.Contains(out, []byte("No files")) == false {
+		t.Fatalf("Child didn't error out as expected")
+	}
+}
+
+func TestActivationNoFiles(t *testing.T) {
+	cmd := exec.Command("go", "run", "../examples/activation/activation.go")
+	cmd.Env = os.Environ()
+	cmd.Env = append(cmd.Env, "LISTEN_FDS=0", "FIX_LISTEN_PID=1")
+
+	out, _ := cmd.CombinedOutput()
+	if bytes.Contains(out, []byte("No files")) == false {
+		t.Fatalf("Child didn't error out as expected")
+	}
+}

+ 44 - 0
third_party/github.com/coreos/go-systemd/examples/activation/activation.go

@@ -0,0 +1,44 @@
+// Activation example used by the activation unit tests.
+package main
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/coreos/go-systemd/activation"
+)
+
+func fixListenPid() {
+	if os.Getenv("FIX_LISTEN_PID") != "" {
+		// HACK: real systemd would set LISTEN_PID before exec'ing but
+		// this is too difficult in golang for the purpose of a test.
+		// Do not do this in real code.
+		os.Setenv("LISTEN_PID", fmt.Sprintf("%d", os.Getpid()))
+	}
+}
+
+func main() {
+	fixListenPid()
+
+	files := activation.Files(false)
+
+	if len(files) == 0 {
+		panic("No files")
+	}
+
+	if os.Getenv("LISTEN_PID") == "" || os.Getenv("LISTEN_FDS") == "" {
+		panic("Should not unset envs")
+	}
+
+	files = activation.Files(true)
+
+	if os.Getenv("LISTEN_PID") != "" || os.Getenv("LISTEN_FDS") != "" {
+		panic("Can not unset envs")
+	}
+
+	// Write out the expected strings to the two pipes
+	files[0].Write([]byte("Hello world"))
+	files[1].Write([]byte("Goodbye world"))
+
+	return
+}

+ 1 - 0
third_party/github.com/coreos/go-systemd/examples/activation/httpserver/README.md

@@ -0,0 +1 @@
+Example of using socket activation with systemd to serve a simple HTTP server on http://127.0.0.1:8076

+ 11 - 0
third_party/github.com/coreos/go-systemd/examples/activation/httpserver/hello.service

@@ -0,0 +1,11 @@
+[Unit]
+Description=Hello World HTTP
+Requires=network.target
+After=multi-user.target
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/httpserver
+
+[Install]
+WantedBy=multi-user.target

+ 5 - 0
third_party/github.com/coreos/go-systemd/examples/activation/httpserver/hello.socket

@@ -0,0 +1,5 @@
+[Socket]
+ListenStream=127.0.0.1:8076
+
+[Install]
+WantedBy=sockets.target

+ 29 - 0
third_party/github.com/coreos/go-systemd/examples/activation/httpserver/httpserver.go

@@ -0,0 +1,29 @@
+package main
+
+import (
+	"io"
+	"net"
+	"net/http"
+
+	"github.com/coreos/go-systemd/activation"
+)
+
+func HelloServer(w http.ResponseWriter, req *http.Request) {
+	io.WriteString(w, "hello socket activated world!\n")
+}
+
+func main() {
+	files := activation.Files(true)
+
+	if len(files) != 1 {
+		panic("Unexpected number of socket activation fds")
+	}
+
+	l, err := net.FileListener(files[0])
+	if err != nil {
+		panic(err)
+	}
+
+	http.HandleFunc("/", HelloServer)
+	http.Serve(l, nil)
+}

+ 9 - 0
third_party/github.com/coreos/go-systemd/test

@@ -0,0 +1,9 @@
+#!/bin/sh -e
+
+PKG="github.com/coreos/go-systemd"
+
+rm -R src
+mkdir -p src/$(dirname $PKG)
+ln -s ../../../ src/$PKG
+
+go test -v ${PKG}/activation

+ 3 - 1
third_party/github.com/coreos/raft/.travis.yml

@@ -1,8 +1,10 @@
 language: go
 
 go:
-  - 1.1
+  - 1.1.2
+  - 1.2
 
 install:
+  - go get github.com/stretchr/testify/assert
   - make dependencies
 

+ 1 - 0
third_party/github.com/coreos/raft/Makefile

@@ -8,6 +8,7 @@ dependencies:
 	go get -d .
 
 test:
+	go test -i ./...
 	go test -v ./...
 
 .PHONY: coverage dependencies test

+ 50 - 2
third_party/github.com/coreos/raft/README.md

@@ -34,11 +34,27 @@ go-raft is under the MIT license.
 
 These projects are built on go-raft:
 
-- [coreos/etcd](https://github.com/coreos/etcd) - A highly-available key value store for shared configuration and service discovery
-- [benbjohnson/raftd](https://github.com/benbjohnson/raftd) - A reference implementation for using the go-raft library for distributed consensus.
+- [coreos/etcd](https://github.com/coreos/etcd) - A highly-available key value store for shared configuration and service discovery.
+- [goraft/raftd](https://github.com/goraft/raftd) - A reference implementation for using the go-raft library for distributed consensus.
+- [skynetservices/skydns](https://github.com/skynetservices/skydns) - DNS for skynet or any other service discovery.
+- [influxdb/influxdb](https://github.com/influxdb/influxdb) - An open-source, distributed, time series, events, and metrics database.
 
 If you have a project that you're using go-raft in, please add it to this README so others can see implementation examples.
 
+## Contact and Resources
+
+- [raft-dev][raft-dev] is a mailing list for discussion about best practices
+  and implementation of Raft. Not goraft specific but helpful if you have
+  questions.
+- [Slides from Ben's talk][bens-talk] which includes easy to understand
+  diagrams of leader election and replication
+- The [Raft Consensus homepage][raft-home] has links to additional raft
+  implementations, slides to talks on Raft and general information
+
+[raft-home]:  http://raftconsensus.github.io/
+[raft-dev]: https://groups.google.com/forum/#!forum/raft-dev
+[bens-talk]: https://speakerdeck.com/benbjohnson/raft-the-understandable-distributed-consensus-protocol
+
 ## The Raft Protocol
 
 This section provides a summary of the Raft protocol from a high level.
@@ -83,6 +99,38 @@ By ensuring that this log is replicated identically between all the nodes in the
 Replicating the log under normal conditions is done by sending an `AppendEntries` RPC from the leader to each of the other servers in the cluster (called Peers).
 Each peer will append the entries from the leader through a 2-phase commit process which ensure that a majority of servers in the cluster have entries written to log.
 
+
+## Raft in Practice
+
+### Optimal Cluster Size
+
+The primary consideration when choosing the node count in your Raft cluster is the number of nodes that can simultaneously fail.
+Because Raft requires a majority of nodes to be available to make progress, the number of node failures the cluster can tolerate is `(n / 2) - 1`.
+
+This means that a 3-node cluster can tolerate 1 node failure.
+If 2 nodes fail then the cluster cannot commit entries or elect a new leader so progress stops.
+A 5-node cluster can tolerate 2 node failures. A 9-node cluster can tolerate 4 node failures.
+It is unlikely that 4 nodes will simultaneously fail so clusters larger than 9 nodes are not common.
+
+Another consideration is performance.
+The leader must replicate log entries for each follower node so CPU and networking resources can quickly be bottlenecked under stress in a large cluster.
+
+
+### Scaling Raft
+
+Once you grow beyond the maximum size of your cluster there are a few options for scaling Raft:
+
+1. *Core nodes with dumb replication.*
+   This option requires you to maintain a small cluster (e.g. 5 nodes) that is involved in the Raft process and then replicate only committed log entries to the remaining nodes in the cluster.
+   This works well if you have reads in your system that can be stale.
+
+2. *Sharding.*
+   This option requires that you segment your data into different clusters.
+   This option works well if you need very strong consistency and therefore need to read and write heavily from the leader.
+
+If you have a very large cluster that you need to replicate to using Option 1 then you may want to look at performing hierarchical replication so that nodes can better share the load.
+
+
 ## History
 
 Ben Johnson started this library for use in his behavioral analytics database called [Sky](https://github.com/skydb/sky).

+ 1 - 1
third_party/github.com/coreos/raft/append_entries_request_test.go

@@ -28,7 +28,7 @@ func createTestAppendEntriesRequest(entryCount int) (*AppendEntriesRequest, []by
 	entries := make([]*LogEntry, 0)
 	for i := 0; i < entryCount; i++ {
 		command := &DefaultJoinCommand{Name: "localhost:1000"}
-		entry, _ := newLogEntry(nil, 1, 2, command)
+		entry, _ := newLogEntry(nil, nil, 1, 2, command)
 		entries = append(entries, entry)
 	}
 	req := newAppendEntriesRequest(1, 1, 1, 1, "leader", entries)

+ 11 - 28
third_party/github.com/coreos/raft/command.go

@@ -8,28 +8,25 @@ import (
 	"reflect"
 )
 
-//------------------------------------------------------------------------------
-//
-// Globals
-//
-//------------------------------------------------------------------------------
-
 var commandTypes map[string]Command
 
 func init() {
 	commandTypes = map[string]Command{}
 }
 
-//------------------------------------------------------------------------------
-//
-// Typedefs
-//
-//------------------------------------------------------------------------------
-
-// A command represents an action to be taken on the replicated state machine.
+// Command represents an action to be taken on the replicated state machine.
 type Command interface {
 	CommandName() string
-	Apply(server Server) (interface{}, error)
+}
+
+// CommandApply represents the interface to apply a command to the server.
+type CommandApply interface {
+	Apply(Context) (interface{}, error)
+}
+
+// deprecatedCommandApply represents the old interface to apply a command to the server.
+type deprecatedCommandApply interface {
+	Apply(Server) (interface{}, error)
 }
 
 type CommandEncoder interface {
@@ -37,16 +34,6 @@ type CommandEncoder interface {
 	Decode(r io.Reader) error
 }
 
-//------------------------------------------------------------------------------
-//
-// Functions
-//
-//------------------------------------------------------------------------------
-
-//--------------------------------------
-// Instantiation
-//--------------------------------------
-
 // Creates a new instance of a command by name.
 func newCommand(name string, data []byte) (Command, error) {
 	// Find the registered command.
@@ -76,10 +63,6 @@ func newCommand(name string, data []byte) (Command, error) {
 	return copy, nil
 }
 
-//--------------------------------------
-// Registration
-//--------------------------------------
-
 // Registers a command by storing a reference to an instance of it.
 func RegisterCommand(command Command) {
 	if command == nil {

+ 39 - 0
third_party/github.com/coreos/raft/context.go

@@ -0,0 +1,39 @@
+package raft
+
+// Context represents the current state of the server. It is passed into
+// a command when the command is being applied since the server methods
+// are locked.
+type Context interface {
+	Server() Server
+	CurrentTerm() uint64
+	CurrentIndex() uint64
+	CommitIndex() uint64
+}
+
+// context is the concrete implementation of Context.
+type context struct {
+	server       Server
+	currentIndex uint64
+	currentTerm  uint64
+	commitIndex  uint64
+}
+
+// Server returns a reference to the server.
+func (c *context) Server() Server {
+	return c.server
+}
+
+// CurrentTerm returns current term the server is in.
+func (c *context) CurrentTerm() uint64 {
+	return c.currentTerm
+}
+
+// CurrentIndex returns current index the server is at.
+func (c *context) CurrentIndex() uint64 {
+	return c.currentIndex
+}
+
+// CommitIndex returns last commit index the server is at.
+func (c *context) CommitIndex() uint64 {
+	return c.commitIndex
+}

+ 58 - 0
third_party/github.com/coreos/raft/event.go

@@ -0,0 +1,58 @@
+package raft
+
+const (
+	StateChangeEventType  = "stateChange"
+	LeaderChangeEventType = "leaderChange"
+	TermChangeEventType   = "termChange"
+	AddPeerEventType      = "addPeer"
+	RemovePeerEventType   = "removePeer"
+
+	HeartbeatTimeoutEventType         = "heartbeatTimeout"
+	ElectionTimeoutThresholdEventType = "electionTimeoutThreshold"
+)
+
+// Event represents an action that occurred within the Raft library.
+// Listeners can subscribe to event types by using the Server.AddEventListener() function.
+type Event interface {
+	Type() string
+	Source() interface{}
+	Value() interface{}
+	PrevValue() interface{}
+}
+
+// event is the concrete implementation of the Event interface.
+type event struct {
+	typ       string
+	source    interface{}
+	value     interface{}
+	prevValue interface{}
+}
+
+// newEvent creates a new event.
+func newEvent(typ string, value interface{}, prevValue interface{}) *event {
+	return &event{
+		typ:       typ,
+		value:     value,
+		prevValue: prevValue,
+	}
+}
+
+// Type returns the type of event that occurred.
+func (e *event) Type() string {
+	return e.typ
+}
+
+// Source returns the object that dispatched the event.
+func (e *event) Source() interface{} {
+	return e.source
+}
+
+// Value returns the current value associated with the event, if applicable.
+func (e *event) Value() interface{} {
+	return e.value
+}
+
+// PrevValue returns the previous value associated with the event, if applicable.
+func (e *event) PrevValue() interface{} {
+	return e.prevValue
+}

+ 50 - 0
third_party/github.com/coreos/raft/event_dispatcher.go

@@ -0,0 +1,50 @@
+package raft
+
+import (
+	"sync"
+)
+
+// eventDispatcher is responsible for managing listeners for named events
+// and dispatching event notifications to those listeners.
+type eventDispatcher struct {
+	sync.RWMutex
+	source    interface{}
+	listeners map[string]eventListeners
+}
+
+// EventListener is a function that can receive event notifications.
+type EventListener func(Event)
+
+// EventListeners represents a collection of individual listeners.
+type eventListeners []EventListener
+
+// newEventDispatcher creates a new eventDispatcher instance.
+func newEventDispatcher(source interface{}) *eventDispatcher {
+	return &eventDispatcher{
+		source:    source,
+		listeners: make(map[string]eventListeners),
+	}
+}
+
+// AddEventListener adds a listener function for a given event type.
+func (d *eventDispatcher) AddEventListener(typ string, listener EventListener) {
+	d.Lock()
+	defer d.Unlock()
+	d.listeners[typ] = append(d.listeners[typ], listener)
+}
+
+// DispatchEvent dispatches an event.
+func (d *eventDispatcher) DispatchEvent(e Event) {
+	d.RLock()
+	defer d.RUnlock()
+
+	// Automatically set the event source.
+	if e, ok := e.(*event); ok {
+		e.source = d.source
+	}
+
+	// Dispatch the event to all listeners.
+	for _, l := range d.listeners[e.Type()] {
+		l(e)
+	}
+}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor