diff --git a/.gitignore b/.gitignore index 9c7aba969..1585b6845 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ serial-port-json-server snapshot/* public/ artifacts* + +# IDEs config +.idea diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 000000000..02553eca6 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,454 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + digest = "1:ecf78eacf406c42f07f66d6b79fda24d2b92dc711bfd0760d0c931678f9621fe" + name = "github.com/Sirupsen/logrus" + packages = ["."] + pruneopts = "NUT" + revision = "ad15b42461921f1fb3529b058c6786c6a45d5162" + version = "v1.1.1" + +[[projects]] + digest = "1:aba270497eb2d49f5cba6f4162d524b9a1195a24cbce8be20bf56a0051f47deb" + name = "github.com/blang/semver" + packages = ["."] + pruneopts = "NUT" + revision = "2ee87856327ba09384cabd113bc6b5d174e9ec0f" + version = "v3.5.1" + +[[projects]] + branch = "master" + digest = "1:dd9ac3f14c49f44e3921aeafa38653e04ae44e219eebc6e0757c04e19098ca40" + name = "github.com/creack/goselect" + packages = ["."] + pruneopts = "NUT" + revision = "58854f77ee8d858ce751b0a9bcc5533fef7bfa9e" + +[[projects]] + digest = "1:d57500f681aba6bbb064c4b885995fd2e3521a7b9ef05f19feedd3b8e72a020e" + name = "github.com/davidmz/go-pageant" + packages = ["."] + pruneopts = "NUT" + revision = "30ad2d03e9fe97a029a6a6dc87bff319e0bb6bc4" + version = "v1.0.1" + +[[projects]] + branch = "master" + digest = "1:9a8c267811e3b6fae377040b8bf050fcee59fdb8cade14ad3f929d924e08093d" + name = "github.com/getlantern/context" + packages = ["."] + pruneopts = "NUT" + revision = "624d99b1798d7c5375ea1d3ca4c5b04d58f7c775" + +[[projects]] + branch = "master" + digest = "1:56460acc7affba18fa344130886a6f841988d1368a051759d2e0c03ef6255f54" + name = "github.com/getlantern/errors" + packages = ["."] + pruneopts = "NUT" + revision = "e24b7f4ff7c70be59bbefca6b7695d68cda8b399" + +[[projects]] + branch = "master" + digest = "1:785bb882679010d1fe5b6b456f3e28b16d54e8418e33cd769e3322c49c47a2e8" + name = "github.com/getlantern/golog" + packages = ["."] + pruneopts = "NUT" + revision = "cca714f7feb5df8e455f409b549d384441ac4578" + +[[projects]] + branch = "master" + digest = "1:f12c7103ba4c446c6822f331ada3e5f0c3626be111a115e92700cd2724bca9ed" + name = "github.com/getlantern/hex" + packages = ["."] + pruneopts = "NUT" + revision = "083fba3033ad473db3dd31c9bb368473d37581a7" + +[[projects]] + branch = "master" + digest = "1:916634881c70eb3c2201419786896254d601a786a9124e662a079d4649df160d" + name = "github.com/getlantern/hidden" + packages = ["."] + pruneopts = "NUT" + revision = "d52a649ab33af200943bb599898dbdcfdbc94cb7" + +[[projects]] + branch = "master" + digest = "1:f84e2692edf40301ae0ce718695cde032f5c6964e4fad812749eb1eaefa95785" + name = "github.com/getlantern/ops" + packages = ["."] + pruneopts = "NUT" + revision = "37353306c90844c8e0591956f56611f46299d202" + +[[projects]] + branch = "master" + digest = "1:0060263f361770203e8bc253fc45ed71a7ba092f7fe632f2148e9e95453ea32b" + name = "github.com/getlantern/systray" + packages = ["."] + pruneopts = "NUT" + revision = "e31397f8c6928d98a8a9a7e80087aebcf0090beb" + +[[projects]] + branch = "master" + digest = "1:23edf5aaca7a1f15d68215ac41595c0732152757e9d7b3f282821222784049f1" + name = "github.com/gin-contrib/sse" + packages = ["."] + pruneopts = "NUT" + revision = "22d885f9ecc78bf4ee5d72b937e4bbcdc58e8cae" + +[[projects]] + digest = "1:7f029513a3c64c1fc923af79bf27d4fd0ce4fafdd13b421c1884d52c84e9c600" + name = "github.com/gin-gonic/gin" + packages = [ + ".", + "binding", + "json", + "render", + ] + pruneopts = "NUT" + revision = "b869fe1415e4b9eb52f247441830d502aece2d4d" + version = "v1.3.0" + +[[projects]] + digest = "1:c204ec81f754234f2c3c4093cc8cc42151aadedd1129b32539a472fd7881e689" + name = "github.com/go-ini/ini" + packages = ["."] + pruneopts = "NUT" + revision = "9c8236e659b76e87bf02044d06fde8683008ff3e" + version = "v1.39.0" + +[[projects]] + digest = "1:cb4e216bd9f58866f42dc65893455b24f879b026fdaa1ecc3aafff625fdb5a66" + name = "github.com/go-ole/go-ole" + packages = [ + ".", + "oleutil", + ] + pruneopts = "NUT" + revision = "a41e3c4b706f6ae8dfbff342b06e40fa4d2d0506" + version = "v1.2.1" + +[[projects]] + digest = "1:91358b3a314c1ddfd4d6445ca9c1fb846842c31c153e626730594b3c95f73f4a" + name = "github.com/go-stack/stack" + packages = ["."] + pruneopts = "NUT" + revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a" + version = "v1.8.0" + +[[projects]] + digest = "1:97df918963298c287643883209a2c3f642e6593379f97ab400c2a2e219ab647d" + name = "github.com/golang/protobuf" + packages = ["proto"] + pruneopts = "NUT" + revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5" + version = "v1.2.0" + +[[projects]] + branch = "master" + digest = "1:46223f4c05549a4f57fe78cbe3348d905f0d91ae7ab8fa4ac1751281dfa52aac" + name = "github.com/googollee/go-engine.io" + packages = [ + ".", + "message", + "parser", + "polling", + "transport", + "websocket", + ] + pruneopts = "NUT" + revision = "e2f255711dcb2ea41e42c6d9d98c172d7edf6509" + +[[projects]] + branch = "master" + digest = "1:5e9a122f51197a970db03a82944e9344201e68f0abd6d66016911cb9ed735572" + name = "github.com/googollee/go-socket.io" + packages = ["."] + pruneopts = "NUT" + revision = "25e1f67559cf5d0e41efbc3e0157bb952596ffc3" + +[[projects]] + digest = "1:4a0c072e44da763409da72d41492373a034baf2e6d849c76d239b4abdfbb6c49" + name = "github.com/gorilla/websocket" + packages = ["."] + pruneopts = "NUT" + revision = "66b9c49e59c6c48f0ffce28c2d8b8a5678502c6d" + version = "v1.4.0" + +[[projects]] + digest = "1:06d89db601972cb01beee33ea815839d29ba8048c4b0d71a79a3e6af96063acf" + name = "github.com/itsjamie/gin-cors" + packages = ["."] + pruneopts = "NUT" + revision = "97b4a9da79331dfa2b6d35f4cdd1e50f5148859c" + version = "1.0.0" + +[[projects]] + digest = "1:8e36686e8b139f8fe240c1d5cf3a145bc675c22ff8e707857cdd3ae17b00d728" + name = "github.com/json-iterator/go" + packages = ["."] + pruneopts = "NUT" + revision = "1624edc4454b8682399def8740d46db5e4362ba4" + version = "v1.1.5" + +[[projects]] + branch = "master" + digest = "1:263f9b0a0bcbfff9d5e7d9f2aa11f53995d98214fe0fb97e429e7a5f4534a0f9" + name = "github.com/kardianos/osext" + packages = ["."] + pruneopts = "NUT" + revision = "ae77be60afb1dcacde03767a8c37337fad28ac14" + +[[projects]] + digest = "1:4059c14e87a2de3a434430340521b5feece186c1469eff0834c29a63870de3ed" + name = "github.com/konsorten/go-windows-terminal-sequences" + packages = ["."] + pruneopts = "NUT" + revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242" + version = "v1.0.1" + +[[projects]] + digest = "1:48306f3ac75da2e9facec89df74e5ac14737402af373171bc4b91655e7d7d097" + name = "github.com/kr/binarydist" + packages = ["."] + pruneopts = "NUT" + revision = "88f551ae580780cc79d12ab4c218ba1ca346b83a" + version = "v0.1.0" + +[[projects]] + digest = "1:47fa0ef6ae6b0387dacb77c7ab8827b4ef621650fd613e43ece61de4cb3f5019" + name = "github.com/kr/fs" + packages = ["."] + pruneopts = "NUT" + revision = "1455def202f6e05b95cc7bfc7e8ae67ae5141eba" + version = "v0.1.0" + +[[projects]] + digest = "1:bffa444ca07c69c599ae5876bc18b25bfd5fa85b297ca10a25594d284a7e9c5d" + name = "github.com/mattn/go-isatty" + packages = ["."] + pruneopts = "NUT" + revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c" + version = "v0.0.4" + +[[projects]] + digest = "1:d0164259ed17929689df11205194d80288e8ae25351778f7a3421a24774c36f8" + name = "github.com/mattn/go-shellwords" + packages = ["."] + pruneopts = "NUT" + revision = "02e3cf038dcea8290e44424da473dd12be796a8a" + version = "v1.0.3" + +[[projects]] + digest = "1:a4b80152551d55dbb835dd81ffa33157f0224b313ae94640c64c9ae5403098db" + name = "github.com/miekg/dns" + packages = ["."] + pruneopts = "NUT" + revision = "915ca3d5ffd945235828a097c917311a9d86ebb4" + version = "v1.0.14" + +[[projects]] + branch = "master" + digest = "1:a4df73029d2c42fabcb6b41e327d2f87e685284ec03edf76921c267d9cfc9c23" + name = "github.com/mitchellh/go-homedir" + packages = ["."] + pruneopts = "NUT" + revision = "ae18d6b8b3205b561c79e8e5f69bff09736185f4" + +[[projects]] + digest = "1:2f42fa12d6911c7b7659738758631bec870b7e9b4c6be5444f963cdcfccc191f" + name = "github.com/modern-go/concurrent" + packages = ["."] + pruneopts = "NUT" + revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94" + version = "1.0.3" + +[[projects]] + digest = "1:c6aca19413b13dc59c220ad7430329e2ec454cc310bc6d8de2c7e2b93c18a0f6" + name = "github.com/modern-go/reflect2" + packages = ["."] + pruneopts = "NUT" + revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" + version = "1.0.1" + +[[projects]] + branch = "master" + digest = "1:8b8b71239fc5851930ed3d267a2d310f100d2f3d340d55eff74b210730d75125" + name = "github.com/oleksandr/bonjour" + packages = ["."] + pruneopts = "NUT" + revision = "5dcf00d8b228be86307f952f550f2191d956b9e2" + +[[projects]] + branch = "master" + digest = "1:8fe179a5468c41a57dd75dcb283c1a81c4ca38a934380ff996437033d7d9509a" + name = "github.com/oxtoacart/bpool" + packages = ["."] + pruneopts = "NUT" + revision = "4e1c5567d7c2dd59fa4c7c83d34c2f3528b025d6" + +[[projects]] + digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121" + name = "github.com/pkg/errors" + packages = ["."] + pruneopts = "NUT" + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + digest = "1:3d8d113726023d6c1dd1f29a19f13266d33a0746fe6f14df8da17eb7409a9aa2" + name = "github.com/pkg/sftp" + packages = ["."] + pruneopts = "NUT" + revision = "08de04f133f27844173471167014e1a753655ac8" + version = "v1.8.3" + +[[projects]] + branch = "master" + digest = "1:ba0f377f1482789a3d8a398ee01f642bd2d6ec97bec11268ccde92677ed1fb5c" + name = "github.com/sfreiberg/simplessh" + packages = ["."] + pruneopts = "NUT" + revision = "495cbb862a9c6348e0fff479ed1e7b70c871b372" + +[[projects]] + branch = "master" + digest = "1:39853e1ae46a02816e2419e1f590e00682b1a6b60bb988597cf2efb84314da45" + name = "github.com/skratchdot/open-golang" + packages = ["open"] + pruneopts = "NUT" + revision = "75fb7ed4208cf72d323d7d02fd1a5964a7a9073c" + +[[projects]] + digest = "1:919fc2a81add8ac4a7a236dceaf3e4c29ba4df96d13c3f2ce13a4d0132ebefb8" + name = "github.com/ugorji/go" + packages = ["codec"] + pruneopts = "NUT" + revision = "b4c50a2b199d93b13dc15e78929cfb23bfdf21ab" + version = "v1.1.1" + +[[projects]] + branch = "master" + digest = "1:c205236572ddcd0988a24c06be96a179982e870d2b7d746c95e06d9803cd9462" + name = "github.com/xrash/smetrics" + packages = ["."] + pruneopts = "NUT" + revision = "a3153f7040e90324c58c6287535e26a0ac5c1cc1" + +[[projects]] + branch = "master" + digest = "1:572a6fb10b136109bd380f283682a2eb05551f3e193ff95a3d4d08d7060fa441" + name = "go.bug.st/serial.v1" + packages = [ + ".", + "enumerator", + "unixutils", + ] + pruneopts = "NUT" + revision = "5f7892a7bb453066bdc6683b9b5d24d9dee03ec1" + +[[projects]] + branch = "master" + digest = "1:a0704c8502c6004cbc247cb339c66270cf5f6cfbb032b25237faf93875abeefa" + name = "golang.org/x/crypto" + packages = [ + "cast5", + "curve25519", + "ed25519", + "ed25519/internal/edwards25519", + "internal/chacha20", + "internal/subtle", + "openpgp", + "openpgp/armor", + "openpgp/elgamal", + "openpgp/errors", + "openpgp/packet", + "openpgp/s2k", + "poly1305", + "ssh", + "ssh/agent", + "ssh/terminal", + ] + pruneopts = "NUT" + revision = "4d3f4d9ffa16a13f451c3b2999e9c49e9750bf06" + +[[projects]] + branch = "master" + digest = "1:40a3cfcb660b2f6354f669eb8cbea46b5a308b42f349782147301ab66fb57184" + name = "golang.org/x/net" + packages = [ + "bpf", + "internal/iana", + "internal/socket", + "ipv4", + "ipv6", + ] + pruneopts = "NUT" + revision = "c44066c5c816ec500d459a2a324a753f78531ae0" + +[[projects]] + branch = "master" + digest = "1:3bcf6eb3757db3e22c41d212f886b86d0f940f86e1af85b13cd31122ac341193" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows", + ] + pruneopts = "NUT" + revision = "9b800f95dbbc54abff0acf7ee32d88ba4e328c89" + +[[projects]] + digest = "1:0215407129c5f116ae8f6d3af64df59c39d3f606a72ef77a1e6ed874f92a8d9c" + name = "gopkg.in/go-playground/validator.v8" + packages = ["."] + pruneopts = "NUT" + revision = "5f1438d3fca68893a817e4a66806cea46a9e4ebf" + version = "v8.18.2" + +[[projects]] + branch = "v0" + digest = "1:299a25c4ee90eb917553bb4d51e04b75f1b56bc1b4f5c63ed21e5369fb533855" + name = "gopkg.in/inconshreveable/go-update.v0" + packages = [ + ".", + "download", + ] + pruneopts = "NUT" + revision = "d8b0b1d421aa1cbf392c05869f8abbc669bb7066" + +[[projects]] + digest = "1:7c95b35057a0ff2e19f707173cc1a947fa43a6eb5c4d300d196ece0334046082" + name = "gopkg.in/yaml.v2" + packages = ["."] + pruneopts = "NUT" + revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" + version = "v2.2.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "github.com/Sirupsen/logrus", + "github.com/blang/semver", + "github.com/getlantern/systray", + "github.com/gin-gonic/gin", + "github.com/go-ini/ini", + "github.com/googollee/go-socket.io", + "github.com/itsjamie/gin-cors", + "github.com/kardianos/osext", + "github.com/kr/binarydist", + "github.com/mattn/go-shellwords", + "github.com/mitchellh/go-homedir", + "github.com/oleksandr/bonjour", + "github.com/pkg/errors", + "github.com/sfreiberg/simplessh", + "github.com/skratchdot/open-golang/open", + "github.com/xrash/smetrics", + "go.bug.st/serial.v1", + "go.bug.st/serial.v1/enumerator", + "golang.org/x/crypto/openpgp", + "gopkg.in/inconshreveable/go-update.v0", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 000000000..44e310071 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,211 @@ +# Gopkg.toml example +# +# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + name = "github.com/Sirupsen/logrus" + version = "1.0.6" + +[[constraint]] + name = "github.com/blang/semver" + version = "3.5.1" + +[[constraint]] + branch = "master" + name = "github.com/creack/goselect" + +[[constraint]] + branch = "master" + name = "github.com/getlantern/context" + +[[constraint]] + branch = "master" + name = "github.com/getlantern/errors" + +[[constraint]] + branch = "master" + name = "github.com/getlantern/filepersist" + +[[constraint]] + branch = "master" + name = "github.com/getlantern/golog" + +[[constraint]] + branch = "master" + name = "github.com/getlantern/hex" + +[[constraint]] + branch = "master" + name = "github.com/getlantern/hidden" + +[[constraint]] + branch = "master" + name = "github.com/getlantern/ops" + +[[constraint]] + name = "github.com/getlantern/stack" + version = "1.5.1" + +[[constraint]] + branch = "master" + name = "github.com/getlantern/systray" + +[[constraint]] + name = "github.com/gin-gonic/gin" + version = "1.2.0" + +[[constraint]] + name = "github.com/go-ini/ini" + version = "1.38.1" + +[[constraint]] + branch = "master" + name = "github.com/googollee/go-engine.io" + +[[constraint]] + branch = "master" + name = "github.com/googollee/go-socket.io" + +[[constraint]] + name = "github.com/gorilla/websocket" + version = "1.2.0" + +[[constraint]] + branch = "filemode" + name = "github.com/inconshreveable/go-update" + +[[constraint]] + name = "github.com/itsjamie/gin-cors" + version = "1.0.0" + +[[constraint]] + branch = "master" + name = "github.com/kardianos/osext" + +[[constraint]] + name = "github.com/kr/binarydist" + version = "0.1.0" + +[[constraint]] + name = "github.com/kr/fs" + version = "0.1.0" + +[[constraint]] + branch = "master" + name = "github.com/manucorporat/sse" + +[[constraint]] + name = "github.com/mattn/go-colorable" + version = "0.0.9" + +[[constraint]] + name = "github.com/mattn/go-isatty" + version = "0.0.3" + +[[constraint]] + name = "github.com/mattn/go-ole" + version = "1.2.1" + +[[constraint]] + name = "github.com/mattn/go-shellwords" + version = "1.0.3" + +[[constraint]] + name = "github.com/miekg/dns" + version = "1.0.8" + +[[constraint]] + branch = "master" + name = "github.com/mitchellh/go-homedir" + +[[constraint]] + branch = "master" + name = "github.com/oleksandr/bonjour" + +[[constraint]] + name = "github.com/pkg/errors" + version = "0.8.0" + +[[constraint]] + name = "github.com/pkg/sftp" + version = "1.8.0" + +[[constraint]] + branch = "master" + name = "github.com/sfreiberg/simplessh" + +[[constraint]] + branch = "master" + name = "github.com/skratchdot/open-golang" + +[[constraint]] + name = "github.com/smartystreets/goconvey" + version = "1.6.3" + +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.2.2" + +[[constraint]] + branch = "master" + name = "github.com/vharitonsky/iniflags" + +[[constraint]] + branch = "master" + name = "github.com/xrash/smetrics" + +[[constraint]] + branch = "master" + name = "go.bug.st/serial.v1" + +[[constraint]] + branch = "master" + name = "golang.org/x/crypto" + +[[constraint]] + branch = "master" + name = "golang.org/x/net" + +[[constraint]] + branch = "master" + name = "golang.org/x/sys" + +[[constraint]] + name = "gopkg.in/bluesuncorp/validator.v5" + version = "5.12.0" + +[[constraint]] + branch = "v0" + name = "gopkg.in/inconshreveable/go-update.v0" + +[[constraint]] + name = "gopkg.in/ini.v1" + version = "1.38.1" + +[prune] + non-go = true + go-tests = true + unused-packages = true \ No newline at end of file diff --git a/tools/download.go b/tools/download.go index aca8028f9..cd4ec94ec 100644 --- a/tools/download.go +++ b/tools/download.go @@ -319,29 +319,77 @@ func stringInSlice(str string, list []string) bool { return false } +func commonPrefix(sep byte, paths []string) string { + // Handle special cases. + switch len(paths) { + case 0: + return "" + case 1: + return path.Clean(paths[0]) + } + + c := []byte(path.Clean(paths[0])) + + // We add a trailing sep to handle: common prefix directory is included in the path list + // (e.g. /home/user1, /home/user1/foo, /home/user1/bar). + // path.Clean will have cleaned off trailing / separators with + // the exception of the root directory, "/" making it "//" + // but this will get fixed up to "/" below). + c = append(c, sep) + + // Ignore the first path since it's already in c + for _, v := range paths[1:] { + // Clean up each path before testing it + v = path.Clean(v) + string(sep) + + // Find the first non-common byte and truncate c + if len(v) < len(c) { + c = c[:len(v)] + } + for i := 0; i < len(c); i++ { + if v[i] != c[i] { + c = c[:i] + break + } + } + } + + // Remove trailing non-separator characters and the final separator + for i := len(c) - 1; i >= 0; i-- { + if c[i] == sep { + c = c[:i] + break + } + } + + return string(c) +} + +func removeStringFromSlice(s []string, r string) []string { + for i, v := range s { + if v == r { + return append(s[:i], s[i+1:]...) + } + } + return s +} + func findBaseDir(dirList []string) string { if len(dirList) == 1 { return filepath.Dir(dirList[0]) + "/" } - baseDir := "" + // https://github.com/backdrop-ops/contrib/issues/55#issuecomment-73814500 dontdiff := []string{"pax_global_header"} - for index, _ := range dirList { - if stringInSlice(dirList[index], dontdiff) { - continue - } - candidateBaseDir := dirList[index] - for i := index; i < len(dirList); i++ { - if !strings.Contains(dirList[i], candidateBaseDir) { - return baseDir - } - } - // avoid setting the candidate if it is the last file - if dirList[len(dirList)-1] != candidateBaseDir { - baseDir = candidateBaseDir - } + for _, v := range dontdiff { + dirList = removeStringFromSlice(dirList, v) + } + + commonBaseDir := commonPrefix(os.PathSeparator, dirList) + if commonBaseDir != "" { + commonBaseDir = commonBaseDir + "/" } - return baseDir + return commonBaseDir } func extractZip(body []byte, location string) (string, error) { diff --git a/tools/download_test.go b/tools/download_test.go index 2ef79d721..74adefb44 100644 --- a/tools/download_test.go +++ b/tools/download_test.go @@ -13,11 +13,14 @@ func Test_findBaseDir(t *testing.T) { {[]string{"bin/bossac"}, "bin/"}, {[]string{"bin/", "bin/bossac"}, "bin/"}, {[]string{"bin/", "bin/bossac", "example"}, ""}, + {[]string{"avrdude/bin/avrdude", "avrdude/etc/avrdude.conf"}, "avrdude/"}, + {[]string{"pax_global_header","bin/", "bin/bossac"}, "bin/"}, + } for _, tt := range cases { t.Run(fmt.Sprintln(tt.dirList), func(t *testing.T) { if got := findBaseDir(tt.dirList); got != tt.want { - t.Errorf("findBaseDir() = %v, want %v", got, tt.want) + t.Errorf("findBaseDir() = got %v, want %v", got, tt.want) } }) } diff --git a/trayicon.go b/trayicon.go index 5f9e3dfd7..6fe2dbfe0 100644 --- a/trayicon.go +++ b/trayicon.go @@ -47,9 +47,9 @@ import ( func setupSysTray() { runtime.LockOSThread() if *hibernate == true { - systray.Run(setupSysTrayHibernate) + systray.Run(setupSysTrayHibernate,nil) } else { - systray.Run(setupSysTrayReal) + systray.Run(setupSysTrayReal,nil) } } diff --git a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/vendor/github.com/Sirupsen/logrus/CHANGELOG.md deleted file mode 100644 index b1fe4b62c..000000000 --- a/vendor/github.com/Sirupsen/logrus/CHANGELOG.md +++ /dev/null @@ -1,41 +0,0 @@ -# 0.8.6 - -* hooks/raven: allow passing an initialized client - -# 0.8.5 - -* logrus/core: revert #208 - -# 0.8.4 - -* formatter/text: fix data race (#218) - -# 0.8.3 - -* logrus/core: fix entry log level (#208) -* logrus/core: improve performance of text formatter by 40% -* logrus/core: expose `LevelHooks` type -* logrus/core: add support for DragonflyBSD and NetBSD -* formatter/text: print structs more verbosely - -# 0.8.2 - -* logrus: fix more Fatal family functions - -# 0.8.1 - -* logrus: fix not exiting on `Fatalf` and `Fatalln` - -# 0.8.0 - -* logrus: defaults to stderr instead of stdout -* hooks/sentry: add special field for `*http.Request` -* formatter/text: ignore Windows for colors - -# 0.7.3 - -* formatter/\*: allow configuration of timestamp layout - -# 0.7.2 - -* formatter/text: Add configuration option for time format (#158) diff --git a/vendor/github.com/Sirupsen/logrus/README.md b/vendor/github.com/Sirupsen/logrus/README.md deleted file mode 100644 index bd9ffb6ed..000000000 --- a/vendor/github.com/Sirupsen/logrus/README.md +++ /dev/null @@ -1,356 +0,0 @@ -# Logrus :walrus: [![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus) [![godoc reference](https://godoc.org/github.com/Sirupsen/logrus?status.png)][godoc] - -Logrus is a structured logger for Go (golang), completely API compatible with -the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not -yet stable (pre 1.0). Logrus itself is completely stable and has been used in -many large deployments. The core API is unlikely to change much but please -version control your Logrus to make sure you aren't fetching latest `master` on -every build.** - -Nicely color-coded in development (when a TTY is attached, otherwise just -plain text): - -![Colored](http://i.imgur.com/PY7qMwd.png) - -With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash -or Splunk: - -```json -{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the -ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} - -{"level":"warning","msg":"The group's number increased tremendously!", -"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"A giant walrus appears!", -"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", -"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} - -{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, -"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} -``` - -With the default `log.Formatter = new(&log.TextFormatter{})` when a TTY is not -attached, the output is compatible with the -[logfmt](http://godoc.org/github.com/kr/logfmt) format: - -```text -time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 -time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 -time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true -time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 -time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 -time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true -exit status 1 -``` - -#### Example - -The simplest way to use Logrus is simply the package-level exported logger: - -```go -package main - -import ( - log "github.com/Sirupsen/logrus" -) - -func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - }).Info("A walrus appears") -} -``` - -Note that it's completely api-compatible with the stdlib logger, so you can -replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` -and you'll now have the flexibility of Logrus. You can customize it all you -want: - -```go -package main - -import ( - "os" - log "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/airbrake" -) - -func init() { - // Log as JSON instead of the default ASCII formatter. - log.SetFormatter(&log.JSONFormatter{}) - - // Use the Airbrake hook to report errors that have Error severity or above to - // an exception tracker. You can create custom hooks, see the Hooks section. - log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development")) - - // Output to stderr instead of stdout, could also be a file. - log.SetOutput(os.Stderr) - - // Only log the warning severity or above. - log.SetLevel(log.WarnLevel) -} - -func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") - - log.WithFields(log.Fields{ - "omg": true, - "number": 122, - }).Warn("The group's number increased tremendously!") - - log.WithFields(log.Fields{ - "omg": true, - "number": 100, - }).Fatal("The ice breaks!") - - // A common pattern is to re-use fields between logging statements by re-using - // the logrus.Entry returned from WithFields() - contextLogger := log.WithFields(log.Fields{ - "common": "this is a common field", - "other": "I also should be logged always", - }) - - contextLogger.Info("I'll be logged with common and other field") - contextLogger.Info("Me too") -} -``` - -For more advanced usage such as logging to multiple locations from the same -application, you can also create an instance of the `logrus` Logger: - -```go -package main - -import ( - "github.com/Sirupsen/logrus" -) - -// Create a new instance of the logger. You can have any number of instances. -var log = logrus.New() - -func main() { - // The API for setting attributes is a little different than the package level - // exported logger. See Godoc. - log.Out = os.Stderr - - log.WithFields(logrus.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") -} -``` - -#### Fields - -Logrus encourages careful, structured logging though logging fields instead of -long, unparseable error messages. For example, instead of: `log.Fatalf("Failed -to send event %s to topic %s with key %d")`, you should log the much more -discoverable: - -```go -log.WithFields(log.Fields{ - "event": event, - "topic": topic, - "key": key, -}).Fatal("Failed to send event") -``` - -We've found this API forces you to think about logging in a way that produces -much more useful logging messages. We've been in countless situations where just -a single added field to a log statement that was already there would've saved us -hours. The `WithFields` call is optional. - -In general, with Logrus using any of the `printf`-family functions should be -seen as a hint you should add a field, however, you can still use the -`printf`-family functions with Logrus. - -#### Hooks - -You can add hooks for logging levels. For example to send errors to an exception -tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to -multiple places simultaneously, e.g. syslog. - -Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in -`init`: - -```go -import ( - log "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/airbrake" - logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" - "log/syslog" -) - -func init() { - log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development")) - - hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") - if err != nil { - log.Error("Unable to connect to local syslog daemon") - } else { - log.AddHook(hook) - } -} -``` - - -| Hook | Description | -| ----- | ----------- | -| [Airbrake](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) | Send errors to an exception tracking service compatible with the Airbrake API. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. | -| [Papertrail](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) | Send errors to the Papertrail hosted logging service via UDP. | -| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | -| [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | -| [Sentry](https://github.com/Sirupsen/logrus/blob/master/hooks/sentry/sentry.go) | Send errors to the Sentry error logging and aggregation service. | -| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | -| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | -| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | -| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | -| [Graylog](https://github.com/gemnasium/logrus-hooks/tree/master/graylog) | Hook for logging to [Graylog](http://graylog2.org/) | -| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | -| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | -| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | -| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | -| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | -| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | - -#### Level logging - -Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. - -```go -log.Debug("Useful debugging information.") -log.Info("Something noteworthy happened!") -log.Warn("You should probably take a look at this.") -log.Error("Something failed but I'm not quitting.") -// Calls os.Exit(1) after logging -log.Fatal("Bye.") -// Calls panic() after logging -log.Panic("I'm bailing.") -``` - -You can set the logging level on a `Logger`, then it will only log entries with -that severity or anything above it: - -```go -// Will log anything that is info or above (warn, error, fatal, panic). Default. -log.SetLevel(log.InfoLevel) -``` - -It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose -environment if your application has that. - -#### Entries - -Besides the fields added with `WithField` or `WithFields` some fields are -automatically added to all logging events: - -1. `time`. The timestamp when the entry was created. -2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after - the `AddFields` call. E.g. `Failed to send event.` -3. `level`. The logging level. E.g. `info`. - -#### Environments - -Logrus has no notion of environment. - -If you wish for hooks and formatters to only be used in specific environments, -you should handle that yourself. For example, if your application has a global -variable `Environment`, which is a string representation of the environment you -could do: - -```go -import ( - log "github.com/Sirupsen/logrus" -) - -init() { - // do something here to set environment depending on an environment variable - // or command-line flag - if Environment == "production" { - log.SetFormatter(&logrus.JSONFormatter{}) - } else { - // The TextFormatter is default, you don't actually have to do this. - log.SetFormatter(&log.TextFormatter{}) - } -} -``` - -This configuration is how `logrus` was intended to be used, but JSON in -production is mostly only useful if you do log aggregation with tools like -Splunk or Logstash. - -#### Formatters - -The built-in logging formatters are: - -* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise - without colors. - * *Note:* to force colored output when there is no TTY, set the `ForceColors` - field to `true`. To force no colored output even if there is a TTY set the - `DisableColors` field to `true` -* `logrus.JSONFormatter`. Logs fields as JSON. -* `logrus_logstash.LogstashFormatter`. Logs fields as Logstash Events (http://logstash.net). - - ```go - logrus.SetFormatter(&logrus_logstash.LogstashFormatter{Type: “application_name"}) - ``` - -Third party logging formatters: - -* [`zalgo`](https://github.com/aybabtme/logzalgo): invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. - -You can define your formatter by implementing the `Formatter` interface, -requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a -`Fields` type (`map[string]interface{}`) with all your fields as well as the -default ones (see Entries section above): - -```go -type MyJSONFormatter struct { -} - -log.SetFormatter(new(MyJSONFormatter)) - -func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { - // Note this doesn't include Time, Level and Message which are available on - // the Entry. Consult `godoc` on information about those fields or read the - // source of the official loggers. - serialized, err := json.Marshal(entry.Data) - if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) - } - return append(serialized, '\n'), nil -} -``` - -#### Logger as an `io.Writer` - -Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it. - -```go -w := logger.Writer() -defer w.Close() - -srv := http.Server{ - // create a stdlib log.Logger that writes to - // logrus.Logger. - ErrorLog: log.New(w, "", 0), -} -``` - -Each line written to that writer will be printed the usual way, using formatters -and hooks. The level for those entries is `info`. - -#### Rotation - -Log rotation is not provided with Logrus. Log rotation should be done by an -external program (like `logrotate(8)`) that can compress and delete old log -entries. It should not be a feature of the application-level logger. - - -[godoc]: https://godoc.org/github.com/Sirupsen/logrus diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit.go b/vendor/github.com/Sirupsen/logrus/alt_exit.go new file mode 100644 index 000000000..8af90637a --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/alt_exit.go @@ -0,0 +1,64 @@ +package logrus + +// The following code was sourced and modified from the +// https://github.com/tebeka/atexit package governed by the following license: +// +// Copyright (c) 2012 Miki Tebeka . +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import ( + "fmt" + "os" +) + +var handlers = []func(){} + +func runHandler(handler func()) { + defer func() { + if err := recover(); err != nil { + fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err) + } + }() + + handler() +} + +func runHandlers() { + for _, handler := range handlers { + runHandler(handler) + } +} + +// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code) +func Exit(code int) { + runHandlers() + os.Exit(code) +} + +// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke +// all handlers. The handlers will also be invoked when any Fatal log entry is +// made. +// +// This method is useful when a caller wishes to use logrus to log a fatal +// message but also needs to gracefully shutdown. An example usecase could be +// closing database connections, or sending a alert that the application is +// closing. +func RegisterExitHandler(handler func()) { + handlers = append(handlers, handler) +} diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/Sirupsen/logrus/doc.go new file mode 100644 index 000000000..da67aba06 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/doc.go @@ -0,0 +1,26 @@ +/* +Package logrus is a structured logger for Go, completely API compatible with the standard library logger. + + +The simplest way to use Logrus is simply the package-level exported logger: + + package main + + import ( + log "github.com/sirupsen/logrus" + ) + + func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "number": 1, + "size": 10, + }).Info("A walrus appears") + } + +Output: + time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 + +For a full guide visit https://github.com/sirupsen/logrus +*/ +package logrus diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/Sirupsen/logrus/entry.go index 699ea035c..ca634a609 100644 --- a/vendor/github.com/Sirupsen/logrus/entry.go +++ b/vendor/github.com/Sirupsen/logrus/entry.go @@ -3,11 +3,25 @@ package logrus import ( "bytes" "fmt" - "io" "os" + "reflect" + "sync" "time" ) +var bufferPool *sync.Pool + +func init() { + bufferPool = &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + } +} + +// Defines the key when adding errors using WithError. +var ErrorKey = "error" + // An entry is the final or intermediate Logrus logging entry. It contains all // the fields passed with WithField{,s}. It's finally logged when Debug, Info, // Warn, Error, Fatal or Panic is called on it. These objects can be reused and @@ -22,35 +36,41 @@ type Entry struct { Time time.Time // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic + // This field will be set on entry firing and the value will be equal to the one in Logger struct field. Level Level // Message passed to Debug, Info, Warn, Error, Fatal or Panic Message string + + // When formatter is called in entry.log(), a Buffer may be set to entry + Buffer *bytes.Buffer + + // err may contain a field formatting error + err string } func NewEntry(logger *Logger) *Entry { return &Entry{ Logger: logger, - // Default is three fields, give a little extra room + // Default is five fields, give a little extra room Data: make(Fields, 5), } } -// Returns a reader for the entry, which is a proxy to the formatter. -func (entry *Entry) Reader() (*bytes.Buffer, error) { - serialized, err := entry.Logger.Formatter.Format(entry) - return bytes.NewBuffer(serialized), err -} - // Returns the string representation from the reader and ultimately the // formatter. func (entry *Entry) String() (string, error) { - reader, err := entry.Reader() + serialized, err := entry.Logger.Formatter.Format(entry) if err != nil { return "", err } + str := string(serialized) + return str, nil +} - return reader.String(), err +// Add an error as single field (using the key defined in ErrorKey) to the Entry. +func (entry *Entry) WithError(err error) *Entry { + return entry.WithField(ErrorKey, err) } // Add a single field to the Entry. @@ -60,52 +80,90 @@ func (entry *Entry) WithField(key string, value interface{}) *Entry { // Add a map of fields to the Entry. func (entry *Entry) WithFields(fields Fields) *Entry { - data := Fields{} + data := make(Fields, len(entry.Data)+len(fields)) for k, v := range entry.Data { data[k] = v } + var field_err string for k, v := range fields { - data[k] = v + if t := reflect.TypeOf(v); t != nil && t.Kind() == reflect.Func { + field_err = fmt.Sprintf("can not add field %q", k) + if entry.err != "" { + field_err = entry.err + ", " + field_err + } + } else { + data[k] = v + } } - return &Entry{Logger: entry.Logger, Data: data} + return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: field_err} } -func (entry *Entry) log(level Level, msg string) { - entry.Time = time.Now() +// Overrides the time of the Entry. +func (entry *Entry) WithTime(t time.Time) *Entry { + return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t} +} + +// This function is not declared with a pointer value because otherwise +// race conditions will occur when using multiple goroutines +func (entry Entry) log(level Level, msg string) { + var buffer *bytes.Buffer + + // Default to now, but allow users to override if they want. + // + // We don't have to worry about polluting future calls to Entry#log() + // with this assignment because this function is declared with a + // non-pointer receiver. + if entry.Time.IsZero() { + entry.Time = time.Now() + } + entry.Level = level entry.Message = msg - if err := entry.Logger.Hooks.Fire(level, entry); err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) - entry.Logger.mu.Unlock() - } + entry.fireHooks() - reader, err := entry.Reader() - if err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) - entry.Logger.mu.Unlock() - } + buffer = bufferPool.Get().(*bytes.Buffer) + buffer.Reset() + defer bufferPool.Put(buffer) + entry.Buffer = buffer - entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() + entry.write() - _, err = io.Copy(entry.Logger.Out, reader) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) - } + entry.Buffer = nil // To avoid Entry#log() returning a value that only would make sense for // panic() to use in Entry#Panic(), we avoid the allocation by checking // directly here. if level <= PanicLevel { - panic(entry) + panic(&entry) + } +} + +func (entry *Entry) fireHooks() { + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + err := entry.Logger.Hooks.Fire(entry.Level, entry) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) + } +} + +func (entry *Entry) write() { + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + serialized, err := entry.Logger.Formatter.Format(entry) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + } else { + _, err = entry.Logger.Out.Write(serialized) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + } } } func (entry *Entry) Debug(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { + if entry.Logger.IsLevelEnabled(DebugLevel) { entry.log(DebugLevel, fmt.Sprint(args...)) } } @@ -115,13 +173,13 @@ func (entry *Entry) Print(args ...interface{}) { } func (entry *Entry) Info(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { + if entry.Logger.IsLevelEnabled(InfoLevel) { entry.log(InfoLevel, fmt.Sprint(args...)) } } func (entry *Entry) Warn(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { + if entry.Logger.IsLevelEnabled(WarnLevel) { entry.log(WarnLevel, fmt.Sprint(args...)) } } @@ -131,20 +189,20 @@ func (entry *Entry) Warning(args ...interface{}) { } func (entry *Entry) Error(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { + if entry.Logger.IsLevelEnabled(ErrorLevel) { entry.log(ErrorLevel, fmt.Sprint(args...)) } } func (entry *Entry) Fatal(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { + if entry.Logger.IsLevelEnabled(FatalLevel) { entry.log(FatalLevel, fmt.Sprint(args...)) } - os.Exit(1) + Exit(1) } func (entry *Entry) Panic(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { + if entry.Logger.IsLevelEnabled(PanicLevel) { entry.log(PanicLevel, fmt.Sprint(args...)) } panic(fmt.Sprint(args...)) @@ -153,13 +211,13 @@ func (entry *Entry) Panic(args ...interface{}) { // Entry Printf family functions func (entry *Entry) Debugf(format string, args ...interface{}) { - if entry.Logger.Level >= DebugLevel { + if entry.Logger.IsLevelEnabled(DebugLevel) { entry.Debug(fmt.Sprintf(format, args...)) } } func (entry *Entry) Infof(format string, args ...interface{}) { - if entry.Logger.Level >= InfoLevel { + if entry.Logger.IsLevelEnabled(InfoLevel) { entry.Info(fmt.Sprintf(format, args...)) } } @@ -169,7 +227,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) { } func (entry *Entry) Warnf(format string, args ...interface{}) { - if entry.Logger.Level >= WarnLevel { + if entry.Logger.IsLevelEnabled(WarnLevel) { entry.Warn(fmt.Sprintf(format, args...)) } } @@ -179,20 +237,20 @@ func (entry *Entry) Warningf(format string, args ...interface{}) { } func (entry *Entry) Errorf(format string, args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { + if entry.Logger.IsLevelEnabled(ErrorLevel) { entry.Error(fmt.Sprintf(format, args...)) } } func (entry *Entry) Fatalf(format string, args ...interface{}) { - if entry.Logger.Level >= FatalLevel { + if entry.Logger.IsLevelEnabled(FatalLevel) { entry.Fatal(fmt.Sprintf(format, args...)) } - os.Exit(1) + Exit(1) } func (entry *Entry) Panicf(format string, args ...interface{}) { - if entry.Logger.Level >= PanicLevel { + if entry.Logger.IsLevelEnabled(PanicLevel) { entry.Panic(fmt.Sprintf(format, args...)) } } @@ -200,13 +258,13 @@ func (entry *Entry) Panicf(format string, args ...interface{}) { // Entry Println family functions func (entry *Entry) Debugln(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { + if entry.Logger.IsLevelEnabled(DebugLevel) { entry.Debug(entry.sprintlnn(args...)) } } func (entry *Entry) Infoln(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { + if entry.Logger.IsLevelEnabled(InfoLevel) { entry.Info(entry.sprintlnn(args...)) } } @@ -216,7 +274,7 @@ func (entry *Entry) Println(args ...interface{}) { } func (entry *Entry) Warnln(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { + if entry.Logger.IsLevelEnabled(WarnLevel) { entry.Warn(entry.sprintlnn(args...)) } } @@ -226,20 +284,20 @@ func (entry *Entry) Warningln(args ...interface{}) { } func (entry *Entry) Errorln(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { + if entry.Logger.IsLevelEnabled(ErrorLevel) { entry.Error(entry.sprintlnn(args...)) } } func (entry *Entry) Fatalln(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { + if entry.Logger.IsLevelEnabled(FatalLevel) { entry.Fatal(entry.sprintlnn(args...)) } - os.Exit(1) + Exit(1) } func (entry *Entry) Panicln(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { + if entry.Logger.IsLevelEnabled(PanicLevel) { entry.Panic(entry.sprintlnn(args...)) } } diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/Sirupsen/logrus/exported.go index a67e1b802..fb2a7a1f0 100644 --- a/vendor/github.com/Sirupsen/logrus/exported.go +++ b/vendor/github.com/Sirupsen/logrus/exported.go @@ -2,6 +2,7 @@ package logrus import ( "io" + "time" ) var ( @@ -15,37 +16,37 @@ func StandardLogger() *Logger { // SetOutput sets the standard logger output. func SetOutput(out io.Writer) { - std.mu.Lock() - defer std.mu.Unlock() - std.Out = out + std.SetOutput(out) } // SetFormatter sets the standard logger formatter. func SetFormatter(formatter Formatter) { - std.mu.Lock() - defer std.mu.Unlock() - std.Formatter = formatter + std.SetFormatter(formatter) } // SetLevel sets the standard logger level. func SetLevel(level Level) { - std.mu.Lock() - defer std.mu.Unlock() - std.Level = level + std.SetLevel(level) } // GetLevel returns the standard logger level. func GetLevel() Level { - std.mu.Lock() - defer std.mu.Unlock() - return std.Level + return std.GetLevel() +} + +// IsLevelEnabled checks if the log level of the standard logger is greater than the level param +func IsLevelEnabled(level Level) bool { + return std.IsLevelEnabled(level) } // AddHook adds a hook to the standard logger hooks. func AddHook(hook Hook) { - std.mu.Lock() - defer std.mu.Unlock() - std.Hooks.Add(hook) + std.AddHook(hook) +} + +// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. +func WithError(err error) *Entry { + return std.WithField(ErrorKey, err) } // WithField creates an entry from the standard logger and adds a field to @@ -67,6 +68,15 @@ func WithFields(fields Fields) *Entry { return std.WithFields(fields) } +// WithTime creats an entry from the standard logger and overrides the time of +// logs generated with it. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithTime(t time.Time) *Entry { + return std.WithTime(t) +} + // Debug logs a message at level Debug on the standard logger. func Debug(args ...interface{}) { std.Debug(args...) @@ -102,7 +112,7 @@ func Panic(args ...interface{}) { std.Panic(args...) } -// Fatal logs a message at level Fatal on the standard logger. +// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1. func Fatal(args ...interface{}) { std.Fatal(args...) } @@ -142,7 +152,7 @@ func Panicf(format string, args ...interface{}) { std.Panicf(format, args...) } -// Fatalf logs a message at level Fatal on the standard logger. +// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1. func Fatalf(format string, args ...interface{}) { std.Fatalf(format, args...) } @@ -182,7 +192,7 @@ func Panicln(args ...interface{}) { std.Panicln(args...) } -// Fatalln logs a message at level Fatal on the standard logger. +// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1. func Fatalln(args ...interface{}) { std.Fatalln(args...) } diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/Sirupsen/logrus/formatter.go index 104d689f1..be2f3fcee 100644 --- a/vendor/github.com/Sirupsen/logrus/formatter.go +++ b/vendor/github.com/Sirupsen/logrus/formatter.go @@ -2,7 +2,14 @@ package logrus import "time" -const DefaultTimestampFormat = time.RFC3339 +// Default key names for the default fields +const ( + defaultTimestampFormat = time.RFC3339 + FieldKeyMsg = "msg" + FieldKeyLevel = "level" + FieldKeyTime = "time" + FieldKeyLogrusError = "logrus_error" +) // The Formatter interface is used to implement a custom Formatter. It takes an // `Entry`. It exposes all the fields, including the default ones: @@ -30,19 +37,28 @@ type Formatter interface { // // It's not exported because it's still using Data in an opinionated way. It's to // avoid code duplication between the two default formatters. -func prefixFieldClashes(data Fields) { - _, ok := data["time"] - if ok { - data["fields.time"] = data["time"] +func prefixFieldClashes(data Fields, fieldMap FieldMap) { + timeKey := fieldMap.resolve(FieldKeyTime) + if t, ok := data[timeKey]; ok { + data["fields."+timeKey] = t + delete(data, timeKey) } - _, ok = data["msg"] - if ok { - data["fields.msg"] = data["msg"] + msgKey := fieldMap.resolve(FieldKeyMsg) + if m, ok := data[msgKey]; ok { + data["fields."+msgKey] = m + delete(data, msgKey) } - _, ok = data["level"] - if ok { - data["fields.level"] = data["level"] + levelKey := fieldMap.resolve(FieldKeyLevel) + if l, ok := data[levelKey]; ok { + data["fields."+levelKey] = l + delete(data, levelKey) + } + + logrusErrKey := fieldMap.resolve(FieldKeyLogrusError) + if l, ok := data[logrusErrKey]; ok { + data["fields."+logrusErrKey] = l + delete(data, logrusErrKey) } } diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/Sirupsen/logrus/json_formatter.go index 2ad6dc5cf..ef8d07460 100644 --- a/vendor/github.com/Sirupsen/logrus/json_formatter.go +++ b/vendor/github.com/Sirupsen/logrus/json_formatter.go @@ -1,41 +1,100 @@ package logrus import ( + "bytes" "encoding/json" "fmt" ) +type fieldKey string + +// FieldMap allows customization of the key names for default fields. +type FieldMap map[fieldKey]string + +func (f FieldMap) resolve(key fieldKey) string { + if k, ok := f[key]; ok { + return k + } + + return string(key) +} + +// JSONFormatter formats logs into parsable json type JSONFormatter struct { // TimestampFormat sets the format used for marshaling timestamps. TimestampFormat string + + // DisableTimestamp allows disabling automatic timestamps in output + DisableTimestamp bool + + // DataKey allows users to put all the log entry parameters into a nested dictionary at a given key. + DataKey string + + // FieldMap allows users to customize the names of keys for default fields. + // As an example: + // formatter := &JSONFormatter{ + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyMsg: "@message", + // }, + // } + FieldMap FieldMap + + // PrettyPrint will indent all json logs + PrettyPrint bool } +// Format renders a single log entry func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { data := make(Fields, len(entry.Data)+3) for k, v := range entry.Data { switch v := v.(type) { case error: // Otherwise errors are ignored by `encoding/json` - // https://github.com/Sirupsen/logrus/issues/137 + // https://github.com/sirupsen/logrus/issues/137 data[k] = v.Error() default: data[k] = v } } - prefixFieldClashes(data) + + if f.DataKey != "" { + newData := make(Fields, 4) + newData[f.DataKey] = data + data = newData + } + + prefixFieldClashes(data, f.FieldMap) timestampFormat := f.TimestampFormat if timestampFormat == "" { - timestampFormat = DefaultTimestampFormat + timestampFormat = defaultTimestampFormat } - data["time"] = entry.Time.Format(timestampFormat) - data["msg"] = entry.Message - data["level"] = entry.Level.String() + if entry.err != "" { + data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err + } + if !f.DisableTimestamp { + data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat) + } + data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message + data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() - serialized, err := json.Marshal(data) - if err != nil { + var b *bytes.Buffer + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} + } + + encoder := json.NewEncoder(b) + if f.PrettyPrint { + encoder.SetIndent("", " ") + } + if err := encoder.Encode(data); err != nil { return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) } - return append(serialized, '\n'), nil + + return b.Bytes(), nil } diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/Sirupsen/logrus/logger.go index e4974bfbe..b67bfcbd3 100644 --- a/vendor/github.com/Sirupsen/logrus/logger.go +++ b/vendor/github.com/Sirupsen/logrus/logger.go @@ -4,12 +4,14 @@ import ( "io" "os" "sync" + "sync/atomic" + "time" ) type Logger struct { // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a - // file, or leave it default which is `os.Stdout`. You can also set this to - // something more adventorous, such as logging to Kafka. + // file, or leave it default which is `os.Stderr`. You can also set this to + // something more adventurous, such as logging to Kafka. Out io.Writer // Hooks for the logger instance. These allow firing events based on logging // levels and log entries. For example, to send errors to an error tracking @@ -24,10 +26,33 @@ type Logger struct { Formatter Formatter // The logging level the logger should log at. This is typically (and defaults // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be - // logged. `logrus.Debug` is useful in + // logged. Level Level - // Used to sync writing to the log. - mu sync.Mutex + // Used to sync writing to the log. Locking is enabled by Default + mu MutexWrap + // Reusable empty entry + entryPool sync.Pool +} + +type MutexWrap struct { + lock sync.Mutex + disabled bool +} + +func (mw *MutexWrap) Lock() { + if !mw.disabled { + mw.lock.Lock() + } +} + +func (mw *MutexWrap) Unlock() { + if !mw.disabled { + mw.lock.Unlock() + } +} + +func (mw *MutexWrap) Disable() { + mw.disabled = true } // Creates a new logger. Configuration should be set by changing `Formatter`, @@ -51,156 +76,292 @@ func New() *Logger { } } -// Adds a field to the log entry, note that you it doesn't log until you call -// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. -// Ff you want multiple fields, use `WithFields`. +func (logger *Logger) newEntry() *Entry { + entry, ok := logger.entryPool.Get().(*Entry) + if ok { + return entry + } + return NewEntry(logger) +} + +func (logger *Logger) releaseEntry(entry *Entry) { + entry.Data = map[string]interface{}{} + logger.entryPool.Put(entry) +} + +// Adds a field to the log entry, note that it doesn't log until you call +// Debug, Print, Info, Warn, Error, Fatal or Panic. It only creates a log entry. +// If you want multiple fields, use `WithFields`. func (logger *Logger) WithField(key string, value interface{}) *Entry { - return NewEntry(logger).WithField(key, value) + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithField(key, value) } // Adds a struct of fields to the log entry. All it does is call `WithField` for // each `Field`. func (logger *Logger) WithFields(fields Fields) *Entry { - return NewEntry(logger).WithFields(fields) + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithFields(fields) +} + +// Add an error as single field to the log entry. All it does is call +// `WithError` for the given `error`. +func (logger *Logger) WithError(err error) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithError(err) +} + +// Overrides the time of the log entry. +func (logger *Logger) WithTime(t time.Time) *Entry { + entry := logger.newEntry() + defer logger.releaseEntry(entry) + return entry.WithTime(t) } func (logger *Logger) Debugf(format string, args ...interface{}) { - if logger.Level >= DebugLevel { - NewEntry(logger).Debugf(format, args...) + if logger.IsLevelEnabled(DebugLevel) { + entry := logger.newEntry() + entry.Debugf(format, args...) + logger.releaseEntry(entry) } } func (logger *Logger) Infof(format string, args ...interface{}) { - if logger.Level >= InfoLevel { - NewEntry(logger).Infof(format, args...) + if logger.IsLevelEnabled(InfoLevel) { + entry := logger.newEntry() + entry.Infof(format, args...) + logger.releaseEntry(entry) } } func (logger *Logger) Printf(format string, args ...interface{}) { - NewEntry(logger).Printf(format, args...) + entry := logger.newEntry() + entry.Printf(format, args...) + logger.releaseEntry(entry) } func (logger *Logger) Warnf(format string, args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warnf(format, args...) + if logger.IsLevelEnabled(WarnLevel) { + entry := logger.newEntry() + entry.Warnf(format, args...) + logger.releaseEntry(entry) } } func (logger *Logger) Warningf(format string, args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warnf(format, args...) + if logger.IsLevelEnabled(WarnLevel) { + entry := logger.newEntry() + entry.Warnf(format, args...) + logger.releaseEntry(entry) } } func (logger *Logger) Errorf(format string, args ...interface{}) { - if logger.Level >= ErrorLevel { - NewEntry(logger).Errorf(format, args...) + if logger.IsLevelEnabled(ErrorLevel) { + entry := logger.newEntry() + entry.Errorf(format, args...) + logger.releaseEntry(entry) } } func (logger *Logger) Fatalf(format string, args ...interface{}) { - if logger.Level >= FatalLevel { - NewEntry(logger).Fatalf(format, args...) + if logger.IsLevelEnabled(FatalLevel) { + entry := logger.newEntry() + entry.Fatalf(format, args...) + logger.releaseEntry(entry) } - os.Exit(1) + Exit(1) } func (logger *Logger) Panicf(format string, args ...interface{}) { - if logger.Level >= PanicLevel { - NewEntry(logger).Panicf(format, args...) + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + entry.Panicf(format, args...) + logger.releaseEntry(entry) } } func (logger *Logger) Debug(args ...interface{}) { - if logger.Level >= DebugLevel { - NewEntry(logger).Debug(args...) + if logger.IsLevelEnabled(DebugLevel) { + entry := logger.newEntry() + entry.Debug(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Info(args ...interface{}) { - if logger.Level >= InfoLevel { - NewEntry(logger).Info(args...) + if logger.IsLevelEnabled(InfoLevel) { + entry := logger.newEntry() + entry.Info(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Print(args ...interface{}) { - NewEntry(logger).Info(args...) + entry := logger.newEntry() + entry.Info(args...) + logger.releaseEntry(entry) } func (logger *Logger) Warn(args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warn(args...) + if logger.IsLevelEnabled(WarnLevel) { + entry := logger.newEntry() + entry.Warn(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Warning(args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warn(args...) + if logger.IsLevelEnabled(WarnLevel) { + entry := logger.newEntry() + entry.Warn(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Error(args ...interface{}) { - if logger.Level >= ErrorLevel { - NewEntry(logger).Error(args...) + if logger.IsLevelEnabled(ErrorLevel) { + entry := logger.newEntry() + entry.Error(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Fatal(args ...interface{}) { - if logger.Level >= FatalLevel { - NewEntry(logger).Fatal(args...) + if logger.IsLevelEnabled(FatalLevel) { + entry := logger.newEntry() + entry.Fatal(args...) + logger.releaseEntry(entry) } - os.Exit(1) + Exit(1) } func (logger *Logger) Panic(args ...interface{}) { - if logger.Level >= PanicLevel { - NewEntry(logger).Panic(args...) + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + entry.Panic(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Debugln(args ...interface{}) { - if logger.Level >= DebugLevel { - NewEntry(logger).Debugln(args...) + if logger.IsLevelEnabled(DebugLevel) { + entry := logger.newEntry() + entry.Debugln(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Infoln(args ...interface{}) { - if logger.Level >= InfoLevel { - NewEntry(logger).Infoln(args...) + if logger.IsLevelEnabled(InfoLevel) { + entry := logger.newEntry() + entry.Infoln(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Println(args ...interface{}) { - NewEntry(logger).Println(args...) + entry := logger.newEntry() + entry.Println(args...) + logger.releaseEntry(entry) } func (logger *Logger) Warnln(args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warnln(args...) + if logger.IsLevelEnabled(WarnLevel) { + entry := logger.newEntry() + entry.Warnln(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Warningln(args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warnln(args...) + if logger.IsLevelEnabled(WarnLevel) { + entry := logger.newEntry() + entry.Warnln(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Errorln(args ...interface{}) { - if logger.Level >= ErrorLevel { - NewEntry(logger).Errorln(args...) + if logger.IsLevelEnabled(ErrorLevel) { + entry := logger.newEntry() + entry.Errorln(args...) + logger.releaseEntry(entry) } } func (logger *Logger) Fatalln(args ...interface{}) { - if logger.Level >= FatalLevel { - NewEntry(logger).Fatalln(args...) + if logger.IsLevelEnabled(FatalLevel) { + entry := logger.newEntry() + entry.Fatalln(args...) + logger.releaseEntry(entry) } - os.Exit(1) + Exit(1) } func (logger *Logger) Panicln(args ...interface{}) { - if logger.Level >= PanicLevel { - NewEntry(logger).Panicln(args...) + if logger.IsLevelEnabled(PanicLevel) { + entry := logger.newEntry() + entry.Panicln(args...) + logger.releaseEntry(entry) } } + +//When file is opened with appending mode, it's safe to +//write concurrently to a file (within 4k message on Linux). +//In these cases user can choose to disable the lock. +func (logger *Logger) SetNoLock() { + logger.mu.Disable() +} + +func (logger *Logger) level() Level { + return Level(atomic.LoadUint32((*uint32)(&logger.Level))) +} + +// SetLevel sets the logger level. +func (logger *Logger) SetLevel(level Level) { + atomic.StoreUint32((*uint32)(&logger.Level), uint32(level)) +} + +// GetLevel returns the logger level. +func (logger *Logger) GetLevel() Level { + return logger.level() +} + +// AddHook adds a hook to the logger hooks. +func (logger *Logger) AddHook(hook Hook) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.Hooks.Add(hook) +} + +// IsLevelEnabled checks if the log level of the logger is greater than the level param +func (logger *Logger) IsLevelEnabled(level Level) bool { + return logger.level() >= level +} + +// SetFormatter sets the logger formatter. +func (logger *Logger) SetFormatter(formatter Formatter) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.Formatter = formatter +} + +// SetOutput sets the logger output. +func (logger *Logger) SetOutput(output io.Writer) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.Out = output +} + +// ReplaceHooks replaces the logger hooks and returns the old ones +func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks { + logger.mu.Lock() + oldHooks := logger.Hooks + logger.Hooks = hooks + logger.mu.Unlock() + return oldHooks +} diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/Sirupsen/logrus/logrus.go index 43ee12e90..fa0b9dea8 100644 --- a/vendor/github.com/Sirupsen/logrus/logrus.go +++ b/vendor/github.com/Sirupsen/logrus/logrus.go @@ -3,13 +3,14 @@ package logrus import ( "fmt" "log" + "strings" ) // Fields type, used to pass to `WithFields`. type Fields map[string]interface{} // Level type -type Level uint8 +type Level uint32 // Convert the Level to a string. E.g. PanicLevel becomes "panic". func (level Level) String() string { @@ -33,7 +34,7 @@ func (level Level) String() string { // ParseLevel takes a string level and returns the Logrus log level constant. func ParseLevel(lvl string) (Level, error) { - switch lvl { + switch strings.ToLower(lvl) { case "panic": return PanicLevel, nil case "fatal": @@ -52,6 +53,16 @@ func ParseLevel(lvl string) (Level, error) { return l, fmt.Errorf("not a valid logrus Level: %q", lvl) } +// A constant exposing all logging levels +var AllLevels = []Level{ + PanicLevel, + FatalLevel, + ErrorLevel, + WarnLevel, + InfoLevel, + DebugLevel, +} + // These are the different logging levels. You can set the logging level to log // on your instance of logger, obtained with `logrus.New()`. const ( @@ -74,7 +85,11 @@ const ( ) // Won't compile if StdLogger can't be realized by a log.Logger -var _ StdLogger = &log.Logger{} +var ( + _ StdLogger = &log.Logger{} + _ StdLogger = &Entry{} + _ StdLogger = &Logger{} +) // StdLogger is what your logrus-enabled library should take, that way // it'll accept a stdlib logger and a logrus logger. There's no standard @@ -92,3 +107,44 @@ type StdLogger interface { Panicf(string, ...interface{}) Panicln(...interface{}) } + +// The FieldLogger interface generalizes the Entry and Logger types +type FieldLogger interface { + WithField(key string, value interface{}) *Entry + WithFields(fields Fields) *Entry + WithError(err error) *Entry + + Debugf(format string, args ...interface{}) + Infof(format string, args ...interface{}) + Printf(format string, args ...interface{}) + Warnf(format string, args ...interface{}) + Warningf(format string, args ...interface{}) + Errorf(format string, args ...interface{}) + Fatalf(format string, args ...interface{}) + Panicf(format string, args ...interface{}) + + Debug(args ...interface{}) + Info(args ...interface{}) + Print(args ...interface{}) + Warn(args ...interface{}) + Warning(args ...interface{}) + Error(args ...interface{}) + Fatal(args ...interface{}) + Panic(args ...interface{}) + + Debugln(args ...interface{}) + Infoln(args ...interface{}) + Println(args ...interface{}) + Warnln(args ...interface{}) + Warningln(args ...interface{}) + Errorln(args ...interface{}) + Fatalln(args ...interface{}) + Panicln(args ...interface{}) + + // IsDebugEnabled() bool + // IsInfoEnabled() bool + // IsWarnEnabled() bool + // IsErrorEnabled() bool + // IsFatalEnabled() bool + // IsPanicEnabled() bool +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go deleted file mode 100644 index 71f8d67a5..000000000 --- a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build darwin freebsd openbsd netbsd dragonfly - -package logrus - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA - -type Termios syscall.Termios diff --git a/vendor/github.com/Sirupsen/logrus/terminal_check_appengine.go b/vendor/github.com/Sirupsen/logrus/terminal_check_appengine.go new file mode 100644 index 000000000..2403de981 --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_check_appengine.go @@ -0,0 +1,11 @@ +// +build appengine + +package logrus + +import ( + "io" +) + +func checkIfTerminal(w io.Writer) bool { + return true +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_check_js.go b/vendor/github.com/Sirupsen/logrus/terminal_check_js.go new file mode 100644 index 000000000..0c209750a --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_check_js.go @@ -0,0 +1,11 @@ +// +build js + +package logrus + +import ( + "io" +) + +func checkIfTerminal(w io.Writer) bool { + return false +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go new file mode 100644 index 000000000..cf309d6fb --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go @@ -0,0 +1,19 @@ +// +build !appengine,!js,!windows + +package logrus + +import ( + "io" + "os" + + "golang.org/x/crypto/ssh/terminal" +) + +func checkIfTerminal(w io.Writer) bool { + switch v := w.(type) { + case *os.File: + return terminal.IsTerminal(int(v.Fd())) + default: + return false + } +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/Sirupsen/logrus/terminal_check_windows.go new file mode 100644 index 000000000..3b9d2864c --- /dev/null +++ b/vendor/github.com/Sirupsen/logrus/terminal_check_windows.go @@ -0,0 +1,20 @@ +// +build !appengine,!js,windows + +package logrus + +import ( + "io" + "os" + "syscall" +) + +func checkIfTerminal(w io.Writer) bool { + switch v := w.(type) { + case *os.File: + var mode uint32 + err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode) + return err == nil + default: + return false + } +} diff --git a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go index 4bb537602..3dbd23720 100644 --- a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go +++ b/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go @@ -1,21 +1,8 @@ -// Based on ssh/terminal: -// Copyright 2011 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 linux darwin freebsd openbsd netbsd dragonfly +// +build !windows package logrus -import ( - "syscall" - "unsafe" -) +import "io" -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal() bool { - fd := syscall.Stdout - var termios Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 +func initTerminal(w io.Writer) { } diff --git a/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/vendor/github.com/Sirupsen/logrus/terminal_windows.go index 2e09f6f7e..b4ef5286c 100644 --- a/vendor/github.com/Sirupsen/logrus/terminal_windows.go +++ b/vendor/github.com/Sirupsen/logrus/terminal_windows.go @@ -1,27 +1,18 @@ -// Based on ssh/terminal: -// Copyright 2011 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 windows +// +build !appengine,!js,windows package logrus import ( + "io" + "os" "syscall" - "unsafe" -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") -var ( - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + sequences "github.com/konsorten/go-windows-terminal-sequences" ) -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal() bool { - fd := syscall.Stdout - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 +func initTerminal(w io.Writer) { + switch v := w.(type) { + case *os.File: + sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true) + } } diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/Sirupsen/logrus/text_formatter.go index 17cc29848..d4663b8c2 100644 --- a/vendor/github.com/Sirupsen/logrus/text_formatter.go +++ b/vendor/github.com/Sirupsen/logrus/text_formatter.go @@ -3,9 +3,10 @@ package logrus import ( "bytes" "fmt" - "runtime" + "os" "sort" "strings" + "sync" "time" ) @@ -14,24 +15,20 @@ const ( red = 31 green = 32 yellow = 33 - blue = 34 + blue = 36 gray = 37 ) var ( baseTimestamp time.Time - isTerminal bool + emptyFieldMap FieldMap ) func init() { baseTimestamp = time.Now() - isTerminal = IsTerminal() -} - -func miniTS() int { - return int(time.Since(baseTimestamp) / time.Second) } +// TextFormatter formats logs into text type TextFormatter struct { // Set to true to bypass checking for a TTY before outputting colors. ForceColors bool @@ -39,6 +36,9 @@ type TextFormatter struct { // Force disabling colors. DisableColors bool + // Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/ + EnvironmentOverrideColors bool + // Disable timestamp logging. useful when output is redirected to logging // system that already adds timestamps. DisableTimestamp bool @@ -54,39 +54,125 @@ type TextFormatter struct { // that log extremely frequently and don't use the JSON formatter this may not // be desired. DisableSorting bool + + // The keys sorting function, when uninitialized it uses sort.Strings. + SortingFunc func([]string) + + // Disables the truncation of the level text to 4 characters. + DisableLevelTruncation bool + + // QuoteEmptyFields will wrap empty fields in quotes if true + QuoteEmptyFields bool + + // Whether the logger's out is to a terminal + isTerminal bool + + // FieldMap allows users to customize the names of keys for default fields. + // As an example: + // formatter := &TextFormatter{ + // FieldMap: FieldMap{ + // FieldKeyTime: "@timestamp", + // FieldKeyLevel: "@level", + // FieldKeyMsg: "@message"}} + FieldMap FieldMap + + terminalInitOnce sync.Once } +func (f *TextFormatter) init(entry *Entry) { + if entry.Logger != nil { + f.isTerminal = checkIfTerminal(entry.Logger.Out) + + if f.isTerminal { + initTerminal(entry.Logger.Out) + } + } +} + +func (f *TextFormatter) isColored() bool { + isColored := f.ForceColors || f.isTerminal + + if f.EnvironmentOverrideColors { + if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" { + isColored = true + } else if ok && force == "0" { + isColored = false + } else if os.Getenv("CLICOLOR") == "0" { + isColored = false + } + } + + return isColored && !f.DisableColors +} + +// Format renders a single log entry func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - var keys []string = make([]string, 0, len(entry.Data)) + prefixFieldClashes(entry.Data, f.FieldMap) + + keys := make([]string, 0, len(entry.Data)) for k := range entry.Data { keys = append(keys, k) } - if !f.DisableSorting { - sort.Strings(keys) + fixedKeys := make([]string, 0, 4+len(entry.Data)) + if !f.DisableTimestamp { + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime)) + } + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLevel)) + if entry.Message != "" { + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyMsg)) + } + if entry.err != "" { + fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError)) } - b := &bytes.Buffer{} + if !f.DisableSorting { + if f.SortingFunc == nil { + sort.Strings(keys) + fixedKeys = append(fixedKeys, keys...) + } else { + if !f.isColored() { + fixedKeys = append(fixedKeys, keys...) + f.SortingFunc(fixedKeys) + } else { + f.SortingFunc(keys) + } + } + } else { + fixedKeys = append(fixedKeys, keys...) + } - prefixFieldClashes(entry.Data) + var b *bytes.Buffer + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} + } - isColorTerminal := isTerminal && (runtime.GOOS != "windows") - isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors + f.terminalInitOnce.Do(func() { f.init(entry) }) timestampFormat := f.TimestampFormat if timestampFormat == "" { - timestampFormat = DefaultTimestampFormat + timestampFormat = defaultTimestampFormat } - if isColored { + if f.isColored() { f.printColored(b, entry, keys, timestampFormat) } else { - if !f.DisableTimestamp { - f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) - } - f.appendKeyValue(b, "level", entry.Level.String()) - f.appendKeyValue(b, "msg", entry.Message) - for _, key := range keys { - f.appendKeyValue(b, key, entry.Data[key]) + for _, key := range fixedKeys { + var value interface{} + switch key { + case f.FieldMap.resolve(FieldKeyTime): + value = entry.Time.Format(timestampFormat) + case f.FieldMap.resolve(FieldKeyLevel): + value = entry.Level.String() + case f.FieldMap.resolve(FieldKeyMsg): + value = entry.Message + case f.FieldMap.resolve(FieldKeyLogrusError): + value = entry.err + default: + value = entry.Data[key] + } + f.appendKeyValue(b, key, value) } } @@ -107,53 +193,62 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin levelColor = blue } - levelText := strings.ToUpper(entry.Level.String())[0:4] + levelText := strings.ToUpper(entry.Level.String()) + if !f.DisableLevelTruncation { + levelText = levelText[0:4] + } + + // Remove a single newline if it already exists in the message to keep + // the behavior of logrus text_formatter the same as the stdlib log package + entry.Message = strings.TrimSuffix(entry.Message, "\n") - if !f.FullTimestamp { - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) + if f.DisableTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message) + } else if !f.FullTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message) } else { fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) } for _, k := range keys { v := entry.Data[k] - fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v) + fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k) + f.appendValue(b, v) } } -func needsQuoting(text string) bool { +func (f *TextFormatter) needsQuoting(text string) bool { + if f.QuoteEmptyFields && len(text) == 0 { + return true + } for _, ch := range text { if !((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || - ch == '-' || ch == '.') { - return false + ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') { + return true } } - return true + return false } func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { - + if b.Len() > 0 { + b.WriteByte(' ') + } b.WriteString(key) b.WriteByte('=') + f.appendValue(b, value) +} - switch value := value.(type) { - case string: - if needsQuoting(value) { - b.WriteString(value) - } else { - fmt.Fprintf(b, "%q", value) - } - case error: - errmsg := value.Error() - if needsQuoting(errmsg) { - b.WriteString(errmsg) - } else { - fmt.Fprintf(b, "%q", value) - } - default: - fmt.Fprint(b, value) +func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { + stringVal, ok := value.(string) + if !ok { + stringVal = fmt.Sprint(value) } - b.WriteByte(' ') + if !f.needsQuoting(stringVal) { + b.WriteString(stringVal) + } else { + b.WriteString(fmt.Sprintf("%q", stringVal)) + } } diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/Sirupsen/logrus/writer.go index 1e30b1c75..7bdebedc6 100644 --- a/vendor/github.com/Sirupsen/logrus/writer.go +++ b/vendor/github.com/Sirupsen/logrus/writer.go @@ -7,21 +7,52 @@ import ( ) func (logger *Logger) Writer() *io.PipeWriter { + return logger.WriterLevel(InfoLevel) +} + +func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { + return NewEntry(logger).WriterLevel(level) +} + +func (entry *Entry) Writer() *io.PipeWriter { + return entry.WriterLevel(InfoLevel) +} + +func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { reader, writer := io.Pipe() - go logger.writerScanner(reader) + var printFunc func(args ...interface{}) + + switch level { + case DebugLevel: + printFunc = entry.Debug + case InfoLevel: + printFunc = entry.Info + case WarnLevel: + printFunc = entry.Warn + case ErrorLevel: + printFunc = entry.Error + case FatalLevel: + printFunc = entry.Fatal + case PanicLevel: + printFunc = entry.Panic + default: + printFunc = entry.Print + } + + go entry.writerScanner(reader, printFunc) runtime.SetFinalizer(writer, writerFinalizer) return writer } -func (logger *Logger) writerScanner(reader *io.PipeReader) { +func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { scanner := bufio.NewScanner(reader) for scanner.Scan() { - logger.Print(scanner.Text()) + printFunc(scanner.Text()) } if err := scanner.Err(); err != nil { - logger.Errorf("Error while reading from Writer: %s", err) + entry.Errorf("Error while reading from Writer: %s", err) } reader.Close() } diff --git a/vendor/github.com/blang/semver/README.md b/vendor/github.com/blang/semver/README.md deleted file mode 100644 index 4399639e2..000000000 --- a/vendor/github.com/blang/semver/README.md +++ /dev/null @@ -1,191 +0,0 @@ -semver for golang [![Build Status](https://drone.io/github.com/blang/semver/status.png)](https://drone.io/github.com/blang/semver/latest) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master) -====== - -semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`. - -Usage ------ -```bash -$ go get github.com/blang/semver -``` -Note: Always vendor your dependencies or fix on a specific version tag. - -```go -import github.com/blang/semver -v1, err := semver.Make("1.0.0-beta") -v2, err := semver.Make("2.0.0-beta") -v1.Compare(v2) -``` - -Also check the [GoDocs](http://godoc.org/github.com/blang/semver). - -Why should I use this lib? ------ - -- Fully spec compatible -- No reflection -- No regex -- Fully tested (Coverage >99%) -- Readable parsing/validation errors -- Fast (See [Benchmarks](#benchmarks)) -- Only Stdlib -- Uses values instead of pointers -- Many features, see below - - -Features ------ - -- Parsing and validation at all levels -- Comparator-like comparisons -- Compare Helper Methods -- InPlace manipulation -- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1` -- Sortable (implements sort.Interface) -- database/sql compatible (sql.Scanner/Valuer) -- encoding/json compatible (json.Marshaler/Unmarshaler) - -Ranges ------- - -A `Range` is a set of conditions which specify which versions satisfy the range. - -A condition is composed of an operator and a version. The supported operators are: - -- `<1.0.0` Less than `1.0.0` -- `<=1.0.0` Less than or equal to `1.0.0` -- `>1.0.0` Greater than `1.0.0` -- `>=1.0.0` Greater than or equal to `1.0.0` -- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0` -- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`. - -A `Range` can link multiple `Ranges` separated by space: - -Ranges can be linked by logical AND: - - - `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0` - - `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2` - -Ranges can also be linked by logical OR: - - - `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x` - -AND has a higher precedence than OR. It's not possible to use brackets. - -Ranges can be combined by both AND and OR - - - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1` - -Range usage: - -``` -v, err := semver.Parse("1.2.3") -range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0") -if range(v) { - //valid -} - -``` - -Example ------ - -Have a look at full examples in [examples/main.go](examples/main.go) - -```go -import github.com/blang/semver - -v, err := semver.Make("0.0.1-alpha.preview+123.github") -fmt.Printf("Major: %d\n", v.Major) -fmt.Printf("Minor: %d\n", v.Minor) -fmt.Printf("Patch: %d\n", v.Patch) -fmt.Printf("Pre: %s\n", v.Pre) -fmt.Printf("Build: %s\n", v.Build) - -// Prerelease versions array -if len(v.Pre) > 0 { - fmt.Println("Prerelease versions:") - for i, pre := range v.Pre { - fmt.Printf("%d: %q\n", i, pre) - } -} - -// Build meta data array -if len(v.Build) > 0 { - fmt.Println("Build meta data:") - for i, build := range v.Build { - fmt.Printf("%d: %q\n", i, build) - } -} - -v001, err := semver.Make("0.0.1") -// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE -v001.GT(v) == true -v.LT(v001) == true -v.GTE(v) == true -v.LTE(v) == true - -// Or use v.Compare(v2) for comparisons (-1, 0, 1): -v001.Compare(v) == 1 -v.Compare(v001) == -1 -v.Compare(v) == 0 - -// Manipulate Version in place: -v.Pre[0], err = semver.NewPRVersion("beta") -if err != nil { - fmt.Printf("Error parsing pre release version: %q", err) -} - -fmt.Println("\nValidate versions:") -v.Build[0] = "?" - -err = v.Validate() -if err != nil { - fmt.Printf("Validation failed: %s\n", err) -} -``` - - -Benchmarks ------ - - BenchmarkParseSimple-4 5000000 390 ns/op 48 B/op 1 allocs/op - BenchmarkParseComplex-4 1000000 1813 ns/op 256 B/op 7 allocs/op - BenchmarkParseAverage-4 1000000 1171 ns/op 163 B/op 4 allocs/op - BenchmarkStringSimple-4 20000000 119 ns/op 16 B/op 1 allocs/op - BenchmarkStringLarger-4 10000000 206 ns/op 32 B/op 2 allocs/op - BenchmarkStringComplex-4 5000000 324 ns/op 80 B/op 3 allocs/op - BenchmarkStringAverage-4 5000000 273 ns/op 53 B/op 2 allocs/op - BenchmarkValidateSimple-4 200000000 9.33 ns/op 0 B/op 0 allocs/op - BenchmarkValidateComplex-4 3000000 469 ns/op 0 B/op 0 allocs/op - BenchmarkValidateAverage-4 5000000 256 ns/op 0 B/op 0 allocs/op - BenchmarkCompareSimple-4 100000000 11.8 ns/op 0 B/op 0 allocs/op - BenchmarkCompareComplex-4 50000000 30.8 ns/op 0 B/op 0 allocs/op - BenchmarkCompareAverage-4 30000000 41.5 ns/op 0 B/op 0 allocs/op - BenchmarkSort-4 3000000 419 ns/op 256 B/op 2 allocs/op - BenchmarkRangeParseSimple-4 2000000 850 ns/op 192 B/op 5 allocs/op - BenchmarkRangeParseAverage-4 1000000 1677 ns/op 400 B/op 10 allocs/op - BenchmarkRangeParseComplex-4 300000 5214 ns/op 1440 B/op 30 allocs/op - BenchmarkRangeMatchSimple-4 50000000 25.6 ns/op 0 B/op 0 allocs/op - BenchmarkRangeMatchAverage-4 30000000 56.4 ns/op 0 B/op 0 allocs/op - BenchmarkRangeMatchComplex-4 10000000 153 ns/op 0 B/op 0 allocs/op - -See benchmark cases at [semver_test.go](semver_test.go) - - -Motivation ------ - -I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like. - - -Contribution ------ - -Feel free to make a pull request. For bigger changes create a issue first to discuss about it. - - -License ------ - -See [LICENSE](LICENSE) file. diff --git a/vendor/github.com/blang/semver/range.go b/vendor/github.com/blang/semver/range.go index 0a8eaa1c9..fca406d47 100644 --- a/vendor/github.com/blang/semver/range.go +++ b/vendor/github.com/blang/semver/range.go @@ -2,10 +2,33 @@ package semver import ( "fmt" + "strconv" "strings" "unicode" ) +type wildcardType int + +const ( + noneWildcard wildcardType = iota + majorWildcard wildcardType = 1 + minorWildcard wildcardType = 2 + patchWildcard wildcardType = 3 +) + +func wildcardTypefromInt(i int) wildcardType { + switch i { + case 1: + return majorWildcard + case 2: + return minorWildcard + case 3: + return patchWildcard + default: + return noneWildcard + } +} + type comparator func(Version, Version) bool var ( @@ -92,8 +115,12 @@ func ParseRange(s string) (Range, error) { if err != nil { return nil, err } + expandedParts, err := expandWildcardVersion(orParts) + if err != nil { + return nil, err + } var orFn Range - for _, p := range orParts { + for _, p := range expandedParts { var andFn Range for _, ap := range p { opStr, vStr, err := splitComparatorVersion(ap) @@ -164,20 +191,39 @@ func buildVersionRange(opStr, vStr string) (*versionRange, error) { } -// splitAndTrim splits a range string by spaces and cleans leading and trailing spaces +// inArray checks if a byte is contained in an array of bytes +func inArray(s byte, list []byte) bool { + for _, el := range list { + if el == s { + return true + } + } + return false +} + +// splitAndTrim splits a range string by spaces and cleans whitespaces func splitAndTrim(s string) (result []string) { last := 0 + var lastChar byte + excludeFromSplit := []byte{'>', '<', '='} for i := 0; i < len(s); i++ { - if s[i] == ' ' { + if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) { if last < i-1 { result = append(result, s[last:i]) } last = i + 1 + } else if s[i] != ' ' { + lastChar = s[i] } } if last < len(s)-1 { result = append(result, s[last:]) } + + for i, v := range result { + result[i] = strings.Replace(v, " ", "", -1) + } + // parts := strings.Split(s, " ") // for _, x := range parts { // if s := strings.TrimSpace(x); len(s) != 0 { @@ -188,7 +234,6 @@ func splitAndTrim(s string) (result []string) { } // splitComparatorVersion splits the comparator from the version. -// Spaces between the comparator and the version are not allowed. // Input must be free of leading or trailing spaces. func splitComparatorVersion(s string) (string, string, error) { i := strings.IndexFunc(s, unicode.IsDigit) @@ -198,6 +243,144 @@ func splitComparatorVersion(s string) (string, string, error) { return strings.TrimSpace(s[0:i]), s[i:], nil } +// getWildcardType will return the type of wildcard that the +// passed version contains +func getWildcardType(vStr string) wildcardType { + parts := strings.Split(vStr, ".") + nparts := len(parts) + wildcard := parts[nparts-1] + + possibleWildcardType := wildcardTypefromInt(nparts) + if wildcard == "x" { + return possibleWildcardType + } + + return noneWildcard +} + +// createVersionFromWildcard will convert a wildcard version +// into a regular version, replacing 'x's with '0's, handling +// special cases like '1.x.x' and '1.x' +func createVersionFromWildcard(vStr string) string { + // handle 1.x.x + vStr2 := strings.Replace(vStr, ".x.x", ".x", 1) + vStr2 = strings.Replace(vStr2, ".x", ".0", 1) + parts := strings.Split(vStr2, ".") + + // handle 1.x + if len(parts) == 2 { + return vStr2 + ".0" + } + + return vStr2 +} + +// incrementMajorVersion will increment the major version +// of the passed version +func incrementMajorVersion(vStr string) (string, error) { + parts := strings.Split(vStr, ".") + i, err := strconv.Atoi(parts[0]) + if err != nil { + return "", err + } + parts[0] = strconv.Itoa(i + 1) + + return strings.Join(parts, "."), nil +} + +// incrementMajorVersion will increment the minor version +// of the passed version +func incrementMinorVersion(vStr string) (string, error) { + parts := strings.Split(vStr, ".") + i, err := strconv.Atoi(parts[1]) + if err != nil { + return "", err + } + parts[1] = strconv.Itoa(i + 1) + + return strings.Join(parts, "."), nil +} + +// expandWildcardVersion will expand wildcards inside versions +// following these rules: +// +// * when dealing with patch wildcards: +// >= 1.2.x will become >= 1.2.0 +// <= 1.2.x will become < 1.3.0 +// > 1.2.x will become >= 1.3.0 +// < 1.2.x will become < 1.2.0 +// != 1.2.x will become < 1.2.0 >= 1.3.0 +// +// * when dealing with minor wildcards: +// >= 1.x will become >= 1.0.0 +// <= 1.x will become < 2.0.0 +// > 1.x will become >= 2.0.0 +// < 1.0 will become < 1.0.0 +// != 1.x will become < 1.0.0 >= 2.0.0 +// +// * when dealing with wildcards without +// version operator: +// 1.2.x will become >= 1.2.0 < 1.3.0 +// 1.x will become >= 1.0.0 < 2.0.0 +func expandWildcardVersion(parts [][]string) ([][]string, error) { + var expandedParts [][]string + for _, p := range parts { + var newParts []string + for _, ap := range p { + if strings.Index(ap, "x") != -1 { + opStr, vStr, err := splitComparatorVersion(ap) + if err != nil { + return nil, err + } + + versionWildcardType := getWildcardType(vStr) + flatVersion := createVersionFromWildcard(vStr) + + var resultOperator string + var shouldIncrementVersion bool + switch opStr { + case ">": + resultOperator = ">=" + shouldIncrementVersion = true + case ">=": + resultOperator = ">=" + case "<": + resultOperator = "<" + case "<=": + resultOperator = "<" + shouldIncrementVersion = true + case "", "=", "==": + newParts = append(newParts, ">="+flatVersion) + resultOperator = "<" + shouldIncrementVersion = true + case "!=", "!": + newParts = append(newParts, "<"+flatVersion) + resultOperator = ">=" + shouldIncrementVersion = true + } + + var resultVersion string + if shouldIncrementVersion { + switch versionWildcardType { + case patchWildcard: + resultVersion, _ = incrementMinorVersion(flatVersion) + case minorWildcard: + resultVersion, _ = incrementMajorVersion(flatVersion) + } + } else { + resultVersion = flatVersion + } + + ap = resultOperator + resultVersion + } + newParts = append(newParts, ap) + } + expandedParts = append(expandedParts, newParts) + } + + return expandedParts, nil +} + func parseComparator(s string) comparator { switch s { case "==": @@ -222,3 +405,12 @@ func parseComparator(s string) comparator { return nil } + +// MustParseRange is like ParseRange but panics if the range cannot be parsed. +func MustParseRange(s string) Range { + r, err := ParseRange(s) + if err != nil { + panic(`semver: ParseRange(` + s + `): ` + err.Error()) + } + return r +} diff --git a/vendor/github.com/blang/semver/semver.go b/vendor/github.com/blang/semver/semver.go index bbf85ce97..8ee0842e6 100644 --- a/vendor/github.com/blang/semver/semver.go +++ b/vendor/github.com/blang/semver/semver.go @@ -200,6 +200,29 @@ func Make(s string) (Version, error) { return Parse(s) } +// ParseTolerant allows for certain version specifications that do not strictly adhere to semver +// specs to be parsed by this library. It does so by normalizing versions before passing them to +// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions +// with only major and minor components specified +func ParseTolerant(s string) (Version, error) { + s = strings.TrimSpace(s) + s = strings.TrimPrefix(s, "v") + + // Split into major.minor.(patch+pr+meta) + parts := strings.SplitN(s, ".", 3) + if len(parts) < 3 { + if strings.ContainsAny(parts[len(parts)-1], "+-") { + return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data") + } + for len(parts) < 3 { + parts = append(parts, "0") + } + s = strings.Join(parts, ".") + } + + return Parse(s) +} + // Parse parses version string and returns a validated Version or error func Parse(s string) (Version, error) { if len(s) == 0 { diff --git a/vendor/github.com/carlescere/scheduler/README.md b/vendor/github.com/carlescere/scheduler/README.md deleted file mode 100644 index 5339766e2..000000000 --- a/vendor/github.com/carlescere/scheduler/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# scheduler -[![GoDoc](https://godoc.org/github.com/carlescere/scheduler?status.svg)](https://godoc.org/github.com/carlescere/scheduler) -[![Build Status](https://travis-ci.org/carlescere/scheduler.svg?branch=master)](https://travis-ci.org/carlescere/scheduler) -[![Coverage Status](https://coveralls.io/repos/carlescere/scheduler/badge.svg?branch=master)](https://coveralls.io/r/carlescere/scheduler?branch=master) - -Job scheduling made easy. - -Scheduler allows you to schedule recurrent jobs with an easy-to-read syntax. - -Inspired by the article **[Rethinking Cron](http://adam.heroku.com/past/2010/4/13/rethinking_cron/)** and the **[schedule](https://github.com/dbader/schedule)** python module. - -## How to use? -```go -job := func() { - fmt.Println("Time's up!") -} - -scheduler.Every(5).Minutes().Run(job) -scheduler.Every().Day().Run(job) -scheduler.Every().Monday().At("08:30").Run(job) -``` - -## How it works? -By specifying the chain of calls, a `Job` struct is instantiated and a goroutine is starts observing the `Job`. - -The goroutine will be on pause until: -* The next run scheduled is due. This will cause to execute the job. -* The `SkipWait` channel is activated. This will cause to execute the job. -* The `Quit` channel is activated. This will cause to finish the job. - -## Not immediate recurrent jobs -By default the behaviour of the recurrent jobs (Every(N) seconds, minutes, hours) is to start executing the job right away and then wait the required amount of time. By calling specifically `.NotImmediately()` you can override that behaviour and not execute it directly when the function `Run()` is called. - -```go -scheduler.Every(5).Minutes().NotImmediately().Run(job) -``` - -## License -Distributed under MIT license. See `LICENSE` for more information. diff --git a/vendor/github.com/carlescere/scheduler/scheduler.go b/vendor/github.com/carlescere/scheduler/scheduler.go deleted file mode 100644 index 010c0909f..000000000 --- a/vendor/github.com/carlescere/scheduler/scheduler.go +++ /dev/null @@ -1,315 +0,0 @@ -// Package scheduler is a cron replacement based on: -// http://adam.herokuapp.com/past/2010/4/13/rethinking_cron/ -// and -// https://github.com/dbader/schedule -// -// Uses include: -// func main() { -// job := func() { -// fmt.Println("Time's up!") -// } -// scheduler.Every(5).Seconds().Run(function) -// scheduler.Every().Day().Run(function) -// scheduler.Every().Sunday().At("08:30").Run(function) -// } -package scheduler - -import ( - "errors" - "strconv" - "strings" - "time" -) - -type scheduled interface { - nextRun() (time.Duration, error) -} - -// Job defines a running job and allows to stop a scheduled job or run it. -type Job struct { - fn func() - Quit chan bool - SkipWait chan bool - err error - schedule scheduled - isRunning bool -} - -type recurrent struct { - units int - period time.Duration - done bool -} - -func (r *recurrent) nextRun() (time.Duration, error) { - if r.units == 0 || r.period == 0 { - return 0, errors.New("cannot set recurrent time with 0") - } - if !r.done { - r.done = true - return 0, nil - } - return time.Duration(r.units) * r.period, nil -} - -type daily struct { - hour int - min int - sec int -} - -func (d *daily) setTime(h, m, s int) { - d.hour = h - d.min = m - d.sec = s -} - -func (d daily) nextRun() (time.Duration, error) { - now := time.Now() - year, month, day := now.Date() - date := time.Date(year, month, day, d.hour, d.min, d.sec, 0, time.Local) - if now.Before(date) { - return date.Sub(now), nil - } - date = time.Date(year, month, day+1, d.hour, d.min, d.sec, 0, time.Local) - return date.Sub(now), nil -} - -type weekly struct { - day time.Weekday - d daily -} - -func (w weekly) nextRun() (time.Duration, error) { - now := time.Now() - year, month, day := now.Date() - numDays := w.day - now.Weekday() - if numDays == 0 { - numDays = 7 - } else if numDays < 0 { - numDays += 7 - } - date := time.Date(year, month, day+int(numDays), w.d.hour, w.d.min, w.d.sec, 0, time.Local) - return date.Sub(now), nil -} - -// Every defines when to run a job. For a recurrent jobs (n seconds/minutes/hours) you -// should specify the unit and then call to the correspondent period method. -func Every(times ...int) *Job { - switch len(times) { - case 0: - return &Job{} - case 1: - r := new(recurrent) - r.units = times[0] - return &Job{schedule: r} - default: - // Yeah... I don't like it either. But go does not support default - // parameters nor method overloading. In an ideal world should - // return an error at compile time not at runtime. :/ - return &Job{err: errors.New("too many arguments in Every")} - } -} - -// NotImmediately allows recurrent jobs not to be executed immediatelly after -// definition. If a job is declared hourly won't start executing until the first hour -// passed. -func (j *Job) NotImmediately() *Job { - rj, ok := j.schedule.(*recurrent) - if !ok { - j.err = errors.New("bad function chaining") - return j - } - rj.done = true - return j -} - -// At lets you define a specific time when the job would be run. Does not work with -// recurrent jobs. -// Time should be defined as a string separated by a colon. Could be used as "08:35:30", -// "08:35" or "8" for only the hours. -func (j *Job) At(hourTime string) *Job { - if j.err != nil { - return j - } - hour, min, sec, err := parseTime(hourTime) - if err != nil { - j.err = err - return j - } - d, ok := j.schedule.(daily) - if !ok { - w, ok := j.schedule.(weekly) - if !ok { - j.err = errors.New("bad function chaining") - return j - } - w.d.setTime(hour, min, sec) - j.schedule = w - } else { - d.setTime(hour, min, sec) - j.schedule = d - } - return j -} - -// Run sets the job to the schedule and returns the pointer to the job so it may be -// stopped or executed without waiting or an error. -func (j *Job) Run(f func()) (*Job, error) { - if j.err != nil { - return nil, j.err - } - var next time.Duration - var err error - j.Quit = make(chan bool, 1) - j.SkipWait = make(chan bool, 1) - j.fn = f - // Check for possible errors in scheduling - next, err = j.schedule.nextRun() - if err != nil { - return nil, err - } - go func(j *Job) { - for { - select { - case <-j.Quit: - return - case <-j.SkipWait: - go func(j *Job) { - j.isRunning = true - j.fn() - j.isRunning = false - }(j) - case <-time.After(next): - go func(j *Job) { - j.isRunning = true - j.fn() - j.isRunning = false - }(j) - } - next, _ = j.schedule.nextRun() - } - }(j) - return j, nil -} - -func parseTime(str string) (hour, min, sec int, err error) { - chunks := strings.Split(str, ":") - var hourStr, minStr, secStr string - switch len(chunks) { - case 1: - hourStr = chunks[0] - minStr = "0" - secStr = "0" - case 2: - hourStr = chunks[0] - minStr = chunks[1] - secStr = "0" - case 3: - hourStr = chunks[0] - minStr = chunks[1] - secStr = chunks[2] - } - hour, err = strconv.Atoi(hourStr) - if err != nil { - return 0, 0, 0, errors.New("bad time") - } - min, err = strconv.Atoi(minStr) - if err != nil { - return 0, 0, 0, errors.New("bad time") - } - sec, err = strconv.Atoi(secStr) - if err != nil { - return 0, 0, 0, errors.New("bad time") - } - - if hour > 23 || min > 59 || sec > 59 { - return 0, 0, 0, errors.New("bad time") - } - - return -} - -func (j *Job) dayOfWeek(d time.Weekday) *Job { - if j.schedule != nil { - j.err = errors.New("bad function chaining") - } - j.schedule = weekly{day: d} - return j -} - -// Monday sets the job to run every Monday. -func (j *Job) Monday() *Job { - return j.dayOfWeek(time.Monday) -} - -// Tuesday sets the job to run every Tuesday. -func (j *Job) Tuesday() *Job { - return j.dayOfWeek(time.Tuesday) -} - -// Wednesday sets the job to run every Wednesday. -func (j *Job) Wednesday() *Job { - return j.dayOfWeek(time.Wednesday) -} - -// Thursday sets the job to run every Thursday. -func (j *Job) Thursday() *Job { - return j.dayOfWeek(time.Thursday) -} - -// Friday sets the job to run every Friday. -func (j *Job) Friday() *Job { - return j.dayOfWeek(time.Friday) -} - -// Saturday sets the job to run every Saturday. -func (j *Job) Saturday() *Job { - return j.dayOfWeek(time.Saturday) -} - -// Sunday sets the job to run every Sunday. -func (j *Job) Sunday() *Job { - return j.dayOfWeek(time.Sunday) -} - -// Day sets the job to run every day. -func (j *Job) Day() *Job { - if j.schedule != nil { - j.err = errors.New("bad function chaining") - } - j.schedule = daily{} - return j -} - -func (j *Job) timeOfDay(d time.Duration) *Job { - if j.err != nil { - return j - } - r := j.schedule.(*recurrent) - r.period = d - j.schedule = r - return j -} - -// Seconds sets the job to run every n Seconds where n was defined in the Every -// function. -func (j *Job) Seconds() *Job { - return j.timeOfDay(time.Second) -} - -// Minutes sets the job to run every n Minutes where n was defined in the Every -// function. -func (j *Job) Minutes() *Job { - return j.timeOfDay(time.Minute) -} - -// Hours sets the job to run every n Hours where n was defined in the Every function. -func (j *Job) Hours() *Job { - return j.timeOfDay(time.Hour) -} - -// IsRunning returns if the job is currently running -func (j *Job) IsRunning() bool { - return j.isRunning -} diff --git a/vendor/github.com/creack/goselect/.gitignore b/vendor/github.com/creack/goselect/.gitignore deleted file mode 100644 index 6f4dacea8..000000000 --- a/vendor/github.com/creack/goselect/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -go-select* -goselect* -example-* -example/example diff --git a/vendor/github.com/creack/goselect/Dockerfile b/vendor/github.com/creack/goselect/Dockerfile deleted file mode 100644 index d03b5a9d9..000000000 --- a/vendor/github.com/creack/goselect/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM google/golang:stable -MAINTAINER Guillaume J. Charmes -CMD /tmp/a.out -ADD . /src -RUN cd /src && go build -o /tmp/a.out diff --git a/vendor/github.com/creack/goselect/README.md b/vendor/github.com/creack/goselect/README.md deleted file mode 100644 index d5d06510e..000000000 --- a/vendor/github.com/creack/goselect/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# go-select - -select(2) implementation in Go - -## Supported platforms - -| | 386 | amd64 | arm | arm64 | -|---------------|-----|-------|-----|-------| -| **linux** | yes | yes | yes | yes | -| **darwin** | yes | yes | n/a | ?? | -| **freebsd** | yes | yes | yes | ?? | -| **openbsd** | yes | yes | yes | ?? | -| **netbsd** | yes | yes | yes | ?? | -| **dragonfly** | n/a | yes | n/a | ?? | -| **solaris** | n/a | no | n/a | ?? | -| **plan9** | no | no | n/a | ?? | -| **windows** | yes | yes | n/a | ?? | -| **android** | n/a | n/a | no | ?? | - -*n/a: platform not supported by Go - -Go on `plan9` and `solaris` do not implement `syscall.Select` not `syscall.SYS_SELECT`. - -## Cross compile - -Using davecheney's https://github.com/davecheney/golang-crosscompile - -``` -export PLATFORMS="darwin/386 darwin/amd64 freebsd/386 freebsd/amd64 freebsd/arm linux/386 linux/amd64 linux/arm windows/386 windows/amd64 openbsd/386 openbsd/amd64 netbsd/386 netbsd/amd64 dragonfly/amd64 plan9/386 plan9/amd64 solaris/amd64" -``` diff --git a/vendor/github.com/creack/goselect/example/main.go b/vendor/github.com/creack/goselect/example/main.go deleted file mode 100644 index 86d8d16eb..000000000 --- a/vendor/github.com/creack/goselect/example/main.go +++ /dev/null @@ -1,369 +0,0 @@ -package main - -import ( - "fmt" - "io" - "log" - "net" - "os" - "sync" - "time" - - "github.com/creack/goselect" -) - -type fder interface { - Fd() uintptr -} - -// ErrNotFder . -var ErrNotFder = fmt.Errorf("Not a fder") - -type readFder interface { - io.Reader - fder -} - -type writeFder interface { - io.Reader - fder -} - -// SelectReader . -type selectReader struct { - readFder - ready chan struct{} - stop chan struct{} -} - -func (r *selectReader) Read(buf []byte) (int, error) { - select { - case <-r.stop: - return 0, io.EOF - case <-r.ready: - return r.readFder.Read(buf) - } -} - -// Select . -type Select struct { - readers []*selectReader - writers []writeFder - controlPipeR *os.File - controlPipeW *os.File -} - -// NewSelect . -func NewSelect() (*Select, error) { - r, w, err := os.Pipe() - if err != nil { - return nil, err - } - s := &Select{ - readers: []*selectReader{}, - writers: []writeFder{}, - controlPipeR: r, - controlPipeW: w, - } - return s, nil -} - -func (s *Select) run() { - rFDSet := &goselect.FDSet{} - var max uintptr - var fd uintptr - for { - // TODO: this can be cached and changed only upon controlePipe event. - rFDSet.Zero() - fd = s.controlPipeR.Fd() - max = fd - rFDSet.Set(fd) - for _, r := range s.readers { - fd = r.Fd() - if max < fd { - max = fd - } - rFDSet.Set(fd) - } - println("-------> preselect") - if err := goselect.Select(int(max)+1, rFDSet, nil, nil, -1); err != nil { - log.Fatal(err) - } - for i := uintptr(0); i < goselect.FD_SETSIZE; i++ { - if rFDSet.IsSet(i) { - println(i, "is ready") - } - } - println("<-------- postselect") - for _, r := range s.readers { - if rFDSet.IsSet(r.Fd()) { - func(r *selectReader) { r.ready <- struct{}{} }(r) - } - } - if rFDSet.IsSet(s.controlPipeR.Fd()) { - buf := make([]byte, 1024) - n, err := s.controlPipeR.Read(buf) - if err != nil { - if err == io.EOF { - break - } - log.Fatal(err) - } - fmt.Printf("----> control: %s\n", buf[:n]) - } - } -} - -// NewReader . -func (s *Select) NewReader(r io.Reader) (io.Reader, error) { - rr, ok := r.(readFder) - if !ok { - return nil, ErrNotFder - } - ret := &selectReader{ - readFder: rr, - ready: make(chan struct{}), - stop: make(chan struct{}), - } - s.readers = append(s.readers, ret) - if _, err := s.controlPipeW.Write([]byte("newreader")); err != nil { - return nil, err - } - return ret, nil -} - -func test6() error { - s, err := NewSelect() - if err != nil { - return err - } - _ = s - - fmt.Printf("%d\n", os.Getpid()) - const MAX = 4 - rs := []io.Reader{} - ws := []io.Writer{} - for i := 0; i < MAX; i++ { - r, w, _ := os.Pipe() - println(i, "--->", r.Fd(), w.Fd()) - rs = append(rs, r) - ws = append(ws, w) - } - - c := make(chan struct{}) - wg := sync.WaitGroup{} - for i := 0; i < MAX; i++ { - wg.Add(1) - go func() { - time.Sleep(2 * time.Second) - <-c - wg.Done() - }() - } - time.Sleep(4 * time.Second) - close(c) - wg.Wait() - for i := 0; i < MAX; i++ { - time.Sleep(5 * time.Second) - wg.Add(1) - go func(r io.Reader, i int) { - rr, _ := s.NewReader(r) - r = rr - buf := make([]byte, 1024) - for { - n, err := r.Read(buf) - if err != nil { - log.Printf("[%d] error read: %s\n", i, err) - break - } - _ = n - fmt.Printf("[%d] %s\n", i, buf[:n]) - } - wg.Done() - }(rs[i], i) - } - for i := 0; i < 1; i++ { - for i := 0; i < MAX; i++ { - fmt.Fprintf(ws[i], "{%d} hello", i) - } - time.Sleep(5 * time.Second) - } - wg.Wait() - return nil -} - -func test4() error { - rFDSet := &goselect.FDSet{} - buf := make([]byte, 1024) - for { - // TODO: this can be cached and changed only upon controlePipe event. - rFDSet.Zero() - rFDSet.Set(os.Stdin.Fd()) - if err := goselect.Select(int(os.Stdin.Fd())+1, rFDSet, nil, nil, -1); err != nil { - return err - } - for i := uintptr(0); i < goselect.FD_SETSIZE; i++ { - if rFDSet.IsSet(i) { - println(i, "is ready") - } - } - if rFDSet.IsSet(os.Stdin.Fd()) { - n, err := os.Stdin.Read(buf) - if err != nil { - if err == io.EOF { - break - } - return err - } - fmt.Printf("---->: %s\n", buf[:n]) - } - } - return nil -} - -type Client struct { - f *os.File - queue [][]byte -} - -func (c *Client) Push(msg []byte) { - c.queue = append(c.queue, msg) - println(len(c.queue)) -} - -func (c *Client) Pop() []byte { - if len(c.queue) == 0 { - return nil - } - tmp := c.queue[0] - c.queue = c.queue[1:] - return tmp -} - -func testServer() error { - l, err := net.Listen("tcp", "0.0.0.0:8080") - if err != nil { - return err - } - ll, ok := l.(*net.TCPListener) - if !ok { - return fmt.Errorf("wrong listener type") - } - - llf, err := ll.File() - if err != nil { - return err - } - - rFDSet := &goselect.FDSet{} - wFDSet := &goselect.FDSet{} - - buf := make([]byte, 1024) - var max, fd uintptr - - clients := []*Client{} - - for { - // TODO: this can be cached and changed only upon controlePipe event. - rFDSet.Zero() - wFDSet.Zero() - fd = llf.Fd() - max = fd - rFDSet.Set(fd) - - for _, c := range clients { - fd = c.f.Fd() - rFDSet.Set(fd) - if len(c.queue) > 0 { - wFDSet.Set(fd) - } - if max < fd { - max = fd - } - } - - if err := goselect.Select(int(max)+1, rFDSet, wFDSet, nil, -1); err != nil { - return err - } - println("-->") - - // Watch for new clients - if rFDSet.IsSet(llf.Fd()) { - c, err := ll.AcceptTCP() - if err != nil { - return err - } - f, err := c.File() - if err != nil { - return err - } - fd = f.Fd() - println("New client:", fd) - clients = append(clients, &Client{f: f}) - } - - // Watch for client activity - for _, c := range clients { - fd = c.f.Fd() - if rFDSet.IsSet(fd) { - n, err := c.f.Read(buf) - if err != nil { - return err - } - fmt.Printf("%s", buf[:n]) - for _, cc := range clients { - if c != cc { - cc.Push(buf[:n]) - } - } - } - } - - // Send message to clients - for _, c := range clients { - fd = c.f.Fd() - if wFDSet.IsSet(fd) { - msg := c.Pop() - fmt.Printf("%d write ready: %v\n", fd, msg) - if msg != nil { - _, err := c.f.Write(msg) - if err != nil { - return err - } - } - } - } - } -} - -func main() { - if err := testServer(); err != nil { - log.Fatal(err) - } -} - -func test5() error { - wg := sync.WaitGroup{} - fmt.Printf("%d\n", os.Getpid()) - for i := 0; i < 200; i++ { - r, w, _ := os.Pipe() - go func(w io.Writer) { - for { - w.Write([]byte("hello")) - time.Sleep(time.Second) - } - }(w) - wg.Add(1) - go func(r io.Reader) { - buf := make([]byte, 1024) - for { - _, err := r.Read(buf) - if err != nil { - log.Fatal(err) - } - } - }(r) - } - wg.Wait() - return nil -} diff --git a/vendor/github.com/creack/goselect/fdset_32.go b/vendor/github.com/creack/goselect/fdset_32.go index 8b90d21a9..a346d3f1c 100644 --- a/vendor/github.com/creack/goselect/fdset_32.go +++ b/vendor/github.com/creack/goselect/fdset_32.go @@ -1,4 +1,4 @@ -// +build darwin openbsd netbsd 386 arm +// +build darwin openbsd netbsd 386 arm mips mipsle package goselect diff --git a/vendor/github.com/creack/goselect/fdset_64.go b/vendor/github.com/creack/goselect/fdset_64.go index 4e032e4ea..0e70213d8 100644 --- a/vendor/github.com/creack/goselect/fdset_64.go +++ b/vendor/github.com/creack/goselect/fdset_64.go @@ -1,5 +1,5 @@ // +build !darwin,!netbsd,!openbsd -// +build amd64 arm64 +// +build amd64 arm64 ppc64le mips64 mips64le s390x package goselect diff --git a/vendor/github.com/creack/goselect/select_test.go b/vendor/github.com/creack/goselect/select_test.go deleted file mode 100644 index 6948b5beb..000000000 --- a/vendor/github.com/creack/goselect/select_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package goselect - -import ( - "fmt" - "io" - "os" - "testing" - "time" -) - -type fder interface { - Fd() uintptr -} - -func TestReadWriteSync(t *testing.T) { - const count = 50 - rrs := []io.Reader{} - wws := []io.Writer{} - rFDSet := &FDSet{} - for i := 0; i < count; i++ { - rr, ww, err := os.Pipe() - if err != nil { - t.Fatal(err) - } - rrs = append(rrs, rr) - wws = append(wws, ww) - } - - go func() { - time.Sleep(time.Second) - for i := 0; i < count; i++ { - fmt.Fprintf(wws[i], "hello %d", i) - time.Sleep(time.Millisecond) - } - }() - - buf := make([]byte, 1024) - for i := 0; i < count; i++ { - rFDSet.Zero() - for i := 0; i < count; i++ { - rFDSet.Set(rrs[i].(fder).Fd()) - } - - if err := RetrySelect(1024, rFDSet, nil, nil, -1, 10, 10*time.Millisecond); err != nil { - t.Fatalf("select call failed: %s", err) - } - for j := 0; j < count; j++ { - if rFDSet.IsSet(rrs[j].(fder).Fd()) { - // println(i, j) - if i != j { - t.Fatalf("unexpected fd ready: %d,expected: %d", j, i) - } - _, err := rrs[j].Read(buf) - if err != nil { - t.Fatalf("read call failed: %s", err) - } - } - } - } -} diff --git a/vendor/github.com/creack/goselect/test_crosscompile.sh b/vendor/github.com/creack/goselect/test_crosscompile.sh deleted file mode 100755 index 533ca6647..000000000 --- a/vendor/github.com/creack/goselect/test_crosscompile.sh +++ /dev/null @@ -1,17 +0,0 @@ -export GOOS=linux; export GOARCH=arm; echo $GOOS/$GOARCH; go build -export GOOS=linux; export GOARCH=arm64; echo $GOOS/$GOARCH; go build -export GOOS=linux; export GOARCH=amd64; echo $GOOS/$GOARCH; go build -export GOOS=linux; export GOARCH=386; echo $GOOS/$GOARCH; go build -export GOOS=darwin; export GOARCH=arm; echo $GOOS/$GOARCH; go build -export GOOS=darwin; export GOARCH=arm64; echo $GOOS/$GOARCH; go build -export GOOS=darwin; export GOARCH=amd64; echo $GOOS/$GOARCH; go build -export GOOS=darwin; export GOARCH=386; echo $GOOS/$GOARCH; go build -export GOOS=freebsd; export GOARCH=arm; echo $GOOS/$GOARCH; go build -export GOOS=freebsd; export GOARCH=amd64; echo $GOOS/$GOARCH; go build -export GOOS=freebsd; export GOARCH=386; echo $GOOS/$GOARCH; go build -export GOOS=openbsd; export GOARCH=arm; echo $GOOS/$GOARCH; go build -export GOOS=openbsd; export GOARCH=amd64; echo $GOOS/$GOARCH; go build -export GOOS=openbsd; export GOARCH=386; echo $GOOS/$GOARCH; go build -export GOOS=netbsd; export GOARCH=arm; echo $GOOS/$GOARCH; go build -export GOOS=netbsd; export GOARCH=amd64; echo $GOOS/$GOARCH; go build -export GOOS=netbsd; export GOARCH=386; echo $GOOS/$GOARCH; go build diff --git a/vendor/github.com/creack/goselect/zselect_windows.go b/vendor/github.com/creack/goselect/zselect_windows.go index c3b10e1d0..e01502c07 100644 --- a/vendor/github.com/creack/goselect/zselect_windows.go +++ b/vendor/github.com/creack/goselect/zselect_windows.go @@ -20,8 +20,6 @@ func _select(nfds int, readfds *FDSet, writefds *FDSet, exceptfds *FDSet, timeou if total == 0 { if e1 != 0 { err = error(e1) - } else { - err = syscall.EINVAL } } return diff --git a/vendor/github.com/davidmz/go-pageant/LICENSE.txt b/vendor/github.com/davidmz/go-pageant/LICENSE.txt new file mode 100644 index 000000000..bbe93b8c7 --- /dev/null +++ b/vendor/github.com/davidmz/go-pageant/LICENSE.txt @@ -0,0 +1,16 @@ +Copyright (c) 2014 David Mzareulyan + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/davidmz/go-pageant/io_windows.go b/vendor/github.com/davidmz/go-pageant/io_windows.go new file mode 100644 index 000000000..8f375515d --- /dev/null +++ b/vendor/github.com/davidmz/go-pageant/io_windows.go @@ -0,0 +1,42 @@ +package pageant + +import ( + "io" + "sync" + + "golang.org/x/crypto/ssh/agent" +) + +// New returns new ssh-agent instance (see http://golang.org/x/crypto/ssh/agent) +func New() agent.Agent { + return agent.NewClient(&conn{}) +} + +type conn struct { + sync.Mutex + buf []byte +} + +func (c *conn) Write(p []byte) (int, error) { + c.Lock() + defer c.Unlock() + + resp, err := query(p) + if err != nil { + return 0, err + } + c.buf = append(c.buf, resp...) + return len(p), nil +} + +func (c *conn) Read(p []byte) (int, error) { + c.Lock() + defer c.Unlock() + + if len(c.buf) == 0 { + return 0, io.EOF + } + n := copy(p, c.buf) + c.buf = c.buf[n:] + return n, nil +} diff --git a/vendor/github.com/davidmz/go-pageant/pageant_windows.go b/vendor/github.com/davidmz/go-pageant/pageant_windows.go new file mode 100644 index 000000000..520e8f430 --- /dev/null +++ b/vendor/github.com/davidmz/go-pageant/pageant_windows.go @@ -0,0 +1,134 @@ +// Package pageant provides an interface to PyTTY pageant.exe utility. +// This package is windows-only +package pageant + +// see https://github.com/Yasushi/putty/blob/master/windows/winpgntc.c#L155 +// see https://github.com/paramiko/paramiko/blob/master/paramiko/win_pageant.py + +import ( + "encoding/binary" + "errors" + "fmt" + "sync" + "syscall" + "unsafe" +) + +// MaxMessageLen defines maximum size of message can be sent to pageant +const MaxMessageLen = 8192 + +var ( + // ErrPageantNotFound returns when pageant process not found + ErrPageantNotFound = errors.New("pageant process not found") + // ErrSendMessage returns when message to pageant cannt be sent + ErrSendMessage = errors.New("error sending message") + + // ErrMessageTooLong returns when message is too long (see MaxMessageLen) + ErrMessageTooLong = errors.New("message too long") + // ErrInvalidMessageFormat returns when message have invalid fomat + ErrInvalidMessageFormat = errors.New("invalid message format") + // ErrResponseTooLong returns when response from pageant is too long + ErrResponseTooLong = errors.New("response too long") +) + +///////////////////////// + +const ( + agentCopydataID = 0x804e50ba + wmCopydata = 74 +) + +type copyData struct { + dwData uintptr + cbData uint32 + lpData unsafe.Pointer +} + +var ( + lock sync.Mutex + + winFindWindow = winAPI("user32.dll", "FindWindowW") + winGetCurrentThreadID = winAPI("kernel32.dll", "GetCurrentThreadId") + winSendMessage = winAPI("user32.dll", "SendMessageW") +) + +func winAPI(dllName, funcName string) func(...uintptr) (uintptr, uintptr, error) { + proc := syscall.MustLoadDLL(dllName).MustFindProc(funcName) + return func(a ...uintptr) (uintptr, uintptr, error) { return proc.Call(a...) } +} + +// Available returns true if Pageant is started +func Available() bool { return pageantWindow() != 0 } + +// Query sends message msg to Pageant and returns response or error. +// 'msg' is raw agent request with length prefix +// Response is raw agent response with length prefix +func query(msg []byte) ([]byte, error) { + if len(msg) > MaxMessageLen { + return nil, ErrMessageTooLong + } + + msgLen := binary.BigEndian.Uint32(msg[:4]) + if len(msg) != int(msgLen)+4 { + return nil, ErrInvalidMessageFormat + } + + lock.Lock() + defer lock.Unlock() + + paWin := pageantWindow() + + if paWin == 0 { + return nil, ErrPageantNotFound + } + + thID, _, _ := winGetCurrentThreadID() + mapName := fmt.Sprintf("PageantRequest%08x", thID) + pMapName, _ := syscall.UTF16PtrFromString(mapName) + + mmap, err := syscall.CreateFileMapping(syscall.InvalidHandle, nil, syscall.PAGE_READWRITE, 0, MaxMessageLen+4, pMapName) + if err != nil { + return nil, err + } + defer syscall.CloseHandle(mmap) + + ptr, err := syscall.MapViewOfFile(mmap, syscall.FILE_MAP_WRITE, 0, 0, 0) + if err != nil { + return nil, err + } + defer syscall.UnmapViewOfFile(ptr) + + mmSlice := (*(*[MaxMessageLen]byte)(unsafe.Pointer(ptr)))[:] + + copy(mmSlice, msg) + + mapNameBytesZ := append([]byte(mapName), 0) + + cds := copyData{ + dwData: agentCopydataID, + cbData: uint32(len(mapNameBytesZ)), + lpData: unsafe.Pointer(&(mapNameBytesZ[0])), + } + + resp, _, _ := winSendMessage(paWin, wmCopydata, 0, uintptr(unsafe.Pointer(&cds))) + + if resp == 0 { + return nil, ErrSendMessage + } + + respLen := binary.BigEndian.Uint32(mmSlice[:4]) + if respLen > MaxMessageLen-4 { + return nil, ErrResponseTooLong + } + + respData := make([]byte, respLen+4) + copy(respData, mmSlice) + + return respData, nil +} + +func pageantWindow() uintptr { + nameP, _ := syscall.UTF16PtrFromString("Pageant") + h, _, _ := winFindWindow(uintptr(unsafe.Pointer(nameP)), uintptr(unsafe.Pointer(nameP))) + return h +} diff --git a/vendor/github.com/facchinm/go-serial-native/README.md b/vendor/github.com/facchinm/go-serial-native/README.md deleted file mode 100644 index c2eaf65c2..000000000 --- a/vendor/github.com/facchinm/go-serial-native/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Go Serial - -[![GoDoc](https://godoc.org/github.com/mikepb/go-serial?status.svg)](https://godoc.org/github.com/mikepb/go-serial) - -Package serial provides a binding to libserialport for serial port -functionality. Serial ports are commonly used with embedded systems, -such as the Arduino platform. - -## Usage - -```go -package main - -import ( - "github.com/mikepb/go-serial" - "log" -) - -func main() { - options := serial.RawOptions - options.BitRate = 115200 - p, err := options.Open("/dev/tty") - if err != nil { - log.Panic(err) - } - - defer p.Close() - - buf := make([]byte, 1) - if c, err := p.Read(buf); err != nil { - log.Panic(err) - } else { - log.Println(buf) - } -} -``` - -## Documentation - -https://godoc.org/github.com/mikepb/go-serial - - -## License - - Copyright 2014 Michael Phan-Ba - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -Files from the libserialport library are licensed under the GNU Lesser General -Public License. These files include in the header the notice that follows. - - This file is part of the libserialport project. - - Copyright (C) 2010-2012 Bert Vermeulen - Copyright (C) 2010-2012 Uwe Hermann - Copyright (C) 2013-2014 Martin Ling - Copyright (C) 2013 Matthias Heidbrink - Copyright (C) 2014 Aurelien Jacobs - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . diff --git a/vendor/github.com/facchinm/go-serial-native/libserialport.h b/vendor/github.com/facchinm/go-serial-native/libserialport.h deleted file mode 100644 index 64f4e9f82..000000000 --- a/vendor/github.com/facchinm/go-serial-native/libserialport.h +++ /dev/null @@ -1,1430 +0,0 @@ -/* - * This file is part of the libserialport project. - * - * Copyright (C) 2013 Martin Ling - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/** - * @mainpage libserialport API - * - * Introduction - * ============ - * - * libserialport is a minimal library written in C that is intended to take - * care of the OS-specific details when writing software that uses serial ports. - * - * By writing your serial code to use libserialport, you enable it to work - * transparently on any platform supported by the library. - * - * The operations that are supported are: - * - * - @ref Enumeration (obtaining a list of serial ports on the system) - * - @ref Ports - * - @ref Configuration (baud rate, parity, etc.) - * - @ref Signals (modem control lines, breaks, etc.) - * - @ref Data - * - @ref Waiting - * - @ref Errors - * - * libserialport is an open source project released under the LGPL3+ license. - * - * API principles - * ============== - * - * The API is simple, and designed to be a minimal wrapper around the serial - * port support in each OS. - * - * Most functions take a pointer to a struct sp_port, which represents a serial - * port. These structures are always allocated and freed by the library, using - * the functions in the @ref Enumeration "Enumeration" section. - * - * Most functions have return type @ref sp_return and can return only four - * possible error values: - * - * - @ref SP_ERR_ARG means that a function was called with invalid - * arguments. This implies a bug in the caller. The arguments passed would - * be invalid regardless of the underlying OS or serial device involved. - * - * - @ref SP_ERR_FAIL means that the OS reported a failure. The error code or - * message provided by the OS can be obtained by calling sp_last_error_code() - * or sp_last_error_message(). - * - * - @ref SP_ERR_SUPP indicates that there is no support for the requested - * operation in the current OS, driver or device. No error message is - * available from the OS in this case. There is either no way to request - * the operation in the first place, or libserialport does not know how to - * do so in the current version. - * - * - @ref SP_ERR_MEM indicates that a memory allocation failed. - * - * All of these error values are negative. - * - * Calls that succeed return @ref SP_OK, which is equal to zero. Some functions - * declared @ref sp_return can also return a positive value for a successful - * numeric result, e.g. sp_blocking_read() or sp_blocking_write(). - */ - -#ifndef LIBSERIALPORT_LIBSERIALPORT_H -#define LIBSERIALPORT_LIBSERIALPORT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#ifdef _WIN32 -#include -#endif - -/** Return values. */ -enum sp_return { - /** Operation completed successfully. */ - SP_OK = 0, - /** Invalid arguments were passed to the function. */ - SP_ERR_ARG = -1, - /** A system error occured while executing the operation. */ - SP_ERR_FAIL = -2, - /** A memory allocation failed while executing the operation. */ - SP_ERR_MEM = -3, - /** The requested operation is not supported by this system or device. */ - SP_ERR_SUPP = -4 -}; - -/** Port access modes. */ -enum sp_mode { - /** Open port for read access. */ - SP_MODE_READ = 1, - /** Open port for write access. */ - SP_MODE_WRITE = 2, - /** Open port for read and write access. */ - SP_MODE_READ_WRITE = 3 -}; - -/** Port events. */ -enum sp_event { - /* Data received and ready to read. */ - SP_EVENT_RX_READY = 1, - /* Ready to transmit new data. */ - SP_EVENT_TX_READY = 2, - /* Error occured. */ - SP_EVENT_ERROR = 4 -}; - -/** Buffer selection. */ -enum sp_buffer { - /** Input buffer. */ - SP_BUF_INPUT = 1, - /** Output buffer. */ - SP_BUF_OUTPUT = 2, - /** Both buffers. */ - SP_BUF_BOTH = 3 -}; - -/** Parity settings. */ -enum sp_parity { - /** Special value to indicate setting should be left alone. */ - SP_PARITY_INVALID = -1, - /** No parity. */ - SP_PARITY_NONE = 0, - /** Odd parity. */ - SP_PARITY_ODD = 1, - /** Even parity. */ - SP_PARITY_EVEN = 2, - /** Mark parity. */ - SP_PARITY_MARK = 3, - /** Space parity. */ - SP_PARITY_SPACE = 4 -}; - -/** RTS pin behaviour. */ -enum sp_rts { - /** Special value to indicate setting should be left alone. */ - SP_RTS_INVALID = -1, - /** RTS off. */ - SP_RTS_OFF = 0, - /** RTS on. */ - SP_RTS_ON = 1, - /** RTS used for flow control. */ - SP_RTS_FLOW_CONTROL = 2 -}; - -/** CTS pin behaviour. */ -enum sp_cts { - /** Special value to indicate setting should be left alone. */ - SP_CTS_INVALID = -1, - /** CTS ignored. */ - SP_CTS_IGNORE = 0, - /** CTS used for flow control. */ - SP_CTS_FLOW_CONTROL = 1 -}; - -/** DTR pin behaviour. */ -enum sp_dtr { - /** Special value to indicate setting should be left alone. */ - SP_DTR_INVALID = -1, - /** DTR off. */ - SP_DTR_OFF = 0, - /** DTR on. */ - SP_DTR_ON = 1, - /** DTR used for flow control. */ - SP_DTR_FLOW_CONTROL = 2 -}; - -/** DSR pin behaviour. */ -enum sp_dsr { - /** Special value to indicate setting should be left alone. */ - SP_DSR_INVALID = -1, - /** DSR ignored. */ - SP_DSR_IGNORE = 0, - /** DSR used for flow control. */ - SP_DSR_FLOW_CONTROL = 1 -}; - -/** XON/XOFF flow control behaviour. */ -enum sp_xonxoff { - /** Special value to indicate setting should be left alone. */ - SP_XONXOFF_INVALID = -1, - /** XON/XOFF disabled. */ - SP_XONXOFF_DISABLED = 0, - /** XON/XOFF enabled for input only. */ - SP_XONXOFF_IN = 1, - /** XON/XOFF enabled for output only. */ - SP_XONXOFF_OUT = 2, - /** XON/XOFF enabled for input and output. */ - SP_XONXOFF_INOUT = 3 -}; - -/** Standard flow control combinations. */ -enum sp_flowcontrol { - /** No flow control. */ - SP_FLOWCONTROL_NONE = 0, - /** Software flow control using XON/XOFF characters. */ - SP_FLOWCONTROL_XONXOFF = 1, - /** Hardware flow control using RTS/CTS signals. */ - SP_FLOWCONTROL_RTSCTS = 2, - /** Hardware flow control using DTR/DSR signals. */ - SP_FLOWCONTROL_DTRDSR = 3 -}; - -/** Input signals. */ -enum sp_signal { - /** Clear to send. */ - SP_SIG_CTS = 1, - /** Data set ready. */ - SP_SIG_DSR = 2, - /** Data carrier detect. */ - SP_SIG_DCD = 4, - /** Ring indicator. */ - SP_SIG_RI = 8 -}; - -/** Transport types. */ -enum sp_transport { - /** Native platform serial port. */ - SP_TRANSPORT_NATIVE, - /** USB serial port adapter. */ - SP_TRANSPORT_USB, - /** Bluetooth serial port adapter. */ - SP_TRANSPORT_BLUETOOTH -}; - -/** - * @struct sp_port - * An opaque structure representing a serial port. - */ -struct sp_port; - -/** - * @struct sp_port_config - * An opaque structure representing the configuration for a serial port. - */ -struct sp_port_config; - -/** - * @struct sp_event_set - * A set of handles to wait on for events. - */ -struct sp_event_set { - /** Array of OS-specific handles. */ - void *handles; - /** Array of bitmasks indicating which events apply for each handle. */ - enum sp_event *masks; - /** Number of handles. */ - unsigned int count; -}; - -/** -@defgroup Enumeration Port enumeration -@{ -*/ - -/** - * Obtain a pointer to a new sp_port structure representing the named port. - * - * The user should allocate a variable of type "struct sp_port *" and pass a - * pointer to this to receive the result. - * - * The result should be freed after use by calling sp_free_port(). - * - * If any error is returned, the variable pointed to by port_ptr will be set - * to NULL. Otherwise, it will be set to point to the newly allocated port. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr); - -/** - * Free a port structure obtained from sp_get_port_by_name() or sp_copy_port(). - * - * @since 0.1.0 - */ -void sp_free_port(struct sp_port *port); - -/** - * List the serial ports available on the system. - * - * The result obtained is an array of pointers to sp_port structures, - * terminated by a NULL. The user should allocate a variable of type - * "struct sp_port **" and pass a pointer to this to receive the result. - * - * The result should be freed after use by calling sp_free_port_list(). - * If a port from the list is to be used after freeing the list, it must be - * copied first using sp_copy_port(). - * - * If any error is returned, the variable pointed to by list_ptr will be set - * to NULL. Otherwise, it will be set to point to the newly allocated array. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_list_ports(struct sp_port ***list_ptr); - -/** - * Make a new copy of a sp_port structure. - * - * The user should allocate a variable of type "struct sp_port *" and pass a - * pointer to this to receive the result. - * - * The copy should be freed after use by calling sp_free_port(). - * - * If any error is returned, the variable pointed to by copy_ptr will be set - * to NULL. Otherwise, it will be set to point to the newly allocated copy. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr); - -/** - * Free a port list obtained from sp_list_ports(). - * - * This will also free all the sp_port structures referred to from the list; - * any that are to be retained must be copied first using sp_copy_port(). - * - * @since 0.1.0 - */ -void sp_free_port_list(struct sp_port **ports); - -/** - * @} - * @defgroup Ports Opening, closing and querying ports - * @{ - */ - -/** - * Open the specified serial port. - * - * @param port Pointer to port structure. - * @param flags Flags to use when opening the serial port. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_open(struct sp_port *port, enum sp_mode flags); - -/** - * Close the specified serial port. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_close(struct sp_port *port); - -/** - * Get the name of a port. - * - * The name returned is whatever is normally used to refer to a port on the - * current operating system; e.g. for Windows it will usually be a "COMn" - * device name, and for Unix it will be a device path beginning with "/dev/". - * - * @param port Pointer to port structure. - * - * @return The port name, or NULL if an invalid port is passed. The name - * string is part of the port structure and may not be used after the - * port structure has been freed. - * - * @since 0.1.0 - */ -char *sp_get_port_name(const struct sp_port *port); - -/** - * Get a description for a port, to present to end user. - * - * @param port Pointer to port structure. - * - * @return The port description, or NULL if an invalid port is passed. - * The description string is part of the port structure and may not be used - * after the port structure has been freed. - * - * @since 0.2.0 - */ -char *sp_get_port_description(struct sp_port *port); - -/** - * Get the transport type used by a port. - * - * @param port Pointer to port structure. - * - * @return The port transport type. - * - * @since 0.2.0 - */ -enum sp_transport sp_get_port_transport(struct sp_port *port); - -/** - * Get the USB bus number and address on bus of a USB serial adapter port. - * - * @param port Pointer to port structure. - * @param usb_bus Pointer to variable to store USB bus. - * @param usb_address Pointer to variable to store USB address - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.2.0 - */ -enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port, - int *usb_bus, int *usb_address); - -/** - * Get the USB Vendor ID and Product ID of a USB serial adapter port. - * - * @param port Pointer to port structure. - * @param usb_vid Pointer to variable to store USB VID. - * @param usb_pid Pointer to variable to store USB PID - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.2.0 - */ -enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, int *usb_vid, int *usb_pid); - -/** - * Get the USB manufacturer string of a USB serial adapter port. - * - * @param port Pointer to port structure. - * - * @return The port manufacturer string, or NULL if an invalid port is passed. - * The manufacturer string is part of the port structure and may not be used - * after the port structure has been freed. - * - * @since 0.2.0 - */ -char *sp_get_port_usb_manufacturer(const struct sp_port *port); - -/** - * Get the USB product string of a USB serial adapter port. - * - * @param port Pointer to port structure. - * - * @return The port product string, or NULL if an invalid port is passed. - * The product string is part of the port structure and may not be used - * after the port structure has been freed. - * - * @since 0.2.0 - */ -char *sp_get_port_usb_product(const struct sp_port *port); - -/** - * Get the USB serial number string of a USB serial adapter port. - * - * @param port Pointer to port structure. - * - * @return The port serial number, or NULL if an invalid port is passed. - * The serial number string is part of the port structure and may not be used - * after the port structure has been freed. - * - * @since 0.2.0 - */ -char *sp_get_port_usb_serial(const struct sp_port *port); - -/** - * Get the MAC address of a Bluetooth serial adapter port. - * - * @param port Pointer to port structure. - * - * @return The port MAC address, or NULL if an invalid port is passed. - * The MAC address string is part of the port structure and may not be used - * after the port structure has been freed. - * - * @since 0.2.0 - */ -char *sp_get_port_bluetooth_address(const struct sp_port *port); - -/** - * Get the operating system handle for a port. - * - * The type of the handle depends on the operating system. On Unix based - * systems, the handle is a file descriptor of type "int". On Windows, the - * handle is of type "HANDLE". The user should allocate a variable of the - * appropriate type and pass a pointer to this to receive the result. - * - * To obtain a valid handle, the port must first be opened by calling - * sp_open() using the same port structure. - * - * After the port is closed or the port structure freed, the handle may - * no longer be valid. - * - * @warning This feature is provided so that programs may make use of - * OS-specific functionality where desired. Doing so obviously - * comes at a cost in portability. It also cannot be guaranteed - * that direct usage of the OS handle will not conflict with the - * library's own usage of the port. Be careful. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr); - -/** - * @} - * @defgroup Configuration Setting port parameters - * @{ - */ - -/** - * Allocate a port configuration structure. - * - * The user should allocate a variable of type "struct sp_config *" and pass a - * pointer to this to receive the result. The variable will be updated to - * point to the new configuration structure. The structure is opaque and must - * be accessed via the functions provided. - * - * All parameters in the structure will be initialised to special values which - * are ignored by sp_set_config(). - * - * The structure should be freed after use by calling sp_free_config(). - * - * @param config_ptr Pointer to variable to receive result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_new_config(struct sp_port_config **config_ptr); - -/** - * Free a port configuration structure. - * - * @param config Pointer to configuration structure. - * - * @since 0.1.0 - */ -void sp_free_config(struct sp_port_config *config); - -/** - * Get the current configuration of the specified serial port. - * - * The user should allocate a configuration structure using sp_new_config() - * and pass this as the config parameter. The configuration structure will - * be updated with the port configuration. - * - * Any parameters that are configured with settings not recognised or - * supported by libserialport, will be set to special values that are - * ignored by sp_set_config(). - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config); - -/** - * Set the configuration for the specified serial port. - * - * For each parameter in the configuration, there is a special value (usually - * -1, but see the documentation for each field). These values will be ignored - * and the corresponding setting left unchanged on the port. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config); - -/** - * Set the baud rate for the specified serial port. - * - * @param port Pointer to port structure. - * @param baudrate Baud rate in bits per second. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_baudrate(struct sp_port *port, int baudrate); - -/** - * Get the baud rate from a port configuration. - * - * The user should allocate a variable of type int and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param baudrate_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_baudrate(const struct sp_port_config *config, int *baudrate_ptr); - -/** - * Set the baud rate in a port configuration. - * - * @param config Pointer to configuration structure. - * @param baudrate Baud rate in bits per second, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_baudrate(struct sp_port_config *config, int baudrate); - -/** - * Set the data bits for the specified serial port. - * - * @param port Pointer to port structure. - * @param bits Number of data bits. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_bits(struct sp_port *port, int bits); - -/** - * Get the data bits from a port configuration. - * - * The user should allocate a variable of type int and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param bits_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_bits(const struct sp_port_config *config, int *bits_ptr); - -/** - * Set the data bits in a port configuration. - * - * @param config Pointer to configuration structure. - * @param bits Number of data bits, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_bits(struct sp_port_config *config, int bits); - -/** - * Set the parity setting for the specified serial port. - * - * @param port Pointer to port structure. - * @param parity Parity setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_parity(struct sp_port *port, enum sp_parity parity); - -/** - * Get the parity setting from a port configuration. - * - * The user should allocate a variable of type enum sp_parity and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param parity_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_parity(const struct sp_port_config *config, enum sp_parity *parity_ptr); - -/** - * Set the parity setting in a port configuration. - * - * @param config Pointer to configuration structure. - * @param parity Parity setting, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_parity(struct sp_port_config *config, enum sp_parity parity); - -/** - * Set the stop bits for the specified serial port. - * - * @param port Pointer to port structure. - * @param stopbits Number of stop bits. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_stopbits(struct sp_port *port, int stopbits); - -/** - * Get the stop bits from a port configuration. - * - * The user should allocate a variable of type int and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param stopbits_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_stopbits(const struct sp_port_config *config, int *stopbits_ptr); - -/** - * Set the stop bits in a port configuration. - * - * @param config Pointer to configuration structure. - * @param stopbits Number of stop bits, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_stopbits(struct sp_port_config *config, int stopbits); - -/** - * Set the RTS pin behaviour for the specified serial port. - * - * @param port Pointer to port structure. - * @param rts RTS pin mode. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_rts(struct sp_port *port, enum sp_rts rts); - -/** - * Get the RTS pin behaviour from a port configuration. - * - * The user should allocate a variable of type enum sp_rts and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param rts_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_rts(const struct sp_port_config *config, enum sp_rts *rts_ptr); - -/** - * Set the RTS pin behaviour in a port configuration. - * - * @param config Pointer to configuration structure. - * @param rts RTS pin mode, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_rts(struct sp_port_config *config, enum sp_rts rts); - -/** - * Set the CTS pin behaviour for the specified serial port. - * - * @param port Pointer to port structure. - * @param cts CTS pin mode. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_cts(struct sp_port *port, enum sp_cts cts); - -/** - * Get the CTS pin behaviour from a port configuration. - * - * The user should allocate a variable of type enum sp_cts and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param cts_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_cts(const struct sp_port_config *config, enum sp_cts *cts_ptr); - -/** - * Set the CTS pin behaviour in a port configuration. - * - * @param config Pointer to configuration structure. - * @param cts CTS pin mode, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_cts(struct sp_port_config *config, enum sp_cts cts); - -/** - * Set the DTR pin behaviour for the specified serial port. - * - * @param port Pointer to port structure. - * @param dtr DTR pin mode. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_dtr(struct sp_port *port, enum sp_dtr dtr); - -/** - * Get the DTR pin behaviour from a port configuration. - * - * The user should allocate a variable of type enum sp_dtr and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param dtr_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_dtr(const struct sp_port_config *config, enum sp_dtr *dtr_ptr); - -/** - * Set the DTR pin behaviour in a port configuration. - * - * @param config Pointer to configuration structure. - * @param dtr DTR pin mode, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_dtr(struct sp_port_config *config, enum sp_dtr dtr); - -/** - * Set the DSR pin behaviour for the specified serial port. - * - * @param port Pointer to port structure. - * @param dsr DSR pin mode. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_dsr(struct sp_port *port, enum sp_dsr dsr); - -/** - * Get the DSR pin behaviour from a port configuration. - * - * The user should allocate a variable of type enum sp_dsr and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param dsr_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_dsr(const struct sp_port_config *config, enum sp_dsr *dsr_ptr); - -/** - * Set the DSR pin behaviour in a port configuration. - * - * @param config Pointer to configuration structure. - * @param dsr DSR pin mode, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_dsr(struct sp_port_config *config, enum sp_dsr dsr); - -/** - * Set the XON/XOFF configuration for the specified serial port. - * - * @param port Pointer to port structure. - * @param xon_xoff XON/XOFF mode. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_xon_xoff(struct sp_port *port, enum sp_xonxoff xon_xoff); - -/** - * Get the XON/XOFF configuration from a port configuration. - * - * The user should allocate a variable of type enum sp_xonxoff and pass a pointer to this - * to receive the result. - * - * @param config Pointer to configuration structure. - * @param xon_xoff_ptr Pointer to variable to store result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_config_xon_xoff(const struct sp_port_config *config, enum sp_xonxoff *xon_xoff_ptr); - -/** - * Set the XON/XOFF configuration in a port configuration. - * - * @param config Pointer to configuration structure. - * @param xon_xoff XON/XOFF mode, or -1 to retain current setting. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_xon_xoff(struct sp_port_config *config, enum sp_xonxoff xon_xoff); - -/** - * Set the flow control type in a port configuration. - * - * This function is a wrapper that sets the RTS, CTS, DTR, DSR and - * XON/XOFF settings as necessary for the specified flow control - * type. For more fine-grained control of these settings, use their - * individual configuration functions. - * - * @param config Pointer to configuration structure. - * @param flowcontrol Flow control setting to use. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol); - -/** - * Set the flow control type for the specified serial port. - * - * This function is a wrapper that sets the RTS, CTS, DTR, DSR and - * XON/XOFF settings as necessary for the specified flow control - * type. For more fine-grained control of these settings, use their - * individual configuration functions. - * - * @param port Pointer to port structure. - * @param flowcontrol Flow control setting to use. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol); - -/** - * @} - * @defgroup Data Reading, writing, and flushing data - * @{ -*/ - -/** - * Read bytes from the specified serial port, blocking until complete. - * - * @warning If your program runs on Unix, defines its own signal handlers, and - * needs to abort blocking reads when these are called, then you - * should not use this function. It repeats system calls that return - * with EINTR. To be able to abort a read from a signal handler, you - * should implement your own blocking read using sp_nonblocking_read() - * together with a blocking method that makes sense for your program. - * E.g. you can obtain the file descriptor for an open port using - * sp_get_port_handle() and use this to call select() or pselect(), - * with appropriate arrangements to return if a signal is received. - * - * @param port Pointer to port structure. - * @param buf Buffer in which to store the bytes read. - * @param count Requested number of bytes to read. - * @param timeout Timeout in milliseconds, or zero to wait indefinitely. - * - * @return The number of bytes read on success, or a negative error code. If - * the number of bytes returned is less than that requested, the - * timeout was reached before the requested number of bytes was - * available. If timeout is zero, the function will always return - * either the requested number of bytes or a negative error code. - * - * @since 0.1.0 - */ -enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout); - -/** - * Read bytes from the specified serial port, without blocking. - * - * @param port Pointer to port structure. - * @param buf Buffer in which to store the bytes read. - * @param count Maximum number of bytes to read. - * - * @return The number of bytes read on success, or a negative error code. The - * number of bytes returned may be any number from zero to the maximum - * that was requested. - * - * @since 0.1.0 - */ -enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count); - -/** - * Write bytes to the specified serial port, blocking until complete. - * - * Note that this function only ensures that the accepted bytes have been - * written to the OS; they may be held in driver or hardware buffers and not - * yet physically transmitted. To check whether all written bytes have actually - * been transmitted, use the sp_output_waiting() function. To wait until all - * written bytes have actually been transmitted, use the sp_drain() function. - * - * @warning If your program runs on Unix, defines its own signal handlers, and - * needs to abort blocking writes when these are called, then you - * should not use this function. It repeats system calls that return - * with EINTR. To be able to abort a write from a signal handler, you - * should implement your own blocking write using sp_nonblocking_write() - * together with a blocking method that makes sense for your program. - * E.g. you can obtain the file descriptor for an open port using - * sp_get_port_handle() and use this to call select() or pselect(), - * with appropriate arrangements to return if a signal is received. - * - * @param port Pointer to port structure. - * @param buf Buffer containing the bytes to write. - * @param count Requested number of bytes to write. - * @param timeout Timeout in milliseconds, or zero to wait indefinitely. - * - * @return The number of bytes written on success, or a negative error code. - * If the number of bytes returned is less than that requested, the - * timeout was reached before the requested number of bytes was - * written. If timeout is zero, the function will always return - * either the requested number of bytes or a negative error code. In - * the event of an error there is no way to determine how many bytes - * were sent before the error occured. - * - * @since 0.1.0 - */ -enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout); - -/** - * Write bytes to the specified serial port, without blocking. - * - * Note that this function only ensures that the accepted bytes have been - * written to the OS; they may be held in driver or hardware buffers and not - * yet physically transmitted. To check whether all written bytes have actually - * been transmitted, use the sp_output_waiting() function. To wait until all - * written bytes have actually been transmitted, use the sp_drain() function. - * - * @param port Pointer to port structure. - * @param buf Buffer containing the bytes to write. - * @param count Maximum number of bytes to write. - * - * @return The number of bytes written on success, or a negative error code. - * The number of bytes returned may be any number from zero to the - * maximum that was requested. - * - * @since 0.1.0 - */ -enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count); - -/** - * Gets the number of bytes waiting in the input buffer. - * - * @param port Pointer to port structure. - * - * @return Number of bytes waiting on success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_input_waiting(struct sp_port *port); - -/** - * Gets the number of bytes waiting in the output buffer. - * - * @param port Pointer to port structure. - * - * @return Number of bytes waiting on success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_output_waiting(struct sp_port *port); - -/** - * Flush serial port buffers. Data in the selected buffer(s) is discarded. - * - * @param port Pointer to port structure. - * @param buffers Which buffer(s) to flush. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers); - -/** - * Wait for buffered data to be transmitted. - * - * @warning If your program runs on Unix, defines its own signal handlers, and - * needs to abort draining the output buffer when when these are - * called, then you should not use this function. It repeats system - * calls that return with EINTR. To be able to abort a drain from a - * signal handler, you would need to implement your own blocking - * drain by polling the result of sp_output_waiting(). - * - * @param port Pointer to port structure. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_drain(struct sp_port *port); - -/** - * @} - * @defgroup Waiting Waiting for events - * @{ - */ - -/** - * Allocate storage for a set of events. - * - * The user should allocate a variable of type struct sp_event_set *, - * then pass a pointer to this variable to receive the result. - * - * The result should be freed after use by calling sp_free_event_set(). - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_new_event_set(struct sp_event_set **result_ptr); - -/** - * Add events to a struct sp_event_set for a given port. - * - * The port must first be opened by calling sp_open() using the same port - * structure. - * - * After the port is closed or the port structure freed, the results may - * no longer be valid. - * - * @param event_set Event set to update. - * @param port Pointer to port structure. - * @param mask Bitmask of events to be waited for. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_add_port_events(struct sp_event_set *event_set, - const struct sp_port *port, enum sp_event mask); - -/** - * Wait for any of a set of events to occur. - * - * @param event_set Event set to wait on. - * @param timeout Timeout in milliseconds, or zero to wait indefinitely. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout); - -/** - * Free a structure allocated by sp_new_event_set(). - * - * @since 0.1.0 - */ -void sp_free_event_set(struct sp_event_set *event_set); - -/** - * @} - * @defgroup Signals Port signalling operations - * @{ - */ - -/** - * Gets the status of the control signals for the specified port. - * - * The user should allocate a variable of type "enum sp_signal" and pass a - * pointer to this variable to receive the result. The result is a bitmask - * in which individual signals can be checked by bitwise OR with values of - * the sp_signal enum. - * - * @param port Pointer to port structure. - * @param signal_mask Pointer to variable to receive result. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signal_mask); - -/** - * Put the port transmit line into the break state. - * - * @param port Pointer to port structure. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_start_break(struct sp_port *port); - -/** - * Take the port transmit line out of the break state. - * - * @param port Pointer to port structure. - * - * @return SP_OK upon success, a negative error code otherwise. - * - * @since 0.1.0 - */ -enum sp_return sp_end_break(struct sp_port *port); - -/** - * @} - * @defgroup Errors Obtaining error information - * @{ -*/ - -/** - * Get the error code for a failed operation. - * - * In order to obtain the correct result, this function should be called - * straight after the failure, before executing any other system operations. - * - * @return The system's numeric code for the error that caused the last - * operation to fail. - * - * @since 0.1.0 - */ -int sp_last_error_code(void); - -/** - * Get the error message for a failed operation. - * - * In order to obtain the correct result, this function should be called - * straight after the failure, before executing other system operations. - * - * @return The system's message for the error that caused the last - * operation to fail. This string may be allocated by the function, - * and should be freed after use by calling sp_free_error_message(). - * - * @since 0.1.0 - */ -char *sp_last_error_message(void); - -/** - * Free an error message returned by sp_last_error_message(). - * - * @since 0.1.0 - */ -void sp_free_error_message(char *message); - -/** - * Set the handler function for library debugging messages. - * - * Debugging messages are generated by the library during each operation, - * to help in diagnosing problems. The handler will be called for each - * message. The handler can be set to NULL to ignore all debug messages. - * - * The handler function should accept a format string and variable length - * argument list, in the same manner as e.g. printf(). - * - * The default handler is sp_default_debug_handler(). - * - * @since 0.1.0 - */ -void sp_set_debug_handler(void (*handler)(const char *format, ...)); - -/** - * Default handler function for library debugging messages. - * - * This function prints debug messages to the standard error stream if the - * environment variable LIBSERIALPORT_DEBUG is set. Otherwise, they are - * ignored. - * - * @since 0.1.0 - */ -void sp_default_debug_handler(const char *format, ...); - -/** @} */ - -/** - * @defgroup Versions Version number querying functions, definitions, and macros - * - * This set of API calls returns two different version numbers related - * to libserialport. The "package version" is the release version number of the - * libserialport tarball in the usual "major.minor.micro" format, e.g. "0.1.0". - * - * The "library version" is independent of that; it is the libtool version - * number in the "current:revision:age" format, e.g. "2:0:0". - * See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning for details. - * - * Both version numbers (and/or individual components of them) can be - * retrieved via the API calls at runtime, and/or they can be checked at - * compile/preprocessor time using the respective macros. - * - * @{ - */ - -/* - * Package version macros (can be used for conditional compilation). - */ - -/** The libserialport package 'major' version number. */ -#define SP_PACKAGE_VERSION_MAJOR 0 - -/** The libserialport package 'minor' version number. */ -#define SP_PACKAGE_VERSION_MINOR 2 - -/** The libserialport package 'micro' version number. */ -#define SP_PACKAGE_VERSION_MICRO 0 - -/** The libserialport package version ("major.minor.micro") as string. */ -#define SP_PACKAGE_VERSION_STRING "0.2.0" - -/* - * Library/libtool version macros (can be used for conditional compilation). - */ - -/** The libserialport libtool 'current' version number. */ -#define SP_LIB_VERSION_CURRENT 0 - -/** The libserialport libtool 'revision' version number. */ -#define SP_LIB_VERSION_REVISION 0 - -/** The libserialport libtool 'age' version number. */ -#define SP_LIB_VERSION_AGE 0 - -/** The libserialport libtool version ("current:revision:age") as string. */ -#define SP_LIB_VERSION_STRING "0:0:0" - -/** - * Get the major libserialport package version number. - * - * @return The major package version number. - * - * @since 0.1.0 - */ -int sp_get_major_package_version(void); - -/** - * Get the minor libserialport package version number. - * - * @return The minor package version number. - * - * @since 0.1.0 - */ -int sp_get_minor_package_version(void); - -/** - * Get the micro libserialport package version number. - * - * @return The micro package version number. - * - * @since 0.1.0 - */ -int sp_get_micro_package_version(void); - -/** - * Get the libserialport package version number as a string. - * - * @return The package version number string. The returned string is - * static and thus should NOT be free'd by the caller. - * - * @since 0.1.0 - */ -const char *sp_get_package_version_string(void); - -/** - * Get the "current" part of the libserialport library version number. - * - * @return The "current" library version number. - * - * @since 0.1.0 - */ -int sp_get_current_lib_version(void); - -/** - * Get the "revision" part of the libserialport library version number. - * - * @return The "revision" library version number. - * - * @since 0.1.0 - */ -int sp_get_revision_lib_version(void); - -/** - * Get the "age" part of the libserialport library version number. - * - * @return The "age" library version number. - * - * @since 0.1.0 - */ -int sp_get_age_lib_version(void); - -/** - * Get the libserialport library version number as a string. - * - * @return The library version number string. The returned string is - * static and thus should NOT be free'd by the caller. - * - * @since 0.1.0 - */ -const char *sp_get_lib_version_string(void); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/vendor/github.com/facchinm/go-serial-native/libserialport_internal.h b/vendor/github.com/facchinm/go-serial-native/libserialport_internal.h deleted file mode 100644 index 6611b9866..000000000 --- a/vendor/github.com/facchinm/go-serial-native/libserialport_internal.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * This file is part of the libserialport project. - * - * Copyright (C) 2014 Martin Ling - * Copyright (C) 2014 Aurelien Jacobs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifdef __linux__ -#define _BSD_SOURCE // for timeradd, timersub, timercmp -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _WIN32 -#include -#include -#include -#include -#undef DEFINE_GUID -#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ - static const GUID name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } } -#include -#include -#else -#include -#include -#include -#include -#include -#include -#endif -#ifdef __APPLE__ -#include -#include -#include -#include -#include -#endif -#ifdef __linux__ -#include -#ifndef __ANDROID__ -#include "linux/serial.h" -#endif -#include "linux_termios.h" - -/* TCGETX/TCSETX is not available everywhere. */ -#if defined(TCGETX) && defined(TCSETX) && defined(HAVE_TERMIOX) -#define USE_TERMIOX -#endif -#endif - -/* TIOCINQ/TIOCOUTQ is not available everywhere. */ -#if !defined(TIOCINQ) && defined(FIONREAD) -#define TIOCINQ FIONREAD -#endif -#if !defined(TIOCOUTQ) && defined(FIONWRITE) -#define TIOCOUTQ FIONWRITE -#endif - -/* Non-standard baudrates are not available everywhere. */ -#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && defined(HAVE_BOTHER) -#define USE_TERMIOS_SPEED -#endif - -struct sp_port { - char *name; - char *description; - enum sp_transport transport; - int usb_bus; - int usb_address; - int usb_vid; - int usb_pid; - char *usb_manufacturer; - char *usb_product; - char *usb_serial; - char *bluetooth_address; -#ifdef _WIN32 - char *usb_path; - HANDLE hdl; - COMMTIMEOUTS timeouts; - OVERLAPPED write_ovl; - OVERLAPPED read_ovl; - OVERLAPPED wait_ovl; - DWORD events; - BYTE pending_byte; - BOOL writing; - BOOL composite; -#else - int fd; -#endif -}; - -struct sp_port_config { - int baudrate; - int bits; - enum sp_parity parity; - int stopbits; - enum sp_rts rts; - enum sp_cts cts; - enum sp_dtr dtr; - enum sp_dsr dsr; - enum sp_xonxoff xon_xoff; -}; - -struct port_data { -#ifdef _WIN32 - DCB dcb; -#else - struct termios term; - int controlbits; - int termiox_supported; - int rts_flow; - int cts_flow; - int dtr_flow; - int dsr_flow; -#endif -}; - -#ifdef _WIN32 -typedef HANDLE event_handle; -#else -typedef int event_handle; -#endif - -/* Standard baud rates. */ -#ifdef _WIN32 -#define BAUD_TYPE DWORD -#define BAUD(n) {CBR_##n, n} -#else -#define BAUD_TYPE speed_t -#define BAUD(n) {B##n, n} -#endif - -struct std_baudrate { - BAUD_TYPE index; - int value; -}; - -extern const struct std_baudrate std_baudrates[]; - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -#define NUM_STD_BAUDRATES ARRAY_SIZE(std_baudrates) - -extern void (*sp_debug_handler)(const char *format, ...); - -/* Debug output macros. */ -#define DEBUG_FMT(fmt, ...) do { \ - if (sp_debug_handler) \ - sp_debug_handler(fmt ".\n", __VA_ARGS__); \ -} while (0) -#define DEBUG(msg) DEBUG_FMT(msg, NULL) -#define DEBUG_ERROR(err, msg) DEBUG_FMT("%s returning " #err ": " msg, __func__) -#define DEBUG_FAIL(msg) do { \ - char *errmsg = sp_last_error_message(); \ - DEBUG_FMT("%s returning SP_ERR_FAIL: " msg ": %s", __func__, errmsg); \ - sp_free_error_message(errmsg); \ -} while (0); -#define RETURN() do { \ - DEBUG_FMT("%s returning", __func__); \ - return; \ -} while(0) -#define RETURN_CODE(x) do { \ - DEBUG_FMT("%s returning " #x, __func__); \ - return x; \ -} while (0) -#define RETURN_CODEVAL(x) do { \ - switch (x) { \ - case SP_OK: RETURN_CODE(SP_OK); \ - case SP_ERR_ARG: RETURN_CODE(SP_ERR_ARG); \ - case SP_ERR_FAIL: RETURN_CODE(SP_ERR_FAIL); \ - case SP_ERR_MEM: RETURN_CODE(SP_ERR_MEM); \ - case SP_ERR_SUPP: RETURN_CODE(SP_ERR_SUPP); \ - } \ -} while (0) -#define RETURN_OK() RETURN_CODE(SP_OK); -#define RETURN_ERROR(err, msg) do { \ - DEBUG_ERROR(err, msg); \ - return err; \ -} while (0) -#define RETURN_FAIL(msg) do { \ - DEBUG_FAIL(msg); \ - return SP_ERR_FAIL; \ -} while (0) -#define RETURN_INT(x) do { \ - int _x = x; \ - DEBUG_FMT("%s returning %d", __func__, _x); \ - return _x; \ -} while (0) -#define RETURN_STRING(x) do { \ - char *_x = x; \ - DEBUG_FMT("%s returning %s", __func__, _x); \ - return _x; \ -} while (0) -#define RETURN_POINTER(x) do { \ - void *_x = x; \ - DEBUG_FMT("%s returning %p", __func__, _x); \ - return _x; \ -} while (0) -#define SET_ERROR(val, err, msg) do { DEBUG_ERROR(err, msg); val = err; } while (0) -#define SET_FAIL(val, msg) do { DEBUG_FAIL(msg); val = SP_ERR_FAIL; } while (0) -#define TRACE(fmt, ...) DEBUG_FMT("%s(" fmt ") called", __func__, __VA_ARGS__) -#define TRACE_VOID() DEBUG_FMT("%s() called", __func__) - -#define TRY(x) do { int ret = x; if (ret != SP_OK) RETURN_CODEVAL(ret); } while (0) - -SP_PRIV struct sp_port **list_append(struct sp_port **list, const char *portname); - -/* OS-specific Helper functions. */ -SP_PRIV enum sp_return get_port_details(struct sp_port *port); -SP_PRIV enum sp_return list_ports(struct sp_port ***list); diff --git a/vendor/github.com/facchinm/go-serial-native/linux.c b/vendor/github.com/facchinm/go-serial-native/linux.c deleted file mode 100644 index 204f0fe1a..000000000 --- a/vendor/github.com/facchinm/go-serial-native/linux.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * This file is part of the libserialport project. - * - * Copyright (C) 2014 Aurelien Jacobs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifdef __linux__ - -#include "libserialport.h" -#include "libserialport_internal.h" - -SP_PRIV enum sp_return get_port_details(struct sp_port *port) -{ - /* Description limited to 127 char, - anything longer would not be user friendly anyway */ - char description[128]; - int bus, address; - unsigned int vid, pid; - char manufacturer[128], product[128], serial[128]; - char baddr[32]; - const char dir_name[] = "/sys/class/tty/%s/device/%s%s"; - char sub_dir[32] = "", file_name[PATH_MAX]; - char *ptr, *dev = port->name + 5; - FILE *file; - int i, count; - - if (strncmp(port->name, "/dev/", 5)) - RETURN_ERROR(SP_ERR_ARG, "Device name not recognized."); - - snprintf(file_name, sizeof(file_name), "/sys/class/tty/%s", dev); - count = readlink(file_name, file_name, sizeof(file_name)); - if (count <= 0 || count >= (int) sizeof(file_name)-1) - RETURN_ERROR(SP_ERR_ARG, "Device not found."); - file_name[count] = 0; - if (strstr(file_name, "bluetooth")) - port->transport = SP_TRANSPORT_BLUETOOTH; - else if (strstr(file_name, "usb")) - port->transport = SP_TRANSPORT_USB; - - if (port->transport == SP_TRANSPORT_USB) { - for (i=0; i<5; i++) { - strcat(sub_dir, "../"); - - snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "busnum"); - if (!(file = fopen(file_name, "r"))) - continue; - count = fscanf(file, "%d", &bus); - fclose(file); - if (count != 1) - continue; - - snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "devnum"); - if (!(file = fopen(file_name, "r"))) - continue; - count = fscanf(file, "%d", &address); - fclose(file); - if (count != 1) - continue; - - snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "idVendor"); - if (!(file = fopen(file_name, "r"))) - continue; - count = fscanf(file, "%4x", &vid); - fclose(file); - if (count != 1) - continue; - - snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "idProduct"); - if (!(file = fopen(file_name, "r"))) - continue; - count = fscanf(file, "%4x", &pid); - fclose(file); - if (count != 1) - continue; - - port->usb_bus = bus; - port->usb_address = address; - port->usb_vid = vid; - port->usb_pid = pid; - - snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "product"); - if ((file = fopen(file_name, "r"))) { - if ((ptr = fgets(description, sizeof(description), file))) { - ptr = description + strlen(description) - 1; - if (ptr >= description && *ptr == '\n') - *ptr = 0; - port->description = strdup(description); - } - fclose(file); - } - if (!file || !ptr) - port->description = strdup(dev); - - snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "manufacturer"); - if ((file = fopen(file_name, "r"))) { - if ((ptr = fgets(manufacturer, sizeof(manufacturer), file))) { - ptr = manufacturer + strlen(manufacturer) - 1; - if (ptr >= manufacturer && *ptr == '\n') - *ptr = 0; - port->usb_manufacturer = strdup(manufacturer); - } - fclose(file); - } - - snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "product"); - if ((file = fopen(file_name, "r"))) { - if ((ptr = fgets(product, sizeof(product), file))) { - ptr = product + strlen(product) - 1; - if (ptr >= product && *ptr == '\n') - *ptr = 0; - port->usb_product = strdup(product); - } - fclose(file); - } - - snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "serial"); - if ((file = fopen(file_name, "r"))) { - if ((ptr = fgets(serial, sizeof(serial), file))) { - ptr = serial + strlen(serial) - 1; - if (ptr >= serial && *ptr == '\n') - *ptr = 0; - port->usb_serial = strdup(serial); - } - fclose(file); - } - - break; - } - } else { - port->description = strdup(dev); - - if (port->transport == SP_TRANSPORT_BLUETOOTH) { - snprintf(file_name, sizeof(file_name), dir_name, dev, "", "address"); - if ((file = fopen(file_name, "r"))) { - if ((ptr = fgets(baddr, sizeof(baddr), file))) { - ptr = baddr + strlen(baddr) - 1; - if (ptr >= baddr && *ptr == '\n') - *ptr = 0; - port->bluetooth_address = strdup(baddr); - } - fclose(file); - } - } - } - - RETURN_OK(); -} - -SP_PRIV enum sp_return list_ports(struct sp_port ***list) -{ - char name[PATH_MAX], target[PATH_MAX]; - struct dirent entry, *result; -#ifdef HAVE_SERIAL_STRUCT - struct serial_struct serial_info; - int ioctl_result; -#endif - char buf[sizeof(entry.d_name) + 16]; - int len, fd; - DIR *dir; - int ret = SP_OK; - - DEBUG("Enumerating tty devices"); - if (!(dir = opendir("/sys/class/tty"))) - RETURN_FAIL("could not open /sys/class/tty"); - - DEBUG("Iterating over results"); - while (!readdir_r(dir, &entry, &result) && result) { - snprintf(buf, sizeof(buf), "/sys/class/tty/%s", entry.d_name); - len = readlink(buf, target, sizeof(target)); - if (len <= 0 || len >= (int) sizeof(target)-1) - continue; - target[len] = 0; - if (strstr(target, "virtual")) - continue; - snprintf(name, sizeof(name), "/dev/%s", entry.d_name); - DEBUG_FMT("Found device %s", name); - if (strstr(target, "serial8250")) { - /* The serial8250 driver has a hardcoded number of ports. - * The only way to tell which actually exist on a given system - * is to try to open them and make an ioctl call. */ - DEBUG("serial8250 device, attempting to open"); - if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) { - DEBUG("open failed, skipping"); - continue; - } -#ifdef HAVE_SERIAL_STRUCT - ioctl_result = ioctl(fd, TIOCGSERIAL, &serial_info); -#endif - close(fd); -#ifdef HAVE_SERIAL_STRUCT - if (ioctl_result != 0) { - DEBUG("ioctl failed, skipping"); - continue; - } - if (serial_info.type == PORT_UNKNOWN) { - DEBUG("port type is unknown, skipping"); - continue; - } -#endif - } - DEBUG_FMT("Found port %s", name); - *list = list_append(*list, name); - if (!list) { - SET_ERROR(ret, SP_ERR_MEM, "list append failed"); - break; - } - } - closedir(dir); - - return ret; -} - -#endif diff --git a/vendor/github.com/facchinm/go-serial-native/linux_termios.c b/vendor/github.com/facchinm/go-serial-native/linux_termios.c deleted file mode 100644 index b1e73b1bd..000000000 --- a/vendor/github.com/facchinm/go-serial-native/linux_termios.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of the libserialport project. - * - * Copyright (C) 2013 Martin Ling - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/* - * At the time of writing, glibc does not support the Linux kernel interfaces - * for setting non-standard baud rates and flow control. We therefore have to - * prepare the correct ioctls ourselves, for which we need the declarations in - * linux/termios.h. - * - * We can't include linux/termios.h in serialport.c however, because its - * contents conflict with the termios.h provided by glibc. So this file exists - * to isolate the bits of code which use the kernel termios declarations. - * - * The details vary by architecture. Some architectures have c_ispeed/c_ospeed - * in struct termios, accessed with TCSETS/TCGETS. Others have these fields in - * struct termios2, accessed with TCSETS2/TCGETS2. Some architectures have the - * TCSETX/TCGETX ioctls used with struct termiox, others do not. - */ - -#ifdef __linux__ - -#include -#include -#include "linux_termios.h" - -SP_PRIV unsigned long get_termios_get_ioctl(void) -{ -#ifdef HAVE_TERMIOS2 - return TCGETS2; -#else - return TCGETS; -#endif -} - -SP_PRIV unsigned long get_termios_set_ioctl(void) -{ -#ifdef HAVE_TERMIOS2 - return TCSETS2; -#else - return TCSETS; -#endif -} - -SP_PRIV size_t get_termios_size(void) -{ -#ifdef HAVE_TERMIOS2 - return sizeof(struct termios2); -#else - return sizeof(struct termios); -#endif -} - -#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && defined(HAVE_BOTHER) -SP_PRIV int get_termios_speed(void *data) -{ -#ifdef HAVE_TERMIOS2 - struct termios2 *term = (struct termios2 *) data; -#else - struct termios *term = (struct termios *) data; -#endif - if (term->c_ispeed != term->c_ospeed) - return -1; - else - return term->c_ispeed; -} - -SP_PRIV void set_termios_speed(void *data, int speed) -{ -#ifdef HAVE_TERMIOS2 - struct termios2 *term = (struct termios2 *) data; -#else - struct termios *term = (struct termios *) data; -#endif - term->c_cflag &= ~CBAUD; - term->c_cflag |= BOTHER; - term->c_ispeed = term->c_ospeed = speed; -} -#endif - -#ifdef HAVE_TERMIOX -SP_PRIV size_t get_termiox_size(void) -{ - return sizeof(struct termiox); -} - -SP_PRIV int get_termiox_flow(void *data, int *rts, int *cts, int *dtr, int *dsr) -{ - struct termiox *termx = (struct termiox *) data; - int flags = 0; - - *rts = (termx->x_cflag & RTSXOFF); - *cts = (termx->x_cflag & CTSXON); - *dtr = (termx->x_cflag & DTRXOFF); - *dsr = (termx->x_cflag & DSRXON); - - return flags; -} - -SP_PRIV void set_termiox_flow(void *data, int rts, int cts, int dtr, int dsr) -{ - struct termiox *termx = (struct termiox *) data; - - termx->x_cflag &= ~(RTSXOFF | CTSXON | DTRXOFF | DSRXON); - - if (rts) - termx->x_cflag |= RTSXOFF; - if (cts) - termx->x_cflag |= CTSXON; - if (dtr) - termx->x_cflag |= DTRXOFF; - if (dsr) - termx->x_cflag |= DSRXON; -} -#endif - -#endif diff --git a/vendor/github.com/facchinm/go-serial-native/linux_termios.h b/vendor/github.com/facchinm/go-serial-native/linux_termios.h deleted file mode 100644 index ea8f9daeb..000000000 --- a/vendor/github.com/facchinm/go-serial-native/linux_termios.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the libserialport project. - * - * Copyright (C) 2013 Martin Ling - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifdef __linux__ - -#ifndef LIBSERIALPORT_LINUX_TERMIOS_H -#define LIBSERIALPORT_LINUX_TERMIOS_H - -#include - -SP_PRIV unsigned long get_termios_get_ioctl(void); -SP_PRIV unsigned long get_termios_set_ioctl(void); -SP_PRIV size_t get_termios_size(void); -SP_PRIV int get_termios_speed(void *data); -SP_PRIV void set_termios_speed(void *data, int speed); -SP_PRIV size_t get_termiox_size(void); -SP_PRIV int get_termiox_flow(void *data, int *rts, int *cts, int *dtr, int *dsr); -SP_PRIV void set_termiox_flow(void *data, int rts, int cts, int dtr, int dsr); - -#endif - -#endif diff --git a/vendor/github.com/facchinm/go-serial-native/macosx.c b/vendor/github.com/facchinm/go-serial-native/macosx.c deleted file mode 100644 index 8274ada88..000000000 --- a/vendor/github.com/facchinm/go-serial-native/macosx.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * This file is part of the libserialport project. - * - * Copyright (C) 2013-2014 Martin Ling - * Copyright (C) 2014 Aurelien Jacobs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifdef __APPLE__ - -#include "libserialport.h" -#include "libserialport_internal.h" - -SP_PRIV enum sp_return get_port_details(struct sp_port *port) -{ - /* Description limited to 127 char, - anything longer would not be user friendly anyway */ - char description[128]; - int bus, address, vid, pid = -1; - char manufacturer[128], product[128], serial[128]; - CFMutableDictionaryRef classes; - io_iterator_t iter; - io_object_t ioport, ioparent; - CFTypeRef cf_property, cf_bus, cf_address, cf_vendor, cf_product; - Boolean result; - char path[PATH_MAX], class[16]; - - DEBUG("Getting serial port list"); - if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) - RETURN_FAIL("IOServiceMatching() failed"); - - if (IOServiceGetMatchingServices(kIOMasterPortDefault, classes, - &iter) != KERN_SUCCESS) - RETURN_FAIL("IOServiceGetMatchingServices() failed"); - - DEBUG("Iterating over results"); - while ((ioport = IOIteratorNext(iter))) { - if (!(cf_property = IORegistryEntryCreateCFProperty(ioport, - CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0))) { - IOObjectRelease(ioport); - continue; - } - result = CFStringGetCString(cf_property, path, sizeof(path), - kCFStringEncodingASCII); - CFRelease(cf_property); - if (!result || strcmp(path, port->name)) { - IOObjectRelease(ioport); - continue; - } - DEBUG_FMT("Found port %s", path); - - IORegistryEntryGetParentEntry(ioport, kIOServicePlane, &ioparent); - if ((cf_property=IORegistryEntrySearchCFProperty(ioparent,kIOServicePlane, - CFSTR("IOProviderClass"), kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents))) { - if (CFStringGetCString(cf_property, class, sizeof(class), - kCFStringEncodingASCII) && - strstr(class, "USB")) { - DEBUG("Found USB class device"); - port->transport = SP_TRANSPORT_USB; - } - CFRelease(cf_property); - } - if ((cf_property=IORegistryEntrySearchCFProperty(ioparent,kIOServicePlane, - CFSTR("IOClass"), kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents))) { - if (CFStringGetCString(cf_property, class, sizeof(class), - kCFStringEncodingASCII) && - strstr(class, "USB")) { - DEBUG("Found USB class device"); - port->transport = SP_TRANSPORT_USB; - } - CFRelease(cf_property); - } - IOObjectRelease(ioparent); - - if ((cf_property = IORegistryEntrySearchCFProperty(ioport,kIOServicePlane, - CFSTR("USB Interface Name"), kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents)) || - (cf_property = IORegistryEntrySearchCFProperty(ioport,kIOServicePlane, - CFSTR("USB Product Name"), kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents)) || - (cf_property = IORegistryEntrySearchCFProperty(ioport,kIOServicePlane, - CFSTR("Product Name"), kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents)) || - (cf_property = IORegistryEntryCreateCFProperty(ioport, - CFSTR(kIOTTYDeviceKey), kCFAllocatorDefault, 0))) { - if (CFStringGetCString(cf_property, description, sizeof(description), - kCFStringEncodingASCII)) { - DEBUG_FMT("Found description %s", description); - port->description = strdup(description); - } - CFRelease(cf_property); - } else { - DEBUG("No description for this device"); - } - - cf_bus = IORegistryEntrySearchCFProperty(ioport, kIOServicePlane, - CFSTR("USBBusNumber"), - kCFAllocatorDefault, - kIORegistryIterateRecursively - | kIORegistryIterateParents); - cf_address = IORegistryEntrySearchCFProperty(ioport, kIOServicePlane, - CFSTR("USB Address"), - kCFAllocatorDefault, - kIORegistryIterateRecursively - | kIORegistryIterateParents); - if (cf_bus && cf_address && - CFNumberGetValue(cf_bus , kCFNumberIntType, &bus) && - CFNumberGetValue(cf_address, kCFNumberIntType, &address)) { - DEBUG_FMT("Found matching USB bus:address %03d:%03d", bus, address); - port->usb_bus = bus; - port->usb_address = address; - } - if (cf_bus ) CFRelease(cf_bus); - if (cf_address) CFRelease(cf_address); - - cf_vendor = IORegistryEntrySearchCFProperty(ioport, kIOServicePlane, - CFSTR("idVendor"), - kCFAllocatorDefault, - kIORegistryIterateRecursively - | kIORegistryIterateParents); - cf_product = IORegistryEntrySearchCFProperty(ioport, kIOServicePlane, - CFSTR("idProduct"), - kCFAllocatorDefault, - kIORegistryIterateRecursively - | kIORegistryIterateParents); - if (cf_vendor && cf_product && - CFNumberGetValue(cf_vendor , kCFNumberIntType, &vid) && - CFNumberGetValue(cf_product, kCFNumberIntType, &pid)) { - DEBUG_FMT("Found matching USB vid:pid %04X:%04X", vid, pid); - port->usb_vid = vid; - port->usb_pid = pid; - } - if (cf_vendor ) CFRelease(cf_vendor); - if (cf_product) CFRelease(cf_product); - - if ((cf_property = IORegistryEntrySearchCFProperty(ioport,kIOServicePlane, - CFSTR("USB Vendor Name"), kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents))) { - if (CFStringGetCString(cf_property, manufacturer, sizeof(manufacturer), - kCFStringEncodingASCII)) { - DEBUG_FMT("Found manufacturer %s", manufacturer); - port->usb_manufacturer = strdup(manufacturer); - } - CFRelease(cf_property); - } - - if ((cf_property = IORegistryEntrySearchCFProperty(ioport,kIOServicePlane, - CFSTR("USB Product Name"), kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents))) { - if (CFStringGetCString(cf_property, product, sizeof(product), - kCFStringEncodingASCII)) { - DEBUG_FMT("Found product name %s", product); - port->usb_product = strdup(product); - } - CFRelease(cf_property); - } - - if ((cf_property = IORegistryEntrySearchCFProperty(ioport,kIOServicePlane, - CFSTR("USB Serial Number"), kCFAllocatorDefault, - kIORegistryIterateRecursively | kIORegistryIterateParents))) { - if (CFStringGetCString(cf_property, serial, sizeof(serial), - kCFStringEncodingASCII)) { - DEBUG_FMT("Found serial number %s", serial); - port->usb_serial = strdup(serial); - } - CFRelease(cf_property); - } - - IOObjectRelease(ioport); - break; - } - IOObjectRelease(iter); - - RETURN_OK(); -} - -SP_PRIV enum sp_return list_ports(struct sp_port ***list) -{ - CFMutableDictionaryRef classes; - io_iterator_t iter; - char path[PATH_MAX]; - io_object_t port; - CFTypeRef cf_path; - Boolean result; - int ret = SP_OK; - - DEBUG("Creating matching dictionary"); - if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) { - SET_FAIL(ret, "IOServiceMatching() failed"); - goto out_done; - } - - DEBUG("Getting matching services"); - if (IOServiceGetMatchingServices(kIOMasterPortDefault, classes, - &iter) != KERN_SUCCESS) { - SET_FAIL(ret, "IOServiceGetMatchingServices() failed"); - goto out_done; - } - - DEBUG("Iterating over results"); - while ((port = IOIteratorNext(iter))) { - cf_path = IORegistryEntryCreateCFProperty(port, - CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0); - if (cf_path) { - result = CFStringGetCString(cf_path, path, sizeof(path), - kCFStringEncodingASCII); - CFRelease(cf_path); - if (result) { - DEBUG_FMT("Found port %s", path); - if (!(*list = list_append(*list, path))) { - SET_ERROR(ret, SP_ERR_MEM, "list append failed"); - IOObjectRelease(port); - goto out; - } - } - } - IOObjectRelease(port); - } -out: - IOObjectRelease(iter); -out_done: - - return ret; -} - -#endif diff --git a/vendor/github.com/facchinm/go-serial-native/serial.go b/vendor/github.com/facchinm/go-serial-native/serial.go deleted file mode 100644 index ba94e205a..000000000 --- a/vendor/github.com/facchinm/go-serial-native/serial.go +++ /dev/null @@ -1,1175 +0,0 @@ -/* - -Package serial provides a binding to libserialport for serial port -functionality. Serial ports are commonly used with embedded systems, -such as the Arduino platform. - -Example Usage - - package main - - import ( - "github.com/mikepb/go-serial" - "log" - ) - - func main() { - options := serial.RawOptions - options.BitRate = 115200 - p, err := options.Open("/dev/tty") - if err != nil { - log.Panic(err) - } - - defer p.Close() - - buf := make([]byte, 1) - if c, err := p.Read(buf); err != nil { - log.Panic(err) - } else { - log.Println(buf) - } - } - -*/ -package serial - -/* -#cgo CFLAGS: -g -O2 -Wall -Wextra -DSP_PRIV= -DSP_API= -#cgo darwin LDFLAGS: -framework IOKit -framework CoreFoundation -#cgo windows LDFLAGS: -lsetupapi - -#include -#include -#include -#include "libserialport.h" - -void debug_handler(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); -} - -void setdebug(int enable) { - sp_set_debug_handler(enable ? debug_handler : NULL); -} - -*/ -import "C" - -import ( - "bytes" - "log" - "net" - "reflect" - "runtime" - "time" - "unsafe" -) - -// Debug flag -const Debug = false - -// Port access modes -const ( - MODE_READ = C.SP_MODE_READ // Open port for read access - MODE_WRITE = C.SP_MODE_WRITE // Open port for write access - MODE_READ_WRITE = C.SP_MODE_READ_WRITE // Open port for read and write access. -) - -// Port events. -const ( - EVENT_RX_READY = C.SP_EVENT_RX_READY // Data received and ready to read. - EVENT_TX_READY = C.SP_EVENT_TX_READY // Ready to transmit new data. - EVENT_ERROR = C.SP_EVENT_ERROR // Error occured. -) - -// Parity settings. -const ( - PARITY_INVALID = iota // Special value to indicate setting should be left alone. - PARITY_NONE // No parity. - PARITY_ODD // Odd parity. - PARITY_EVEN // Even parity. - PARITY_MARK // Mark parity. - PARITY_SPACE // Space parity. -) - -// RTS pin behaviour. -const ( - RTS_INVALID = iota // Special value to indicate setting should be left alone. - RTS_OFF // RTS off. - RTS_ON // RTS on. - RTS_FLOW_CONTROL // RTS used for flow control. -) - -// CTS pin behaviour. -const ( - CTS_INVALID = iota // Special value to indicate setting should be left alone. - CTS_IGNORE // CTS ignored. - CTS_FLOW_CONTROL // CTS used for flow control. -) - -// DTR pin behaviour. -const ( - DTR_INVALID = iota // Special value to indicate setting should be left alone. - DTR_OFF // DTR off. - DTR_ON // DTR on. - DTR_FLOW_CONTROL // DTR used for flow control. -) - -// DSR pin behaviour. -const ( - DSR_INVALID = iota // Special value to indicate setting should be left alone. - DSR_IGNORE // DSR ignored. - DSR_FLOW_CONTROL // DSR used for flow control. -) - -// XON/XOFF flow control behaviour. -const ( - XONXOFF_INVALID = iota // Special value to indicate setting should be left alone. - XONXOFF_DISABLED // XON/XOFF disabled. - XONXOFF_IN // XON/XOFF enabled for input only. - XONXOFF_OUT // XON/XOFF enabled for output only. - XONXOFF_INOUT // XON/XOFF enabled for input and output. -) - -// Standard flow control combinations. -const ( - _ = iota - FLOWCONTROL_NONE // No flow control. - FLOWCONTROL_XONXOFF // Software flow control using XON/XOFF characters. - FLOWCONTROL_RTSCTS // Hardware flow control using RTS/CTS signals. - FLOWCONTROL_DTRDSR // Hardware flow control using DTR/DSR signals. -) - -// Input signals -const ( - SIG_CTS = C.SP_SIG_CTS // Clear to send - SIG_DSR = C.SP_SIG_DSR // Data set ready - SIG_DCD = C.SP_SIG_DCD // Data carrier detect - SIG_RI = C.SP_SIG_RI // Ring indicator -) - -// Transport types. -const ( - TRANSPORT_NATIVE = C.SP_TRANSPORT_NATIVE // Native platform serial port. - TRANSPORT_USB = C.SP_TRANSPORT_USB // USB serial port adapter. - TRANSPORT_BLUETOOTH = C.SP_TRANSPORT_BLUETOOTH // Bluetooh serial port adapter. -) - -// Serial port info. -type Info struct { - p *C.struct_sp_port - opened bool -} - -// Serial port options. -type Options struct { - Mode int // read, write; default is read - BitRate int // number of bits per second (baudrate) - DataBits int // number of data bits (5, 6, 7, 8) - StopBits int // number of stop bits (1, 2) - Parity int // none, odd, even, mark, space - FlowControl int // none, xonxoff, rtscts, dtrdsr - - RTS int - CTS int - DTR int - DSR int -} - -// Serial port. -type Port struct { - Info - c *C.struct_sp_port_config - readDeadline time.Time - writeDeadline time.Time -} - -// Implementation of net.Addr -type Addr struct { - name string -} - -// Implementation of net.Error -type Error struct { - msg string - timeout bool - temporary bool -} - -var RawOptions = Options{ - DataBits: 8, - Parity: PARITY_NONE, - StopBits: 1, - FlowControl: FLOWCONTROL_NONE, -} - -var ErrInvalidArguments = &Error{msg: "Invalid arguments were passed to the function"} -var ErrSystem = &Error{msg: "A system error occured while executing the operation"} -var ErrMemoryAllocation = &Error{msg: "A memory allocation failed while executing the operation"} -var ErrUnsupportedOperation = &Error{msg: "The requested operation is not supported by this system or device"} -var ErrTimeout = &Error{msg: "Operation timed out", timeout: true} - -// Map error codes to errors. -func errmsg(err C.enum_sp_return) error { - switch err { - case C.SP_ERR_ARG: - return ErrInvalidArguments - case C.SP_ERR_FAIL: - return ErrSystem - case C.SP_ERR_MEM: - return ErrMemoryAllocation - case C.SP_ERR_SUPP: - return ErrUnsupportedOperation - } - return nil -} - -// Wrap a sp_port struct in a go Port struct and set finalizer for -// garbage collection. -func newInfo(p *C.struct_sp_port) (*Info, error) { - info := &Info{p: p} - runtime.SetFinalizer(info, (*Info).free) - return info, nil -} - -// Finalizer callback for garbage collection. -func (i *Info) free() { - if i.p != nil { - if i.opened { - C.sp_close(i.p) - } - C.sp_free_port(i.p) - } - i.opened = false - i.p = nil -} - -// Wrap a sp_port struct in a go Port struct and set finalizer for -// garbage collection. -func newPort(info *Info) (*Port, error) { - port := &Port{} - - // copy info - if info != nil { - if err := errmsg(C.sp_copy_port(info.p, &port.p)); err != nil { - return nil, err - } - } - - // set finalizers - runtime.SetFinalizer(port, (*Port).free) - - return port, nil -} - -// Finalizer callback for garbage collection. -func (p *Port) free() { - p.Info.free() - if p.c != nil { - C.sp_free_config(p.c) - } - p.c = nil -} - -// calculate milliseconds until deadline (rounded up) -func deadline2millis(deadline time.Time) int64 { - delta := deadline.Sub(time.Now()) - - duration := time.Duration(delta.Nanoseconds()) - duration += duration + time.Millisecond - time.Nanosecond - duration /= time.Millisecond - - millis := int64(duration) - - if Debug { - log.Printf("timeout: %d ns %d ms", delta, millis) - } - - return millis -} - -// Print libserialport debug messages to stderr. -func SetDebug(enable bool) { - if enable { - C.setdebug(1) - } else { - C.setdebug(0) - } -} - -// Get a port by name. -func PortByName(name string) (*Info, error) { - if p, err := portByName(name); err != nil { - return nil, err - } else { - return newInfo(p) - } -} -func portByName(name string) (*C.struct_sp_port, error) { - var p *C.struct_sp_port - - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - - if err := errmsg(C.sp_get_port_by_name(cname, &p)); err != nil { - return nil, err - } - - return p, nil -} - -// List the serial ports available on the system. -func ListPorts() ([]*Info, error) { - var p **C.struct_sp_port - - if err := C.sp_list_ports(&p); err != C.SP_OK { - return nil, errmsg(err) - } - defer C.sp_free_port_list(p) - - // Convert the C array into a Go slice - // See: https://code.google.com/p/go-wiki/wiki/cgo - pp := (*[1 << 15]*C.struct_sp_port)(unsafe.Pointer(p)) - - // count number of ports - c := 0 - for ; uintptr(unsafe.Pointer(pp[c])) != 0; c++ { - } - - // populate - ports := make([]*Info, c) - for j := 0; j < c; j++ { - var pc *C.struct_sp_port - if err := errmsg(C.sp_copy_port(pp[j], &pc)); err != nil { - return nil, err - } - if sp, err := newInfo(pc); err != nil { - return nil, err - } else { - ports[j] = sp - } - } - - return ports, nil -} - -// Get the name of a port. -func (i *Info) Name() string { - return C.GoString(C.sp_get_port_name(i.p)) -} - -// Get a description for a port, to present to end user. -func (i *Info) Description() string { - return C.GoString(C.sp_get_port_description(i.p)) -} - -// Get the transport type used by a port. -func (i *Info) Transport() int { - t := C.sp_get_port_transport(i.p) - return int(t) -} - -// Get the USB bus number and address on bus of a USB serial adapter port. -func (i *Info) USBBusAddress() (int, int, error) { - var bus, address C.int - if err := errmsg(C.sp_get_port_usb_bus_address(i.p, &bus, &address)); err != nil { - return 0, 0, err - } - return int(bus), int(address), nil -} - -// Get the USB Vendor ID and Product ID of a USB serial adapter port. -func (i *Info) USBVIDPID() (int, int, error) { - var vid, pid C.int - if err := errmsg(C.sp_get_port_usb_vid_pid(i.p, &vid, &pid)); err != nil { - return 0, 0, err - } - return int(vid), int(pid), nil -} - -// Get the USB manufacturer string of a USB serial adapter port. -func (i *Info) USBManufacturer() string { - cdesc := C.sp_get_port_usb_manufacturer(i.p) - return C.GoString(cdesc) -} - -// Get the USB product string of a USB serial adapter port. -func (i *Info) USBProduct() string { - cdesc := C.sp_get_port_usb_product(i.p) - return C.GoString(cdesc) -} - -// Get the USB serial number string of a USB serial adapter port. -func (i *Info) USBSerialNumber() string { - cdesc := C.sp_get_port_usb_serial(i.p) - return C.GoString(cdesc) -} - -// Get the MAC address of a Bluetooth serial adapter port. -func (i *Info) BluetoothAddress() string { - cdesc := C.sp_get_port_bluetooth_address(i.p) - return C.GoString(cdesc) -} - -// Open the port for reading and default options. -func (i *Info) Open() (*Port, error) { - return i.OpenPort(&Options{Mode: MODE_READ}) -} - -// Open the port with the specified options. -func (i *Info) OpenPort(options *Options) (*Port, error) { - // create port - port, err := newPort(i) - if err != nil { - return nil, err - } - - // open port - mode := MODE_READ - if options.Mode != 0 { - mode = options.Mode - } - if err = port.open(mode); err != nil { - return nil, err - } - - // apply options - if err = port.Apply(options); err != nil { - port.Close() - return nil, err - } - - return port, nil -} - -func (i *Info) createPortAndInvalidateInfo() (*Port, error) { - port, err := newPort(nil) - if err != nil { - return nil, err - } - - port.p = i.p - port.opened = i.opened - - i.p = nil - i.opened = false - - return port, nil -} - -// Open a port at the given name using the options object. -func (o *Options) Open(name string) (port *Port, err error) { - if info, err := PortByName(name); err != nil { - return nil, err - } else { - return info.OpenPort(o) - } -} - -// Open a port at the given info using the options object. -func (o *Options) OpenAt(info *Info) (port *Port, err error) { - return info.OpenPort(o) -} - -// Open a port for reading. -func Open(name string) (port *Port, err error) { - // get the port by name - if info, err := PortByName(name); err != nil { - return nil, err - } else if p, err := info.createPortAndInvalidateInfo(); p != nil { - return nil, err - } else { - port = p - } - - // open port with read mode - if err = port.open(MODE_READ); err != nil { - return nil, err - } - - return -} - -func (p *Port) open(mode int) error { - if p.opened { - panic("already opened") - } - err := errmsg(C.sp_open(p.p, C.enum_sp_mode(mode))) - p.opened = err == nil - return p.getConf() -} - -// Close the serial port. -func (p *Port) Close() error { - if !p.opened { - panic("already closed") - } - err := errmsg(C.sp_close(p.p)) - p.opened = false - return err -} - -func (p *Port) getConf() error { - if p.c == nil { - if err := errmsg(C.sp_new_config(&p.c)); err != nil { - return err - } - } - return errmsg(C.sp_get_config(p.p, p.c)) -} - -// Apply port options. -func (p *Port) Apply(o *Options) (err error) { - // get port config - var conf *C.struct_sp_port_config - if err = errmsg(C.sp_new_config(&conf)); err != nil { - return - } - defer C.sp_free_config(conf) - - // set bit rate - if o.BitRate != 0 { - err = errmsg(C.sp_set_config_baudrate(conf, C.int(o.BitRate))) - if err != nil { - return - } - } - - // set data bits - if o.DataBits != 0 { - err = errmsg(C.sp_set_config_bits(conf, C.int(o.DataBits))) - if err != nil { - return - } - } - - // set stop bits - if o.StopBits != 0 { - err = errmsg(C.sp_set_config_stopbits(conf, C.int(o.StopBits))) - if err != nil { - return - } - } - - // set parity - if o.Parity != 0 { - cparity := parity2c(o.Parity) - if err = errmsg(C.sp_set_config_parity(conf, cparity)); err != nil { - return - } - } - - // set flow control - if o.FlowControl != 0 { - cfc, err := flow2c(o.FlowControl) - if err != nil { - return err - } - if err = errmsg(C.sp_set_config_flowcontrol(conf, cfc)); err != nil { - return err - } - } - - // set RTS - if o.RTS != 0 { - crts := rts2c(o.RTS) - if err = errmsg(C.sp_set_config_rts(conf, crts)); err != nil { - return - } - } - - // set CTS - if o.CTS != 0 { - ccts := cts2c(o.CTS) - if err = errmsg(C.sp_set_config_cts(conf, ccts)); err != nil { - return - } - } - - // set DTR - if o.DTR != 0 { - cdtr := dtr2c(o.DTR) - if err = errmsg(C.sp_set_config_dtr(conf, cdtr)); err != nil { - return - } - } - - // set DSR - if o.DSR != 0 { - cdsr := dsr2c(o.DSR) - if err = errmsg(C.sp_set_config_dsr(conf, cdsr)); err != nil { - return - } - } - - // apply config - if err = errmsg(C.sp_set_config(p.p, conf)); err != nil { - return - } - - // update local config - return p.getConf() -} - -// Get the baud rate from a port configuration. The port must be -// opened for this operation. -func (p *Port) BitRate() (int, error) { - var bitrate C.int - if err := errmsg(C.sp_get_config_baudrate(p.c, &bitrate)); err != nil { - return 0, err - } - return int(bitrate), nil -} - -// Set the baud rate for the serial port. The port must be opened for -// this operation. Call p.ApplyConfig() to apply the change. -func (p *Port) SetBitRate(bitrate int) error { - if err := errmsg(C.sp_set_baudrate(p.p, C.int(bitrate))); err != nil { - return err - } - return p.getConf() -} - -// Get the data bits from a port configuration. The port must be -// opened for this operation. -func (p *Port) DataBits() (int, error) { - var bits C.int - if err := errmsg(C.sp_get_config_bits(p.c, &bits)); err != nil { - return 0, err - } - return int(bits), nil -} - -// Set the number of data bits for the serial port. The port must be -// opened for this operation. Call p.ApplyConfig() to apply the -// change. -func (p *Port) SetDataBits(bits int) error { - if err := errmsg(C.sp_set_config_bits(p.c, C.int(bits))); err != nil { - return err - } - return p.getConf() -} - -// Get the stop bits from a port configuration. The port must be -// opened for this operation. -func (p *Port) StopBits() (int, error) { - var stopbits C.int - if err := errmsg(C.sp_get_config_stopbits(p.c, &stopbits)); err != nil { - return 0, err - } - return int(stopbits), nil -} - -// Set the stop bits for the serial port. The port must be opened for -// this operation. Call p.ApplyConfig() to apply the change. -func (p *Port) SetStopBits(stopbits int) error { - if err := errmsg(C.sp_set_config_stopbits(p.c, C.int(stopbits))); err != nil { - return err - } - return p.getConf() -} - -// Get the parity setting from a port configuration. The port must be -// opened for this operation. -func (p *Port) Parity() (int, error) { - cparity := C.enum_sp_parity(C.SP_PARITY_INVALID) - if err := errmsg(C.sp_get_config_parity(p.c, &cparity)); err != nil { - return 0, err - } - return c2parity(cparity), nil -} - -// Set the parity setting for the serial port. The port must be opened -// for this operation. Call p.ApplyConfig() to apply the change. -func (p *Port) SetParity(parity int) error { - cparity := parity2c(parity) - if err := errmsg(C.sp_set_config_parity(p.c, cparity)); err != nil { - return err - } - return p.getConf() -} - -func c2parity(cparity C.enum_sp_parity) int { - switch cparity { - case C.SP_PARITY_NONE: - return PARITY_NONE - case C.SP_PARITY_ODD: - return PARITY_ODD - case C.SP_PARITY_EVEN: - return PARITY_EVEN - case C.SP_PARITY_MARK: - return PARITY_MARK - case C.SP_PARITY_SPACE: - return PARITY_SPACE - default: - return PARITY_INVALID - } -} - -func parity2c(parity int) C.enum_sp_parity { - switch parity { - case PARITY_NONE: - return C.SP_PARITY_NONE - case PARITY_ODD: - return C.SP_PARITY_ODD - case PARITY_EVEN: - return C.SP_PARITY_EVEN - case PARITY_MARK: - return C.SP_PARITY_MARK - case PARITY_SPACE: - return C.SP_PARITY_SPACE - default: - return C.SP_PARITY_INVALID - } -} - -// Get the RTS pin behaviour from a port configuration. The port must -// be opened for this operation. -func (p *Port) RTS() (int, error) { - rts := C.enum_sp_rts(C.SP_RTS_INVALID) - if err := errmsg(C.sp_get_config_rts(p.c, &rts)); err != nil { - return 0, err - } - return c2rts(rts), nil -} - -// Set the RTS pin behaviour in a port configuration. The port must be -// opened for this operation. Call p.ApplyConfig() to apply the -// change. -func (p *Port) SetRTS(rts int) error { - crts := rts2c(rts) - if err := errmsg(C.sp_set_config_rts(p.c, crts)); err != nil { - return err - } - return p.getConf() -} - -func c2rts(rts C.enum_sp_rts) int { - switch rts { - case C.SP_RTS_OFF: - return RTS_OFF - case C.SP_RTS_ON: - return RTS_ON - case C.SP_RTS_FLOW_CONTROL: - return RTS_FLOW_CONTROL - default: - return RTS_INVALID - } -} - -func rts2c(rts int) C.enum_sp_rts { - switch rts { - case RTS_OFF: - return C.SP_RTS_OFF - case RTS_ON: - return C.SP_RTS_ON - case RTS_FLOW_CONTROL: - return C.SP_RTS_FLOW_CONTROL - default: - return C.SP_RTS_INVALID - } -} - -// Get the CTS pin behaviour from a port configuration. The port must -// be opened for this operation. -func (p *Port) CTS() (int, error) { - cts := C.enum_sp_cts(C.SP_CTS_INVALID) - if err := errmsg(C.sp_get_config_cts(p.c, &cts)); err != nil { - return 0, err - } - return c2cts(cts), nil -} - -// Set the CTS pin behaviour in a port configuration. The port must be -// opened for this operation. Call p.ApplyConfig() to apply the -// change. -func (p *Port) SetCTS(cts int) error { - ccts := cts2c(cts) - if err := errmsg(C.sp_set_config_cts(p.c, ccts)); err != nil { - return err - } - return p.getConf() -} - -func c2cts(cts C.enum_sp_cts) int { - switch cts { - case C.SP_CTS_IGNORE: - return CTS_IGNORE - case C.SP_CTS_FLOW_CONTROL: - return CTS_FLOW_CONTROL - default: - return CTS_INVALID - } -} - -func cts2c(cts int) C.enum_sp_cts { - switch cts { - case CTS_IGNORE: - return C.SP_CTS_IGNORE - case CTS_FLOW_CONTROL: - return C.SP_CTS_FLOW_CONTROL - default: - return C.SP_CTS_INVALID - } -} - -// Get the DTR pin behaviour from a port configuration. The port must -// be opened for this operation. -func (p *Port) DTR() (int, error) { - dtr := C.enum_sp_dtr(C.SP_DTR_INVALID) - if err := errmsg(C.sp_get_config_dtr(p.c, &dtr)); err != nil { - return 0, err - } - return c2dtr(dtr), nil -} - -// Set the DTR pin behaviour in a port configuration. The port must be -// opened for this operation. Call p.ApplyConfig() to apply the -// change. -func (p *Port) SetDTR(dtr int) error { - cdtr := dtr2c(dtr) - if err := errmsg(C.sp_set_config_dtr(p.c, cdtr)); err != nil { - return err - } - return p.getConf() -} - -func c2dtr(dtr C.enum_sp_dtr) int { - switch dtr { - case C.SP_DTR_OFF: - return DTR_OFF - case C.SP_DTR_ON: - return DTR_ON - case C.SP_DTR_FLOW_CONTROL: - return DTR_FLOW_CONTROL - default: - return DTR_INVALID - } -} - -func dtr2c(dtr int) C.enum_sp_dtr { - switch dtr { - case DTR_OFF: - return C.SP_DTR_OFF - case DTR_ON: - return C.SP_DTR_ON - case DTR_FLOW_CONTROL: - return C.SP_DTR_FLOW_CONTROL - default: - return C.SP_DTR_INVALID - } -} - -// Get the DSR pin behaviour from a port configuration. The port must -// be opened for this operation. -func (p *Port) DSR() (int, error) { - dsr := C.enum_sp_dsr(C.SP_DSR_INVALID) - if err := errmsg(C.sp_get_config_dsr(p.c, &dsr)); err != nil { - return 0, err - } - return c2dsr(dsr), nil -} - -// Set the DSR pin behaviour in a port configuration. The port must be -// opened for this operation. Call p.ApplyConfig() to apply the -// change. -func (p *Port) SetDSR(dsr int) error { - cdsr := dsr2c(dsr) - if err := errmsg(C.sp_set_config_dsr(p.c, cdsr)); err != nil { - return err - } - return p.getConf() -} - -func c2dsr(dsr C.enum_sp_dsr) int { - switch dsr { - case C.SP_DSR_IGNORE: - return DSR_IGNORE - case C.SP_DSR_FLOW_CONTROL: - return DSR_FLOW_CONTROL - default: - return DSR_INVALID - } -} - -func dsr2c(dsr int) C.enum_sp_dsr { - switch dsr { - case DSR_IGNORE: - return C.SP_DSR_IGNORE - case DSR_FLOW_CONTROL: - return C.SP_DSR_FLOW_CONTROL - default: - return C.SP_DSR_INVALID - } -} - -// Get the XON/XOFF configuration from a port configuration. The port -// must be opened for this operation. -func (p *Port) XonXoff() (int, error) { - xon := C.enum_sp_xonxoff(C.SP_XONXOFF_INVALID) - if err := errmsg(C.sp_get_config_xon_xoff(p.c, &xon)); err != nil { - return 0, err - } - return c2xon(xon), nil -} - -// Set the XON/XOFF configuration in a port configuration. The port -// must be opened for this operation. Call p.ApplyConfig() to apply -// the change. -func (p *Port) SetXonXoff(xon int) error { - cxon := xon2c(xon) - if err := errmsg(C.sp_set_config_xon_xoff(p.c, cxon)); err != nil { - return err - } - return p.getConf() -} - -func c2xon(xon C.enum_sp_xonxoff) int { - switch xon { - case C.SP_XONXOFF_DISABLED: - return XONXOFF_DISABLED - case C.SP_XONXOFF_IN: - return XONXOFF_IN - case C.SP_XONXOFF_OUT: - return XONXOFF_OUT - default: - return XONXOFF_INVALID - } -} - -func xon2c(xon int) C.enum_sp_xonxoff { - switch xon { - case XONXOFF_DISABLED: - return C.SP_XONXOFF_DISABLED - case XONXOFF_IN: - return C.SP_XONXOFF_IN - case XONXOFF_OUT: - return C.SP_XONXOFF_OUT - default: - return C.SP_XONXOFF_INVALID - } -} - -// Set the flow control type in a port configuration. The port must be -// opened for this operation. Call p.ApplyConfig() to apply the -// change. -func (p *Port) SetFlowControl(fc int) error { - cfc, err := flow2c(fc) - if err != nil { - return err - } - - if err := errmsg(C.sp_set_config_flowcontrol(p.c, cfc)); err != nil { - return err - } - - return p.getConf() -} - -func flow2c(fc int) (cfc C.enum_sp_flowcontrol, err error) { - switch fc { - case FLOWCONTROL_NONE: - cfc = C.SP_FLOWCONTROL_NONE - case FLOWCONTROL_XONXOFF: - cfc = C.SP_FLOWCONTROL_XONXOFF - case FLOWCONTROL_RTSCTS: - cfc = C.SP_FLOWCONTROL_RTSCTS - case FLOWCONTROL_DTRDSR: - cfc = C.SP_FLOWCONTROL_DTRDSR - default: - err = ErrInvalidArguments - } - return -} - -// Implementation of io.Reader interface. -func (p *Port) Read(b []byte) (int, error) { - var c int32 - var start time.Time - - if Debug { - start = time.Now() - } - - buf, size := unsafe.Pointer(&b[0]), C.size_t(len(b)) - - if p.readDeadline.IsZero() { - - // no deadline - c = C.sp_blocking_read(p.p, buf, size, 0) - - } else if millis := deadline2millis(p.readDeadline); millis <= 0 { - - // call nonblocking read - c = C.sp_nonblocking_read(p.p, buf, size) - - } else { - - // call blocking read - c = C.sp_blocking_read(p.p, buf, size, C.uint(millis)) - - } - - if Debug { - log.Printf("read time: %d ns", time.Since(start).Nanoseconds()) - } - - n := int(c) - - // check for error - if n < 0 { - return 0, errmsg(c) - } else if n != len(b) { - return n, ErrTimeout - } - - // update slice length - reflect.ValueOf(&b).Elem().SetLen(int(c)) - - return n, nil -} - -// Implementation of io.Writer interface. -func (p *Port) Write(b []byte) (int, error) { - var c int32 - var start time.Time - - if Debug { - start = time.Now() - } - - buf, size := unsafe.Pointer(&b[0]), C.size_t(len(b)) - - if p.writeDeadline.IsZero() { - - // no deadline - c = C.sp_blocking_write(p.p, buf, size, 0) - - } else if millis := deadline2millis(p.writeDeadline); millis <= 0 { - - // call nonblocking write - c = C.sp_nonblocking_write(p.p, buf, size) - - } else { - - // call blocking write - c = C.sp_blocking_write(p.p, buf, size, C.uint(millis)) - - } - - if Debug { - log.Printf("write time: %d ns", time.Since(start).Nanoseconds()) - } - - n := int(c) - - // check for error - if n < 0 { - return 0, errmsg(c) - } else if n != len(b) { - return n, ErrTimeout - } - - return n, nil -} - -// WriteString is like Write, but writes the contents of string s -// rather than a slice of bytes. -func (p *Port) WriteString(s string) (int, error) { - return p.Write(bytes.NewBufferString(s).Bytes()) -} - -// Implementation of net.Conn.LocalAddr -func (p *Port) LocalAddr() net.Addr { - return &Addr{name: p.Name()} -} - -// Implementation of net.Conn.RemoteAddr -func (p *Port) RemoteAddr() net.Addr { - return &Addr{name: p.Name()} -} - -// Implementation of net.Conn.SetDeadline -func (p *Port) SetDeadline(t time.Time) error { - p.readDeadline = t - p.writeDeadline = t - return nil -} - -// Implementation of net.Conn.SetReadDeadline -func (p *Port) SetReadDeadline(t time.Time) error { - p.readDeadline = t - return nil -} - -// Implementation of net.Conn.SetWriteDeadline -func (p *Port) SetWriteDeadline(t time.Time) error { - p.writeDeadline = t - return nil -} - -// Gets the number of bytes waiting in the input buffer. -func (p *Port) InputWaiting() (int, error) { - c := C.sp_input_waiting(p.p) - if c < 0 { - return 0, errmsg(c) - } - return int(c), nil -} - -// Gets the number of bytes waiting in the output buffer. -func (p *Port) OutputWaiting() (int, error) { - c := C.sp_output_waiting(p.p) - if c < 0 { - return 0, errmsg(c) - } - return int(c), nil -} - -// Wait for buffered data to be transmitted. -func (p *Port) Sync() error { - return errmsg(C.sp_drain(p.p)) -} - -// Discard buffered data. -func (p *Port) Reset() error { - return errmsg(C.sp_flush(p.p, C.SP_BUF_BOTH)) -} - -// Discard buffered input data. -func (p *Port) ResetInput() error { - return errmsg(C.sp_flush(p.p, C.SP_BUF_INPUT)) -} - -// Discard buffered output data. -func (p *Port) ResetOutput() error { - return errmsg(C.sp_flush(p.p, C.SP_BUF_OUTPUT)) -} - -// Implementation of net.Addr.Network() -func (a *Addr) Network() string { - return "serial" -} - -// Implementation of net.Addr.String() -func (a *Addr) String() string { - return a.name -} - -// Implementation of error.Error() -func (e *Error) Error() string { - return e.msg -} - -// Implementation of net.Error.Timeout() -func (e *Error) Timeout() bool { - return e.timeout -} - -// Implementation of net.Error.Temporary() -func (e *Error) Temporary() bool { - return e.temporary -} diff --git a/vendor/github.com/facchinm/go-serial-native/serialport.c b/vendor/github.com/facchinm/go-serial-native/serialport.c deleted file mode 100644 index 2ec2c2f19..000000000 --- a/vendor/github.com/facchinm/go-serial-native/serialport.c +++ /dev/null @@ -1,2320 +0,0 @@ -/* - * This file is part of the libserialport project. - * - * Copyright (C) 2010-2012 Bert Vermeulen - * Copyright (C) 2010-2012 Uwe Hermann - * Copyright (C) 2013 Martin Ling - * Copyright (C) 2013 Matthias Heidbrink - * Copyright (C) 2014 Aurelien Jacobs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#include "libserialport.h" -#include "libserialport_internal.h" - -const struct std_baudrate std_baudrates[] = { -#ifdef _WIN32 - /* - * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to - * have documented CBR_* macros. - */ - BAUD(110), BAUD(300), BAUD(600), BAUD(1200), BAUD(2400), BAUD(4800), - BAUD(9600), BAUD(14400), BAUD(19200), BAUD(38400), BAUD(57600), - BAUD(115200), BAUD(128000), BAUD(256000), -#else - BAUD(50), BAUD(75), BAUD(110), BAUD(134), BAUD(150), BAUD(200), - BAUD(300), BAUD(600), BAUD(1200), BAUD(1800), BAUD(2400), BAUD(4800), - BAUD(9600), BAUD(19200), BAUD(38400), BAUD(57600), BAUD(115200), - BAUD(230400), -#if !defined(__APPLE__) && !defined(__OpenBSD__) - BAUD(460800), -#endif -#endif -}; - -void (*sp_debug_handler)(const char *format, ...) = sp_default_debug_handler; - -static enum sp_return get_config(struct sp_port *port, struct port_data *data, - struct sp_port_config *config); - -static enum sp_return set_config(struct sp_port *port, struct port_data *data, - const struct sp_port_config *config); - -SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr) -{ - struct sp_port *port; -#ifndef NO_PORT_METADATA - enum sp_return ret; -#endif - int len; - - TRACE("%s, %p", portname, port_ptr); - - if (!port_ptr) - RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); - - *port_ptr = NULL; - - if (!portname) - RETURN_ERROR(SP_ERR_ARG, "Null port name"); - - DEBUG_FMT("Building structure for port %s", portname); - - if (!(port = malloc(sizeof(struct sp_port)))) - RETURN_ERROR(SP_ERR_MEM, "Port structure malloc failed"); - - len = strlen(portname) + 1; - - if (!(port->name = malloc(len))) { - free(port); - RETURN_ERROR(SP_ERR_MEM, "Port name malloc failed"); - } - - memcpy(port->name, portname, len); - -#ifdef _WIN32 - port->usb_path = NULL; - port->hdl = INVALID_HANDLE_VALUE; -#else - port->fd = -1; -#endif - - port->description = NULL; - port->transport = SP_TRANSPORT_NATIVE; - port->usb_bus = -1; - port->usb_address = -1; - port->usb_vid = -1; - port->usb_pid = -1; - port->usb_manufacturer = NULL; - port->usb_product = NULL; - port->usb_serial = NULL; - port->bluetooth_address = NULL; - -#ifndef NO_PORT_METADATA - if ((ret = get_port_details(port)) != SP_OK) { - sp_free_port(port); - return ret; - } -#endif - - *port_ptr = port; - - RETURN_OK(); -} - -SP_API char *sp_get_port_name(const struct sp_port *port) -{ - TRACE("%p", port); - - if (!port) - return NULL; - - RETURN_STRING(port->name); -} - -SP_API char *sp_get_port_description(struct sp_port *port) -{ - TRACE("%p", port); - - if (!port || !port->description) - return NULL; - - RETURN_STRING(port->description); -} - -SP_API enum sp_transport sp_get_port_transport(struct sp_port *port) -{ - TRACE("%p", port); - - if (!port) - RETURN_ERROR(SP_ERR_ARG, "Null port"); - - RETURN_INT(port->transport); -} - -SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port, - int *usb_bus,int *usb_address) -{ - TRACE("%p", port); - - if (!port) - RETURN_ERROR(SP_ERR_ARG, "Null port"); - if (port->transport != SP_TRANSPORT_USB) - RETURN_ERROR(SP_ERR_ARG, "Port does not use USB transport"); - if (port->usb_bus < 0 || port->usb_address < 0) - RETURN_ERROR(SP_ERR_SUPP, "Bus and address values are not available"); - - if (usb_bus) *usb_bus = port->usb_bus; - if (usb_address) *usb_address = port->usb_address; - - RETURN_OK(); -} - -SP_API enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, - int *usb_vid, int *usb_pid) -{ - TRACE("%p", port); - - if (!port) - RETURN_ERROR(SP_ERR_ARG, "Null port"); - if (port->transport != SP_TRANSPORT_USB) - RETURN_ERROR(SP_ERR_ARG, "Port does not use USB transport"); - if (port->usb_vid < 0 || port->usb_pid < 0) - RETURN_ERROR(SP_ERR_SUPP, "VID:PID values are not available"); - - if (usb_vid) *usb_vid = port->usb_vid; - if (usb_pid) *usb_pid = port->usb_pid; - - RETURN_OK(); -} - -SP_API char *sp_get_port_usb_manufacturer(const struct sp_port *port) -{ - TRACE("%p", port); - - if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_manufacturer) - return NULL; - - RETURN_STRING(port->usb_manufacturer); -} - -SP_API char *sp_get_port_usb_product(const struct sp_port *port) -{ - TRACE("%p", port); - - if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_product) - return NULL; - - RETURN_STRING(port->usb_product); -} - -SP_API char *sp_get_port_usb_serial(const struct sp_port *port) -{ - TRACE("%p", port); - - if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_serial) - return NULL; - - RETURN_STRING(port->usb_serial); -} - -SP_API char *sp_get_port_bluetooth_address(const struct sp_port *port) -{ - TRACE("%p", port); - - if (!port || port->transport != SP_TRANSPORT_BLUETOOTH - || !port->bluetooth_address) - return NULL; - - RETURN_STRING(port->bluetooth_address); -} - -SP_API enum sp_return sp_get_port_handle(const struct sp_port *port, - void *result_ptr) -{ - TRACE("%p, %p", port, result_ptr); - - if (!port) - RETURN_ERROR(SP_ERR_ARG, "Null port"); - -#ifdef _WIN32 - HANDLE *handle_ptr = result_ptr; - *handle_ptr = port->hdl; -#else - int *fd_ptr = result_ptr; - *fd_ptr = port->fd; -#endif - - RETURN_OK(); -} - -SP_API enum sp_return sp_copy_port(const struct sp_port *port, - struct sp_port **copy_ptr) -{ - TRACE("%p, %p", port, copy_ptr); - - if (!copy_ptr) - RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); - - *copy_ptr = NULL; - - if (!port) - RETURN_ERROR(SP_ERR_ARG, "Null port"); - - if (!port->name) - RETURN_ERROR(SP_ERR_ARG, "Null port name"); - - DEBUG("Copying port structure"); - - RETURN_INT(sp_get_port_by_name(port->name, copy_ptr)); -} - -SP_API void sp_free_port(struct sp_port *port) -{ - TRACE("%p", port); - - if (!port) { - DEBUG("Null port"); - RETURN(); - } - - DEBUG("Freeing port structure"); - - if (port->name) - free(port->name); - if (port->description) - free(port->description); - if (port->usb_manufacturer) - free(port->usb_manufacturer); - if (port->usb_product) - free(port->usb_product); - if (port->usb_serial) - free(port->usb_serial); - if (port->bluetooth_address) - free(port->bluetooth_address); -#ifdef _WIN32 - if (port->usb_path) - free(port->usb_path); -#endif - - free(port); - - RETURN(); -} - -SP_PRIV struct sp_port **list_append(struct sp_port **list, - const char *portname) -{ - void *tmp; - unsigned int count; - - for (count = 0; list[count]; count++); - if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2)))) - goto fail; - list = tmp; - if (sp_get_port_by_name(portname, &list[count]) != SP_OK) - goto fail; - list[count + 1] = NULL; - return list; - -fail: - sp_free_port_list(list); - return NULL; -} - -SP_API enum sp_return sp_list_ports(struct sp_port ***list_ptr) -{ - struct sp_port **list; - int ret; - - TRACE("%p", list_ptr); - - if (!list_ptr) - RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); - - DEBUG("Enumerating ports"); - - if (!(list = malloc(sizeof(struct sp_port **)))) - RETURN_ERROR(SP_ERR_MEM, "Port list malloc failed"); - - list[0] = NULL; - -#ifdef NO_ENUMERATION - ret = SP_ERR_SUPP; -#else - ret = list_ports(&list); -#endif - - switch (ret) { - case SP_OK: - *list_ptr = list; - RETURN_OK(); - case SP_ERR_SUPP: - DEBUG_ERROR(SP_ERR_SUPP, "Enumeration not supported on this platform"); - default: - if (list) - sp_free_port_list(list); - *list_ptr = NULL; - return ret; - } -} - -SP_API void sp_free_port_list(struct sp_port **list) -{ - unsigned int i; - - TRACE("%p", list); - - if (!list) { - DEBUG("Null list"); - RETURN(); - } - - DEBUG("Freeing port list"); - - for (i = 0; list[i]; i++) - sp_free_port(list[i]); - free(list); - - RETURN(); -} - -#define CHECK_PORT() do { \ - if (port == NULL) \ - RETURN_ERROR(SP_ERR_ARG, "Null port"); \ - if (port->name == NULL) \ - RETURN_ERROR(SP_ERR_ARG, "Null port name"); \ -} while (0) -#ifdef _WIN32 -#define CHECK_PORT_HANDLE() do { \ - if (port->hdl == INVALID_HANDLE_VALUE) \ - RETURN_ERROR(SP_ERR_ARG, "Invalid port handle"); \ -} while (0) -#else -#define CHECK_PORT_HANDLE() do { \ - if (port->fd < 0) \ - RETURN_ERROR(SP_ERR_ARG, "Invalid port fd"); \ -} while (0) -#endif -#define CHECK_OPEN_PORT() do { \ - CHECK_PORT(); \ - CHECK_PORT_HANDLE(); \ -} while (0) - -SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags) -{ - struct port_data data; - struct sp_port_config config; - enum sp_return ret; - - TRACE("%p, 0x%x", port, flags); - - CHECK_PORT(); - - if (flags > SP_MODE_READ_WRITE) - RETURN_ERROR(SP_ERR_ARG, "Invalid flags"); - - DEBUG_FMT("Opening port %s", port->name); - -#ifdef _WIN32 - DWORD desired_access = 0, flags_and_attributes = 0, errors; - char *escaped_port_name; - COMSTAT status; - - /* Prefix port name with '\\.\' to work with ports above COM9. */ - if (!(escaped_port_name = malloc(strlen(port->name) + 5))) - RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed"); - sprintf(escaped_port_name, "\\\\.\\%s", port->name); - - /* Map 'flags' to the OS-specific settings. */ - flags_and_attributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED; - if (flags & SP_MODE_READ) - desired_access |= GENERIC_READ; - if (flags & SP_MODE_WRITE) - desired_access |= GENERIC_WRITE; - - port->hdl = CreateFile(escaped_port_name, desired_access, 0, 0, - OPEN_EXISTING, flags_and_attributes, 0); - - free(escaped_port_name); - - if (port->hdl == INVALID_HANDLE_VALUE) - RETURN_FAIL("port CreateFile() failed"); - - /* All timeouts initially disabled. */ - port->timeouts.ReadIntervalTimeout = 0; - port->timeouts.ReadTotalTimeoutMultiplier = 0; - port->timeouts.ReadTotalTimeoutConstant = 0; - port->timeouts.WriteTotalTimeoutMultiplier = 0; - port->timeouts.WriteTotalTimeoutConstant = 0; - - if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) { - sp_close(port); - RETURN_FAIL("SetCommTimeouts() failed"); - } - - /* Prepare OVERLAPPED structures. */ -#define INIT_OVERLAPPED(ovl) do { \ - memset(&port->ovl, 0, sizeof(port->ovl)); \ - port->ovl.hEvent = INVALID_HANDLE_VALUE; \ - if ((port->ovl.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) \ - == INVALID_HANDLE_VALUE) { \ - sp_close(port); \ - RETURN_FAIL(#ovl "CreateEvent() failed"); \ - } \ -} while (0) - - INIT_OVERLAPPED(read_ovl); - INIT_OVERLAPPED(write_ovl); - INIT_OVERLAPPED(wait_ovl); - - /* Set event mask for RX and error events. */ - if (SetCommMask(port->hdl, EV_RXCHAR | EV_ERR) == 0) { - sp_close(port); - RETURN_FAIL("SetCommMask() failed"); - } - - /* Start background operation for RX and error events. */ - if (WaitCommEvent(port->hdl, &port->events, &port->wait_ovl) == 0) { - if (GetLastError() != ERROR_IO_PENDING) { - sp_close(port); - RETURN_FAIL("WaitCommEvent() failed"); - } - } - - port->writing = FALSE; - -#else - int flags_local = O_NONBLOCK | O_NOCTTY; - - /* Map 'flags' to the OS-specific settings. */ - if ((flags & SP_MODE_READ_WRITE) == SP_MODE_READ_WRITE) - flags_local |= O_RDWR; - else if (flags & SP_MODE_READ) - flags_local |= O_RDONLY; - else if (flags & SP_MODE_WRITE) - flags_local |= O_WRONLY; - - if ((port->fd = open(port->name, flags_local)) < 0) - RETURN_FAIL("open() failed"); -#endif - - ret = get_config(port, &data, &config); - - if (ret < 0) { - sp_close(port); - RETURN_CODEVAL(ret); - } - - /* Set sane port settings. */ -#ifdef _WIN32 - data.dcb.fBinary = TRUE; - data.dcb.fDsrSensitivity = FALSE; - data.dcb.fErrorChar = FALSE; - data.dcb.fNull = FALSE; - data.dcb.fAbortOnError = TRUE; -#else - /* Turn off all fancy termios tricks, give us a raw channel. */ - data.term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IMAXBEL); -#ifdef IUCLC - data.term.c_iflag &= ~IUCLC; -#endif - data.term.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET); -#ifdef OLCUC - data.term.c_oflag &= ~OLCUC; -#endif -#ifdef NLDLY - data.term.c_oflag &= ~NLDLY; -#endif -#ifdef CRDLY - data.term.c_oflag &= ~CRDLY; -#endif -#ifdef TABDLY - data.term.c_oflag &= ~TABDLY; -#endif -#ifdef BSDLY - data.term.c_oflag &= ~BSDLY; -#endif -#ifdef VTDLY - data.term.c_oflag &= ~VTDLY; -#endif -#ifdef FFDLY - data.term.c_oflag &= ~FFDLY; -#endif -#ifdef OFILL - data.term.c_oflag &= ~OFILL; -#endif - data.term.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN); - data.term.c_cc[VMIN] = 0; - data.term.c_cc[VTIME] = 0; - - /* Ignore modem status lines; enable receiver; leave control lines alone on close. */ - data.term.c_cflag |= (CLOCAL | CREAD | HUPCL); -#endif - -#ifdef _WIN32 - if (ClearCommError(port->hdl, &errors, &status) == 0) - RETURN_FAIL("ClearCommError() failed"); -#endif - - ret = set_config(port, &data, &config); - - if (ret < 0) { - sp_close(port); - RETURN_CODEVAL(ret); - } - - RETURN_OK(); -} - -SP_API enum sp_return sp_close(struct sp_port *port) -{ - TRACE("%p", port); - - CHECK_OPEN_PORT(); - - DEBUG_FMT("Closing port %s", port->name); - -#ifdef _WIN32 - /* Returns non-zero upon success, 0 upon failure. */ - if (CloseHandle(port->hdl) == 0) - RETURN_FAIL("port CloseHandle() failed"); - port->hdl = INVALID_HANDLE_VALUE; - - /* Close event handles for overlapped structures. */ -#define CLOSE_OVERLAPPED(ovl) do { \ - if (port->ovl.hEvent != INVALID_HANDLE_VALUE && \ - CloseHandle(port->ovl.hEvent) == 0) \ - RETURN_FAIL(# ovl "event CloseHandle() failed"); \ -} while (0) - CLOSE_OVERLAPPED(read_ovl); - CLOSE_OVERLAPPED(write_ovl); - CLOSE_OVERLAPPED(wait_ovl); - -#else - /* Returns 0 upon success, -1 upon failure. */ - if (close(port->fd) == -1) - RETURN_FAIL("close() failed"); - port->fd = -1; -#endif - - RETURN_OK(); -} - -SP_API enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers) -{ - TRACE("%p, 0x%x", port, buffers); - - CHECK_OPEN_PORT(); - - if (buffers > SP_BUF_BOTH) - RETURN_ERROR(SP_ERR_ARG, "Invalid buffer selection"); - - const char *buffer_names[] = {"no", "input", "output", "both"}; - - DEBUG_FMT("Flushing %s buffers on port %s", - buffer_names[buffers], port->name); - -#ifdef _WIN32 - DWORD flags = 0; - if (buffers & SP_BUF_INPUT) - flags |= PURGE_RXCLEAR; - if (buffers & SP_BUF_OUTPUT) - flags |= PURGE_TXCLEAR; - - /* Returns non-zero upon success, 0 upon failure. */ - if (PurgeComm(port->hdl, flags) == 0) - RETURN_FAIL("PurgeComm() failed"); -#else - int flags = 0; - if (buffers == SP_BUF_BOTH) - flags = TCIOFLUSH; - else if (buffers == SP_BUF_INPUT) - flags = TCIFLUSH; - else if (buffers == SP_BUF_OUTPUT) - flags = TCOFLUSH; - - /* Returns 0 upon success, -1 upon failure. */ - if (tcflush(port->fd, flags) < 0) - RETURN_FAIL("tcflush() failed"); -#endif - RETURN_OK(); -} - -SP_API enum sp_return sp_drain(struct sp_port *port) -{ - TRACE("%p", port); - - CHECK_OPEN_PORT(); - - DEBUG_FMT("Draining port %s", port->name); - -#ifdef _WIN32 - /* Returns non-zero upon success, 0 upon failure. */ - if (FlushFileBuffers(port->hdl) == 0) - RETURN_FAIL("FlushFileBuffers() failed"); - RETURN_OK(); -#else - int result; - while (1) { -#ifdef __ANDROID__ - int arg = 1; - result = ioctl(port->fd, TCSBRK, &arg); -#else - result = tcdrain(port->fd); -#endif - if (result < 0) { - if (errno == EINTR) { - DEBUG("tcdrain() was interrupted"); - continue; - } else { - RETURN_FAIL("tcdrain() failed"); - } - } else { - RETURN_OK(); - } - } -#endif -} - -SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, - size_t count, unsigned int timeout) -{ - TRACE("%p, %p, %d, %d", port, buf, count, timeout); - - CHECK_OPEN_PORT(); - - if (!buf) - RETURN_ERROR(SP_ERR_ARG, "Null buffer"); - - if (timeout) - DEBUG_FMT("Writing %d bytes to port %s, timeout %d ms", - count, port->name, timeout); - else - DEBUG_FMT("Writing %d bytes to port %s, no timeout", - count, port->name); - - if (count == 0) - RETURN_INT(0); - -#ifdef _WIN32 - DWORD bytes_written = 0; - BOOL result; - - /* Wait for previous non-blocking write to complete, if any. */ - if (port->writing) { - DEBUG("Waiting for previous write to complete"); - result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE); - port->writing = 0; - if (!result) - RETURN_FAIL("Previous write failed to complete"); - DEBUG("Previous write completed"); - } - - /* Set timeout. */ - port->timeouts.WriteTotalTimeoutConstant = timeout; - if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) - RETURN_FAIL("SetCommTimeouts() failed"); - - /* Start write. */ - if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl) == 0) { - if (GetLastError() == ERROR_IO_PENDING) { - DEBUG("Waiting for write to complete"); - GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE); - DEBUG_FMT("Write completed, %d/%d bytes written", bytes_written, count); - RETURN_INT(bytes_written); - } else { - RETURN_FAIL("WriteFile() failed"); - } - } else { - DEBUG("Write completed immediately"); - RETURN_INT(count); - } -#else - size_t bytes_written = 0; - unsigned char *ptr = (unsigned char *) buf; - struct timeval start, delta, now, end = {0, 0}; - fd_set fds; - int result; - - if (timeout) { - /* Get time at start of operation. */ - gettimeofday(&start, NULL); - /* Define duration of timeout. */ - delta.tv_sec = timeout / 1000; - delta.tv_usec = (timeout % 1000) * 1000; - /* Calculate time at which we should give up. */ - timeradd(&start, &delta, &end); - } - - /* Loop until we have written the requested number of bytes. */ - while (bytes_written < count) - { - /* Wait until space is available. */ - FD_ZERO(&fds); - FD_SET(port->fd, &fds); - if (timeout) { - gettimeofday(&now, NULL); - if (timercmp(&now, &end, >)) { - DEBUG("write timed out"); - RETURN_INT(bytes_written); - } - timersub(&end, &now, &delta); - } - result = select(port->fd + 1, NULL, &fds, NULL, timeout ? &delta : NULL); - if (result < 0) { - if (errno == EINTR) { - DEBUG("select() call was interrupted, repeating"); - continue; - } else { - RETURN_FAIL("select() failed"); - } - } else if (result == 0) { - DEBUG("write timed out"); - RETURN_INT(bytes_written); - } - - /* Do write. */ - result = write(port->fd, ptr, count - bytes_written); - - if (result < 0) { - if (errno == EAGAIN) - /* This shouldn't happen because we did a select() first, but handle anyway. */ - continue; - else - /* This is an actual failure. */ - RETURN_FAIL("write() failed"); - } - - bytes_written += result; - ptr += result; - } - - RETURN_INT(bytes_written); -#endif -} - -SP_API enum sp_return sp_nonblocking_write(struct sp_port *port, - const void *buf, size_t count) -{ - TRACE("%p, %p, %d", port, buf, count); - - CHECK_OPEN_PORT(); - - if (!buf) - RETURN_ERROR(SP_ERR_ARG, "Null buffer"); - - DEBUG_FMT("Writing up to %d bytes to port %s", count, port->name); - - if (count == 0) - RETURN_INT(0); - -#ifdef _WIN32 - DWORD written = 0; - BYTE *ptr = (BYTE *) buf; - - /* Check whether previous write is complete. */ - if (port->writing) { - if (HasOverlappedIoCompleted(&port->write_ovl)) { - DEBUG("Previous write completed"); - port->writing = 0; - } else { - DEBUG("Previous write not complete"); - /* Can't take a new write until the previous one finishes. */ - RETURN_INT(0); - } - } - - /* Set timeout. */ - port->timeouts.WriteTotalTimeoutConstant = 0; - if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) - RETURN_FAIL("SetCommTimeouts() failed"); - - /* Keep writing data until the OS has to actually start an async IO for it. - * At that point we know the buffer is full. */ - while (written < count) - { - /* Copy first byte of user buffer. */ - port->pending_byte = *ptr++; - - /* Start asynchronous write. */ - if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) { - if (GetLastError() == ERROR_IO_PENDING) { - if (HasOverlappedIoCompleted(&port->write_ovl)) { - DEBUG("Asynchronous write completed immediately"); - port->writing = 0; - written++; - continue; - } else { - DEBUG("Asynchronous write running"); - port->writing = 1; - RETURN_INT(++written); - } - } else { - /* Actual failure of some kind. */ - RETURN_FAIL("WriteFile() failed"); - } - } else { - DEBUG("Single byte written immediately"); - written++; - } - } - - DEBUG("All bytes written immediately"); - - RETURN_INT(written); -#else - /* Returns the number of bytes written, or -1 upon failure. */ - ssize_t written = write(port->fd, buf, count); - - if (written < 0) - RETURN_FAIL("write() failed"); - else - RETURN_INT(written); -#endif -} - -SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf, - size_t count, unsigned int timeout) -{ - TRACE("%p, %p, %d, %d", port, buf, count, timeout); - - CHECK_OPEN_PORT(); - - if (!buf) - RETURN_ERROR(SP_ERR_ARG, "Null buffer"); - - if (timeout) - DEBUG_FMT("Reading %d bytes from port %s, timeout %d ms", - count, port->name, timeout); - else - DEBUG_FMT("Reading %d bytes from port %s, no timeout", - count, port->name); - - if (count == 0) - RETURN_INT(0); - -#ifdef _WIN32 - DWORD bytes_read = 0; - - /* Set timeout. */ - port->timeouts.ReadIntervalTimeout = 0; - port->timeouts.ReadTotalTimeoutConstant = timeout; - if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) - RETURN_FAIL("SetCommTimeouts() failed"); - - /* Start read. */ - if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0) { - if (GetLastError() == ERROR_IO_PENDING) { - DEBUG("Waiting for read to complete"); - GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE); - DEBUG_FMT("Read completed, %d/%d bytes read", bytes_read, count); - } else { - RETURN_FAIL("ReadFile() failed"); - } - } else { - DEBUG("Read completed immediately"); - bytes_read = count; - } - - /* Start background operation for subsequent events. */ - if (WaitCommEvent(port->hdl, &port->events, &port->wait_ovl) == 0) { - if (GetLastError() != ERROR_IO_PENDING) - RETURN_FAIL("WaitCommEvent() failed"); - } - - RETURN_INT(bytes_read); - -#else - size_t bytes_read = 0; - unsigned char *ptr = (unsigned char *) buf; - struct timeval start, delta, now, end = {0, 0}; - fd_set fds; - int result; - - if (timeout) { - /* Get time at start of operation. */ - gettimeofday(&start, NULL); - /* Define duration of timeout. */ - delta.tv_sec = timeout / 1000; - delta.tv_usec = (timeout % 1000) * 1000; - /* Calculate time at which we should give up. */ - timeradd(&start, &delta, &end); - } - - /* Loop until we have the requested number of bytes. */ - while (bytes_read < count) - { - /* Wait until data is available. */ - FD_ZERO(&fds); - FD_SET(port->fd, &fds); - if (timeout) { - gettimeofday(&now, NULL); - if (timercmp(&now, &end, >)) - /* Timeout has expired. */ - RETURN_INT(bytes_read); - timersub(&end, &now, &delta); - } - result = select(port->fd + 1, &fds, NULL, NULL, timeout ? &delta : NULL); - if (result < 0) { - if (errno == EINTR) { - DEBUG("select() call was interrupted, repeating"); - continue; - } else { - RETURN_FAIL("select() failed"); - } - } else if (result == 0) { - DEBUG("read timed out"); - RETURN_INT(bytes_read); - } - - /* Do read. */ - result = read(port->fd, ptr, count - bytes_read); - - if (result < 0) { - if (errno == EAGAIN) - /* This shouldn't happen because we did a select() first, but handle anyway. */ - continue; - else - /* This is an actual failure. */ - RETURN_FAIL("read() failed"); - } - - bytes_read += result; - ptr += result; - } - - RETURN_INT(bytes_read); -#endif -} - -SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, - size_t count) -{ - TRACE("%p, %p, %d", port, buf, count); - - CHECK_OPEN_PORT(); - - if (!buf) - RETURN_ERROR(SP_ERR_ARG, "Null buffer"); - - DEBUG_FMT("Reading up to %d bytes from port %s", count, port->name); - -#ifdef _WIN32 - DWORD bytes_read; - - /* Set timeout. */ - port->timeouts.ReadIntervalTimeout = MAXDWORD; - port->timeouts.ReadTotalTimeoutConstant = 0; - if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) - RETURN_FAIL("SetCommTimeouts() failed"); - - /* Do read. */ - if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0) - RETURN_FAIL("ReadFile() failed"); - - /* Get number of bytes read. */ - if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0) - RETURN_FAIL("GetOverlappedResult() failed"); - - if (bytes_read > 0) { - /* Start background operation for subsequent events. */ - if (WaitCommEvent(port->hdl, &port->events, &port->wait_ovl) == 0) { - if (GetLastError() != ERROR_IO_PENDING) - RETURN_FAIL("WaitCommEvent() failed"); - } - } - - RETURN_INT(bytes_read); -#else - ssize_t bytes_read; - - /* Returns the number of bytes read, or -1 upon failure. */ - if ((bytes_read = read(port->fd, buf, count)) < 0) { - if (errno == EAGAIN) - /* No bytes available. */ - bytes_read = 0; - else - /* This is an actual failure. */ - RETURN_FAIL("read() failed"); - } - RETURN_INT(bytes_read); -#endif -} - -SP_API enum sp_return sp_input_waiting(struct sp_port *port) -{ - TRACE("%p", port); - - CHECK_OPEN_PORT(); - - DEBUG_FMT("Checking input bytes waiting on port %s", port->name); - -#ifdef _WIN32 - DWORD errors; - COMSTAT comstat; - - if (ClearCommError(port->hdl, &errors, &comstat) == 0) - RETURN_FAIL("ClearCommError() failed"); - RETURN_INT(comstat.cbInQue); -#else - int bytes_waiting; - if (ioctl(port->fd, TIOCINQ, &bytes_waiting) < 0) - RETURN_FAIL("TIOCINQ ioctl failed"); - RETURN_INT(bytes_waiting); -#endif -} - -SP_API enum sp_return sp_output_waiting(struct sp_port *port) -{ - TRACE("%p", port); - - CHECK_OPEN_PORT(); - - DEBUG_FMT("Checking output bytes waiting on port %s", port->name); - -#ifdef _WIN32 - DWORD errors; - COMSTAT comstat; - - if (ClearCommError(port->hdl, &errors, &comstat) == 0) - RETURN_FAIL("ClearCommError() failed"); - RETURN_INT(comstat.cbOutQue); -#else - int bytes_waiting; - if (ioctl(port->fd, TIOCOUTQ, &bytes_waiting) < 0) - RETURN_FAIL("TIOCOUTQ ioctl failed"); - RETURN_INT(bytes_waiting); -#endif -} - -SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr) -{ - struct sp_event_set *result; - - TRACE("%p", result_ptr); - - if (!result_ptr) - RETURN_ERROR(SP_ERR_ARG, "Null result"); - - *result_ptr = NULL; - - if (!(result = malloc(sizeof(struct sp_event_set)))) - RETURN_ERROR(SP_ERR_MEM, "sp_event_set malloc() failed"); - - memset(result, 0, sizeof(struct sp_event_set)); - - *result_ptr = result; - - RETURN_OK(); -} - -static enum sp_return add_handle(struct sp_event_set *event_set, - event_handle handle, enum sp_event mask) -{ - void *new_handles; - enum sp_event *new_masks; - - TRACE("%p, %d, %d", event_set, handle, mask); - - if (!(new_handles = realloc(event_set->handles, - sizeof(event_handle) * (event_set->count + 1)))) - RETURN_ERROR(SP_ERR_MEM, "handle array realloc() failed"); - - if (!(new_masks = realloc(event_set->masks, - sizeof(enum sp_event) * (event_set->count + 1)))) - RETURN_ERROR(SP_ERR_MEM, "mask array realloc() failed"); - - event_set->handles = new_handles; - event_set->masks = new_masks; - - ((event_handle *) event_set->handles)[event_set->count] = handle; - event_set->masks[event_set->count] = mask; - - event_set->count++; - - RETURN_OK(); -} - -SP_API enum sp_return sp_add_port_events(struct sp_event_set *event_set, - const struct sp_port *port, enum sp_event mask) -{ - TRACE("%p, %p, %d", event_set, port, mask); - - if (!event_set) - RETURN_ERROR(SP_ERR_ARG, "Null event set"); - - if (!port) - RETURN_ERROR(SP_ERR_ARG, "Null port"); - - if (mask > (SP_EVENT_RX_READY | SP_EVENT_TX_READY | SP_EVENT_ERROR)) - RETURN_ERROR(SP_ERR_ARG, "Invalid event mask"); - - if (!mask) - RETURN_OK(); - -#ifdef _WIN32 - enum sp_event handle_mask; - if ((handle_mask = mask & SP_EVENT_TX_READY)) - TRY(add_handle(event_set, port->write_ovl.hEvent, handle_mask)); - if ((handle_mask = mask & (SP_EVENT_RX_READY | SP_EVENT_ERROR))) - TRY(add_handle(event_set, port->wait_ovl.hEvent, handle_mask)); -#else - TRY(add_handle(event_set, port->fd, mask)); -#endif - - RETURN_OK(); -} - -SP_API void sp_free_event_set(struct sp_event_set *event_set) -{ - TRACE("%p", event_set); - - if (!event_set) { - DEBUG("Null event set"); - RETURN(); - } - - DEBUG("Freeing event set"); - - if (event_set->handles) - free(event_set->handles); - if (event_set->masks) - free(event_set->masks); - - free(event_set); - - RETURN(); -} - -SP_API enum sp_return sp_wait(struct sp_event_set *event_set, - unsigned int timeout) -{ - TRACE("%p, %d", event_set, timeout); - - if (!event_set) - RETURN_ERROR(SP_ERR_ARG, "Null event set"); - -#ifdef _WIN32 - if (WaitForMultipleObjects(event_set->count, event_set->handles, FALSE, - timeout ? timeout : INFINITE) == WAIT_FAILED) - RETURN_FAIL("WaitForMultipleObjects() failed"); - - RETURN_OK(); -#else - struct timeval start, delta, now, end = {0, 0}; - int result, timeout_remaining; - struct pollfd *pollfds; - unsigned int i; - - if (!(pollfds = malloc(sizeof(struct pollfd) * event_set->count))) - RETURN_ERROR(SP_ERR_MEM, "pollfds malloc() failed"); - - for (i = 0; i < event_set->count; i++) { - pollfds[i].fd = ((int *) event_set->handles)[i]; - pollfds[i].events = 0; - pollfds[i].revents = 0; - if (event_set->masks[i] & SP_EVENT_RX_READY) - pollfds[i].events |= POLLIN; - if (event_set->masks[i] & SP_EVENT_TX_READY) - pollfds[i].events |= POLLOUT; - if (event_set->masks[i] & SP_EVENT_ERROR) - pollfds[i].events |= POLLERR; - } - - if (timeout) { - /* Get time at start of operation. */ - gettimeofday(&start, NULL); - /* Define duration of timeout. */ - delta.tv_sec = timeout / 1000; - delta.tv_usec = (timeout % 1000) * 1000; - /* Calculate time at which we should give up. */ - timeradd(&start, &delta, &end); - } - - /* Loop until an event occurs. */ - while (1) - { - if (timeout) { - gettimeofday(&now, NULL); - if (timercmp(&now, &end, >)) { - DEBUG("wait timed out"); - break; - } - timersub(&end, &now, &delta); - timeout_remaining = delta.tv_sec * 1000 + delta.tv_usec / 1000; - } - - result = poll(pollfds, event_set->count, timeout ? timeout_remaining : -1); - - if (result < 0) { - if (errno == EINTR) { - DEBUG("poll() call was interrupted, repeating"); - continue; - } else { - free(pollfds); - RETURN_FAIL("poll() failed"); - } - } else if (result == 0) { - DEBUG("poll() timed out"); - break; - } else { - DEBUG("poll() completed"); - break; - } - } - - free(pollfds); - RETURN_OK(); -#endif -} - -#ifdef USE_TERMIOS_SPEED -static enum sp_return get_baudrate(int fd, int *baudrate) -{ - void *data; - - TRACE("%d, %p", fd, baudrate); - - DEBUG("Getting baud rate"); - - if (!(data = malloc(get_termios_size()))) - RETURN_ERROR(SP_ERR_MEM, "termios malloc failed"); - - if (ioctl(fd, get_termios_get_ioctl(), data) < 0) { - free(data); - RETURN_FAIL("getting termios failed"); - } - - *baudrate = get_termios_speed(data); - - free(data); - - RETURN_OK(); -} - -static enum sp_return set_baudrate(int fd, int baudrate) -{ - void *data; - - TRACE("%d, %d", fd, baudrate); - - DEBUG("Getting baud rate"); - - if (!(data = malloc(get_termios_size()))) - RETURN_ERROR(SP_ERR_MEM, "termios malloc failed"); - - if (ioctl(fd, get_termios_get_ioctl(), data) < 0) { - free(data); - RETURN_FAIL("getting termios failed"); - } - - DEBUG("Setting baud rate"); - - set_termios_speed(data, baudrate); - - if (ioctl(fd, get_termios_set_ioctl(), data) < 0) { - free(data); - RETURN_FAIL("setting termios failed"); - } - - free(data); - - RETURN_OK(); -} -#endif /* USE_TERMIOS_SPEED */ - -#ifdef USE_TERMIOX -static enum sp_return get_flow(int fd, struct port_data *data) -{ - void *termx; - - TRACE("%d, %p", fd, data); - - DEBUG("Getting advanced flow control"); - - if (!(termx = malloc(get_termiox_size()))) - RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed"); - - if (ioctl(fd, TCGETX, termx) < 0) { - free(termx); - RETURN_FAIL("getting termiox failed"); - } - - get_termiox_flow(termx, &data->rts_flow, &data->cts_flow, - &data->dtr_flow, &data->dsr_flow); - - free(termx); - - RETURN_OK(); -} - -static enum sp_return set_flow(int fd, struct port_data *data) -{ - void *termx; - - TRACE("%d, %p", fd, data); - - DEBUG("Getting advanced flow control"); - - if (!(termx = malloc(get_termiox_size()))) - RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed"); - - if (ioctl(fd, TCGETX, termx) < 0) { - free(termx); - RETURN_FAIL("getting termiox failed"); - } - - DEBUG("Setting advanced flow control"); - - set_termiox_flow(termx, data->rts_flow, data->cts_flow, - data->dtr_flow, data->dsr_flow); - - if (ioctl(fd, TCSETX, termx) < 0) { - free(termx); - RETURN_FAIL("setting termiox failed"); - } - - free(termx); - - RETURN_OK(); -} -#endif /* USE_TERMIOX */ - -static enum sp_return get_config(struct sp_port *port, struct port_data *data, - struct sp_port_config *config) -{ - unsigned int i; - - TRACE("%p, %p, %p", port, data, config); - - DEBUG_FMT("Getting configuration for port %s", port->name); - -#ifdef _WIN32 - if (!GetCommState(port->hdl, &data->dcb)) - RETURN_FAIL("GetCommState() failed"); - - for (i = 0; i < NUM_STD_BAUDRATES; i++) { - if (data->dcb.BaudRate == std_baudrates[i].index) { - config->baudrate = std_baudrates[i].value; - break; - } - } - - if (i == NUM_STD_BAUDRATES) - /* BaudRate field can be either an index or a custom baud rate. */ - config->baudrate = data->dcb.BaudRate; - - config->bits = data->dcb.ByteSize; - - if (data->dcb.fParity) - switch (data->dcb.Parity) { - case NOPARITY: - config->parity = SP_PARITY_NONE; - break; - case ODDPARITY: - config->parity = SP_PARITY_ODD; - break; - case EVENPARITY: - config->parity = SP_PARITY_EVEN; - break; - case MARKPARITY: - config->parity = SP_PARITY_MARK; - break; - case SPACEPARITY: - config->parity = SP_PARITY_SPACE; - break; - default: - config->parity = -1; - } - else - config->parity = SP_PARITY_NONE; - - switch (data->dcb.StopBits) { - case ONESTOPBIT: - config->stopbits = 1; - break; - case TWOSTOPBITS: - config->stopbits = 2; - break; - default: - config->stopbits = -1; - } - - switch (data->dcb.fRtsControl) { - case RTS_CONTROL_DISABLE: - config->rts = SP_RTS_OFF; - break; - case RTS_CONTROL_ENABLE: - config->rts = SP_RTS_ON; - break; - case RTS_CONTROL_HANDSHAKE: - config->rts = SP_RTS_FLOW_CONTROL; - break; - default: - config->rts = -1; - } - - config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE; - - switch (data->dcb.fDtrControl) { - case DTR_CONTROL_DISABLE: - config->dtr = SP_DTR_OFF; - break; - case DTR_CONTROL_ENABLE: - config->dtr = SP_DTR_ON; - break; - case DTR_CONTROL_HANDSHAKE: - config->dtr = SP_DTR_FLOW_CONTROL; - break; - default: - config->dtr = -1; - } - - config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE; - - if (data->dcb.fInX) { - if (data->dcb.fOutX) - config->xon_xoff = SP_XONXOFF_INOUT; - else - config->xon_xoff = SP_XONXOFF_IN; - } else { - if (data->dcb.fOutX) - config->xon_xoff = SP_XONXOFF_OUT; - else - config->xon_xoff = SP_XONXOFF_DISABLED; - } - -#else // !_WIN32 - - if (tcgetattr(port->fd, &data->term) < 0) - RETURN_FAIL("tcgetattr() failed"); - - if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0) - RETURN_FAIL("TIOCMGET ioctl failed"); - -#ifdef USE_TERMIOX - int ret = get_flow(port->fd, data); - - if (ret == SP_ERR_FAIL && errno == EINVAL) - data->termiox_supported = 0; - else if (ret < 0) - RETURN_CODEVAL(ret); - else - data->termiox_supported = 1; -#else - data->termiox_supported = 0; -#endif - - for (i = 0; i < NUM_STD_BAUDRATES; i++) { - if (cfgetispeed(&data->term) == std_baudrates[i].index) { - config->baudrate = std_baudrates[i].value; - break; - } - } - - if (i == NUM_STD_BAUDRATES) { -#ifdef __APPLE__ - config->baudrate = (int)data->term.c_ispeed; -#elif defined(USE_TERMIOS_SPEED) - TRY(get_baudrate(port->fd, &config->baudrate)); -#else - config->baudrate = -1; -#endif - } - - switch (data->term.c_cflag & CSIZE) { - case CS8: - config->bits = 8; - break; - case CS7: - config->bits = 7; - break; - case CS6: - config->bits = 6; - break; - case CS5: - config->bits = 5; - break; - default: - config->bits = -1; - } - - if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR)) - config->parity = SP_PARITY_NONE; - else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR)) - config->parity = -1; -#ifdef CMSPAR - else if (data->term.c_cflag & CMSPAR) - config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_MARK : SP_PARITY_SPACE; -#endif - else - config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN; - - config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1; - - if (data->term.c_cflag & CRTSCTS) { - config->rts = SP_RTS_FLOW_CONTROL; - config->cts = SP_CTS_FLOW_CONTROL; - } else { - if (data->termiox_supported && data->rts_flow) - config->rts = SP_RTS_FLOW_CONTROL; - else - config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF; - - config->cts = (data->termiox_supported && data->cts_flow) ? - SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE; - } - - if (data->termiox_supported && data->dtr_flow) - config->dtr = SP_DTR_FLOW_CONTROL; - else - config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF; - - config->dsr = (data->termiox_supported && data->dsr_flow) ? - SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE; - - if (data->term.c_iflag & IXOFF) { - if (data->term.c_iflag & IXON) - config->xon_xoff = SP_XONXOFF_INOUT; - else - config->xon_xoff = SP_XONXOFF_IN; - } else { - if (data->term.c_iflag & IXON) - config->xon_xoff = SP_XONXOFF_OUT; - else - config->xon_xoff = SP_XONXOFF_DISABLED; - } -#endif - - RETURN_OK(); -} - -static enum sp_return set_config(struct sp_port *port, struct port_data *data, - const struct sp_port_config *config) -{ - unsigned int i; -#ifdef __APPLE__ - BAUD_TYPE baud_nonstd; - - baud_nonstd = B0; -#endif -#ifdef USE_TERMIOS_SPEED - int baud_nonstd = 0; -#endif - - TRACE("%p, %p, %p", port, data, config); - - DEBUG_FMT("Setting configuration for port %s", port->name); - -#ifdef _WIN32 - if (config->baudrate >= 0) { - for (i = 0; i < NUM_STD_BAUDRATES; i++) { - if (config->baudrate == std_baudrates[i].value) { - data->dcb.BaudRate = std_baudrates[i].index; - break; - } - } - - if (i == NUM_STD_BAUDRATES) - data->dcb.BaudRate = config->baudrate; - } - - if (config->bits >= 0) - data->dcb.ByteSize = config->bits; - - if (config->parity >= 0) { - switch (config->parity) { - case SP_PARITY_NONE: - data->dcb.Parity = NOPARITY; - break; - case SP_PARITY_ODD: - data->dcb.Parity = ODDPARITY; - break; - case SP_PARITY_EVEN: - data->dcb.Parity = EVENPARITY; - break; - case SP_PARITY_MARK: - data->dcb.Parity = MARKPARITY; - break; - case SP_PARITY_SPACE: - data->dcb.Parity = SPACEPARITY; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting"); - } - } - - if (config->stopbits >= 0) { - switch (config->stopbits) { - /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */ - case 1: - data->dcb.StopBits = ONESTOPBIT; - break; - case 2: - data->dcb.StopBits = TWOSTOPBITS; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting"); - } - } - - if (config->rts >= 0) { - switch (config->rts) { - case SP_RTS_OFF: - data->dcb.fRtsControl = RTS_CONTROL_DISABLE; - break; - case SP_RTS_ON: - data->dcb.fRtsControl = RTS_CONTROL_ENABLE; - break; - case SP_RTS_FLOW_CONTROL: - data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting"); - } - } - - if (config->cts >= 0) { - switch (config->cts) { - case SP_CTS_IGNORE: - data->dcb.fOutxCtsFlow = FALSE; - break; - case SP_CTS_FLOW_CONTROL: - data->dcb.fOutxCtsFlow = TRUE; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting"); - } - } - - if (config->dtr >= 0) { - switch (config->dtr) { - case SP_DTR_OFF: - data->dcb.fDtrControl = DTR_CONTROL_DISABLE; - break; - case SP_DTR_ON: - data->dcb.fDtrControl = DTR_CONTROL_ENABLE; - break; - case SP_DTR_FLOW_CONTROL: - data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting"); - } - } - - if (config->dsr >= 0) { - switch (config->dsr) { - case SP_DSR_IGNORE: - data->dcb.fOutxDsrFlow = FALSE; - break; - case SP_DSR_FLOW_CONTROL: - data->dcb.fOutxDsrFlow = TRUE; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting"); - } - } - - if (config->xon_xoff >= 0) { - switch (config->xon_xoff) { - case SP_XONXOFF_DISABLED: - data->dcb.fInX = FALSE; - data->dcb.fOutX = FALSE; - break; - case SP_XONXOFF_IN: - data->dcb.fInX = TRUE; - data->dcb.fOutX = FALSE; - break; - case SP_XONXOFF_OUT: - data->dcb.fInX = FALSE; - data->dcb.fOutX = TRUE; - break; - case SP_XONXOFF_INOUT: - data->dcb.fInX = TRUE; - data->dcb.fOutX = TRUE; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting"); - } - } - - if (!SetCommState(port->hdl, &data->dcb)) - RETURN_FAIL("SetCommState() failed"); - -#else /* !_WIN32 */ - - int controlbits; - - if (config->baudrate >= 0) { - for (i = 0; i < NUM_STD_BAUDRATES; i++) { - if (config->baudrate == std_baudrates[i].value) { - if (cfsetospeed(&data->term, std_baudrates[i].index) < 0) - RETURN_FAIL("cfsetospeed() failed"); - - if (cfsetispeed(&data->term, std_baudrates[i].index) < 0) - RETURN_FAIL("cfsetispeed() failed"); - break; - } - } - - /* Non-standard baud rate */ - if (i == NUM_STD_BAUDRATES) { -#ifdef __APPLE__ - /* Set "dummy" baud rate. */ - if (cfsetspeed(&data->term, B9600) < 0) - RETURN_FAIL("cfsetspeed() failed"); - baud_nonstd = config->baudrate; -#elif defined(USE_TERMIOS_SPEED) - baud_nonstd = 1; -#else - RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported"); -#endif - } - } - - if (config->bits >= 0) { - data->term.c_cflag &= ~CSIZE; - switch (config->bits) { - case 8: - data->term.c_cflag |= CS8; - break; - case 7: - data->term.c_cflag |= CS7; - break; - case 6: - data->term.c_cflag |= CS6; - break; - case 5: - data->term.c_cflag |= CS5; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting"); - } - } - - if (config->parity >= 0) { - data->term.c_iflag &= ~IGNPAR; - data->term.c_cflag &= ~(PARENB | PARODD); -#ifdef CMSPAR - data->term.c_cflag &= ~CMSPAR; -#endif - switch (config->parity) { - case SP_PARITY_NONE: - data->term.c_iflag |= IGNPAR; - break; - case SP_PARITY_EVEN: - data->term.c_cflag |= PARENB; - break; - case SP_PARITY_ODD: - data->term.c_cflag |= PARENB | PARODD; - break; -#ifdef CMSPAR - case SP_PARITY_MARK: - data->term.c_cflag |= PARENB | PARODD; - data->term.c_cflag |= CMSPAR; - break; - case SP_PARITY_SPACE: - data->term.c_cflag |= PARENB; - data->term.c_cflag |= CMSPAR; - break; -#else - case SP_PARITY_MARK: - case SP_PARITY_SPACE: - RETURN_ERROR(SP_ERR_SUPP, "Mark/space parity not supported"); -#endif - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting"); - } - } - - if (config->stopbits >= 0) { - data->term.c_cflag &= ~CSTOPB; - switch (config->stopbits) { - case 1: - data->term.c_cflag &= ~CSTOPB; - break; - case 2: - data->term.c_cflag |= CSTOPB; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting"); - } - } - - if (config->rts >= 0 || config->cts >= 0) { - if (data->termiox_supported) { - data->rts_flow = data->cts_flow = 0; - switch (config->rts) { - case SP_RTS_OFF: - case SP_RTS_ON: - controlbits = TIOCM_RTS; - if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0) - RETURN_FAIL("Setting RTS signal level failed"); - break; - case SP_RTS_FLOW_CONTROL: - data->rts_flow = 1; - break; - default: - break; - } - if (config->cts == SP_CTS_FLOW_CONTROL) - data->cts_flow = 1; - - if (data->rts_flow && data->cts_flow) - data->term.c_iflag |= CRTSCTS; - else - data->term.c_iflag &= ~CRTSCTS; - } else { - /* Asymmetric use of RTS/CTS not supported. */ - if (data->term.c_iflag & CRTSCTS) { - /* Flow control can only be disabled for both RTS & CTS together. */ - if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) { - if (config->cts != SP_CTS_IGNORE) - RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together"); - } - if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) { - if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL) - RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together"); - } - } else { - /* Flow control can only be enabled for both RTS & CTS together. */ - if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) || - ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL))) - RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together"); - } - - if (config->rts >= 0) { - if (config->rts == SP_RTS_FLOW_CONTROL) { - data->term.c_iflag |= CRTSCTS; - } else { - controlbits = TIOCM_RTS; - if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, - &controlbits) < 0) - RETURN_FAIL("Setting RTS signal level failed"); - } - } - } - } - - if (config->dtr >= 0 || config->dsr >= 0) { - if (data->termiox_supported) { - data->dtr_flow = data->dsr_flow = 0; - switch (config->dtr) { - case SP_DTR_OFF: - case SP_DTR_ON: - controlbits = TIOCM_DTR; - if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0) - RETURN_FAIL("Setting DTR signal level failed"); - break; - case SP_DTR_FLOW_CONTROL: - data->dtr_flow = 1; - break; - default: - break; - } - if (config->dsr == SP_DSR_FLOW_CONTROL) - data->dsr_flow = 1; - } else { - /* DTR/DSR flow control not supported. */ - if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL) - RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported"); - - if (config->dtr >= 0) { - controlbits = TIOCM_DTR; - if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, - &controlbits) < 0) - RETURN_FAIL("Setting DTR signal level failed"); - } - } - } - - if (config->xon_xoff >= 0) { - data->term.c_iflag &= ~(IXON | IXOFF | IXANY); - switch (config->xon_xoff) { - case SP_XONXOFF_DISABLED: - break; - case SP_XONXOFF_IN: - data->term.c_iflag |= IXOFF; - break; - case SP_XONXOFF_OUT: - data->term.c_iflag |= IXON | IXANY; - break; - case SP_XONXOFF_INOUT: - data->term.c_iflag |= IXON | IXOFF | IXANY; - break; - default: - RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting"); - } - } - - if (tcsetattr(port->fd, TCSANOW, &data->term) < 0) - RETURN_FAIL("tcsetattr() failed"); - -#ifdef __APPLE__ - if (baud_nonstd != B0) { - if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1) - RETURN_FAIL("IOSSIOSPEED ioctl failed"); - /* Set baud rates in data->term to correct, but incompatible - * with tcsetattr() value, same as delivered by tcgetattr(). */ - if (cfsetspeed(&data->term, baud_nonstd) < 0) - RETURN_FAIL("cfsetspeed() failed"); - } -#elif defined(__linux__) -#ifdef USE_TERMIOS_SPEED - if (baud_nonstd) - TRY(set_baudrate(port->fd, config->baudrate)); -#endif -#ifdef USE_TERMIOX - if (data->termiox_supported) - TRY(set_flow(port->fd, data)); -#endif -#endif - -#endif /* !_WIN32 */ - - RETURN_OK(); -} - -SP_API enum sp_return sp_new_config(struct sp_port_config **config_ptr) -{ - struct sp_port_config *config; - - TRACE("%p", config_ptr); - - if (!config_ptr) - RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); - - *config_ptr = NULL; - - if (!(config = malloc(sizeof(struct sp_port_config)))) - RETURN_ERROR(SP_ERR_MEM, "config malloc failed"); - - config->baudrate = -1; - config->bits = -1; - config->parity = -1; - config->stopbits = -1; - config->rts = -1; - config->cts = -1; - config->dtr = -1; - config->dsr = -1; - - *config_ptr = config; - - RETURN_OK(); -} - -SP_API void sp_free_config(struct sp_port_config *config) -{ - TRACE("%p", config); - - if (!config) - DEBUG("Null config"); - else - free(config); - - RETURN(); -} - -SP_API enum sp_return sp_get_config(struct sp_port *port, - struct sp_port_config *config) -{ - struct port_data data; - - TRACE("%p, %p", port, config); - - CHECK_OPEN_PORT(); - - if (!config) - RETURN_ERROR(SP_ERR_ARG, "Null config"); - - TRY(get_config(port, &data, config)); - - RETURN_OK(); -} - -SP_API enum sp_return sp_set_config(struct sp_port *port, - const struct sp_port_config *config) -{ - struct port_data data; - struct sp_port_config prev_config; - - TRACE("%p, %p", port, config); - - CHECK_OPEN_PORT(); - - if (!config) - RETURN_ERROR(SP_ERR_ARG, "Null config"); - - TRY(get_config(port, &data, &prev_config)); - TRY(set_config(port, &data, config)); - - RETURN_OK(); -} - -#define CREATE_ACCESSORS(x, type) \ -SP_API enum sp_return sp_set_##x(struct sp_port *port, type x) { \ - struct port_data data; \ - struct sp_port_config config; \ - TRACE("%p, %d", port, x); \ - CHECK_OPEN_PORT(); \ - TRY(get_config(port, &data, &config)); \ - config.x = x; \ - TRY(set_config(port, &data, &config)); \ - RETURN_OK(); \ -} \ -SP_API enum sp_return sp_get_config_##x(const struct sp_port_config *config, \ - type *x) { \ - TRACE("%p, %p", config, x); \ - if (!config) \ - RETURN_ERROR(SP_ERR_ARG, "Null config"); \ - *x = config->x; \ - RETURN_OK(); \ -} \ -SP_API enum sp_return sp_set_config_##x(struct sp_port_config *config, \ - type x) { \ - TRACE("%p, %d", config, x); \ - if (!config) \ - RETURN_ERROR(SP_ERR_ARG, "Null config"); \ - config->x = x; \ - RETURN_OK(); \ -} - -CREATE_ACCESSORS(baudrate, int) -CREATE_ACCESSORS(bits, int) -CREATE_ACCESSORS(parity, enum sp_parity) -CREATE_ACCESSORS(stopbits, int) -CREATE_ACCESSORS(rts, enum sp_rts) -CREATE_ACCESSORS(cts, enum sp_cts) -CREATE_ACCESSORS(dtr, enum sp_dtr) -CREATE_ACCESSORS(dsr, enum sp_dsr) -CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff) - -SP_API enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, - enum sp_flowcontrol flowcontrol) -{ - if (!config) - RETURN_ERROR(SP_ERR_ARG, "Null configuration"); - - if (flowcontrol > SP_FLOWCONTROL_DTRDSR) - RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting"); - - if (flowcontrol == SP_FLOWCONTROL_XONXOFF) - config->xon_xoff = SP_XONXOFF_INOUT; - else - config->xon_xoff = SP_XONXOFF_DISABLED; - - if (flowcontrol == SP_FLOWCONTROL_RTSCTS) { - config->rts = SP_RTS_FLOW_CONTROL; - config->cts = SP_CTS_FLOW_CONTROL; - } else { - if (config->rts == SP_RTS_FLOW_CONTROL) - config->rts = SP_RTS_ON; - config->cts = SP_CTS_IGNORE; - } - - if (flowcontrol == SP_FLOWCONTROL_DTRDSR) { - config->dtr = SP_DTR_FLOW_CONTROL; - config->dsr = SP_DSR_FLOW_CONTROL; - } else { - if (config->dtr == SP_DTR_FLOW_CONTROL) - config->dtr = SP_DTR_ON; - config->dsr = SP_DSR_IGNORE; - } - - RETURN_OK(); -} - -SP_API enum sp_return sp_set_flowcontrol(struct sp_port *port, - enum sp_flowcontrol flowcontrol) -{ - struct port_data data; - struct sp_port_config config; - - TRACE("%p, %d", port, flowcontrol); - - CHECK_OPEN_PORT(); - - TRY(get_config(port, &data, &config)); - - TRY(sp_set_config_flowcontrol(&config, flowcontrol)); - - TRY(set_config(port, &data, &config)); - - RETURN_OK(); -} - -SP_API enum sp_return sp_get_signals(struct sp_port *port, - enum sp_signal *signals) -{ - TRACE("%p, %p", port, signals); - - CHECK_OPEN_PORT(); - - if (!signals) - RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); - - DEBUG_FMT("Getting control signals for port %s", port->name); - - *signals = 0; -#ifdef _WIN32 - DWORD bits; - if (GetCommModemStatus(port->hdl, &bits) == 0) - RETURN_FAIL("GetCommModemStatus() failed"); - if (bits & MS_CTS_ON) - *signals |= SP_SIG_CTS; - if (bits & MS_DSR_ON) - *signals |= SP_SIG_DSR; - if (bits & MS_RLSD_ON) - *signals |= SP_SIG_DCD; - if (bits & MS_RING_ON) - *signals |= SP_SIG_RI; -#else - int bits; - if (ioctl(port->fd, TIOCMGET, &bits) < 0) - RETURN_FAIL("TIOCMGET ioctl failed"); - if (bits & TIOCM_CTS) - *signals |= SP_SIG_CTS; - if (bits & TIOCM_DSR) - *signals |= SP_SIG_DSR; - if (bits & TIOCM_CAR) - *signals |= SP_SIG_DCD; - if (bits & TIOCM_RNG) - *signals |= SP_SIG_RI; -#endif - RETURN_OK(); -} - -SP_API enum sp_return sp_start_break(struct sp_port *port) -{ - TRACE("%p", port); - - CHECK_OPEN_PORT(); -#ifdef _WIN32 - if (SetCommBreak(port->hdl) == 0) - RETURN_FAIL("SetCommBreak() failed"); -#else - if (ioctl(port->fd, TIOCSBRK, 1) < 0) - RETURN_FAIL("TIOCSBRK ioctl failed"); -#endif - - RETURN_OK(); -} - -SP_API enum sp_return sp_end_break(struct sp_port *port) -{ - TRACE("%p", port); - - CHECK_OPEN_PORT(); -#ifdef _WIN32 - if (ClearCommBreak(port->hdl) == 0) - RETURN_FAIL("ClearCommBreak() failed"); -#else - if (ioctl(port->fd, TIOCCBRK, 1) < 0) - RETURN_FAIL("TIOCCBRK ioctl failed"); -#endif - - RETURN_OK(); -} - -SP_API int sp_last_error_code(void) -{ - TRACE_VOID(); -#ifdef _WIN32 - RETURN_INT(GetLastError()); -#else - RETURN_INT(errno); -#endif -} - -SP_API char *sp_last_error_message(void) -{ - TRACE_VOID(); - -#ifdef _WIN32 - LPVOID message; - DWORD error = GetLastError(); - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &message, - 0, NULL ); - - RETURN_STRING(message); -#else - RETURN_STRING(strerror(errno)); -#endif -} - -SP_API void sp_free_error_message(char *message) -{ - TRACE("%s", message); - -#ifdef _WIN32 - LocalFree(message); -#else - (void)message; -#endif - - RETURN(); -} - -SP_API void sp_set_debug_handler(void (*handler)(const char *format, ...)) -{ - TRACE("%p", handler); - - sp_debug_handler = handler; - - RETURN(); -} - -SP_API void sp_default_debug_handler(const char *format, ...) -{ - va_list args; - va_start(args, format); - if (getenv("LIBSERIALPORT_DEBUG")) { - fputs("sp: ", stderr); - vfprintf(stderr, format, args); - } - va_end(args); -} - -SP_API int sp_get_major_package_version(void) -{ - return SP_PACKAGE_VERSION_MAJOR; -} - -SP_API int sp_get_minor_package_version(void) -{ - return SP_PACKAGE_VERSION_MINOR; -} - -SP_API int sp_get_micro_package_version(void) -{ - return SP_PACKAGE_VERSION_MICRO; -} - -SP_API const char *sp_get_package_version_string(void) -{ - return SP_PACKAGE_VERSION_STRING; -} - -SP_API int sp_get_current_lib_version(void) -{ - return SP_LIB_VERSION_CURRENT; -} - -SP_API int sp_get_revision_lib_version(void) -{ - return SP_LIB_VERSION_REVISION; -} - -SP_API int sp_get_age_lib_version(void) -{ - return SP_LIB_VERSION_AGE; -} - -SP_API const char *sp_get_lib_version_string(void) -{ - return SP_LIB_VERSION_STRING; -} - -/** @} */ diff --git a/vendor/github.com/facchinm/go-serial-native/windows.c b/vendor/github.com/facchinm/go-serial-native/windows.c deleted file mode 100644 index b6b4b1037..000000000 --- a/vendor/github.com/facchinm/go-serial-native/windows.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * This file is part of the libserialport project. - * - * Copyright (C) 2013-2014 Martin Ling - * Copyright (C) 2014 Aurelien Jacobs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifdef _WIN32 - -#include "libserialport.h" -#include "libserialport_internal.h" - -char *my_strdup(const char *s) { - char *p = malloc(strlen(s) + 1); - if(p) { strcpy(p, s); } - return p; -} - -/* this goes in whatever header defines my_strdup */ -char *my_strdup(const char *s); -#define strdup(x) my_strdup(x) - -/* USB path is a string of at most 8 decimal numbers < 128 separated by dots */ -#define MAX_USB_PATH (8*3 + 7*1 + 1) - -static void enumerate_hub(struct sp_port *port, char *hub_name, - char *parent_path, DEVINST dev_inst); - -static char *wc_to_utf8(PWCHAR wc_buffer, ULONG size) -{ - WCHAR wc_str[size/sizeof(WCHAR)+1]; - char *utf8_str; - - /* zero terminate the wide char string */ - memcpy(wc_str, wc_buffer, size); - wc_str[sizeof(wc_str)-1] = 0; - - /* compute the size of the utf8 converted string */ - if (!(size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1, - NULL, 0, NULL, NULL))) - return NULL; - - /* allocate utf8 output buffer */ - if (!(utf8_str = malloc(size))) - return NULL; - - /* actually converted to utf8 */ - if (!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1, - utf8_str, size, NULL, NULL)) { - free(utf8_str); - return NULL; - } - - return utf8_str; -} - -static char *get_root_hub_name(HANDLE host_controller) -{ - USB_ROOT_HUB_NAME root_hub_name; - PUSB_ROOT_HUB_NAME root_hub_name_wc; - char *root_hub_name_utf8; - ULONG size = 0; - - /* compute the size of the root hub name string */ - if (!DeviceIoControl(host_controller, IOCTL_USB_GET_ROOT_HUB_NAME, 0, 0, - &root_hub_name, sizeof(root_hub_name), &size, NULL)) - return NULL; - - /* allocate wide char root hub name string */ - size = root_hub_name.ActualLength; - if (!(root_hub_name_wc = malloc(size))) - return NULL; - - /* actually get the root hub name string */ - if (!DeviceIoControl(host_controller, IOCTL_USB_GET_ROOT_HUB_NAME, - NULL, 0, root_hub_name_wc, size, &size, NULL)) { - free(root_hub_name_wc); - return NULL; - } - - /* convert the root hub name string to utf8 */ - root_hub_name_utf8 = wc_to_utf8(root_hub_name_wc->RootHubName, size); - free(root_hub_name_wc); - return root_hub_name_utf8; -} - -static char *get_external_hub_name(HANDLE hub, ULONG connection_index) -{ - USB_NODE_CONNECTION_NAME ext_hub_name; - PUSB_NODE_CONNECTION_NAME ext_hub_name_wc; - char *ext_hub_name_utf8; - ULONG size; - - /* compute the size of the external hub name string */ - ext_hub_name.ConnectionIndex = connection_index; - if (!DeviceIoControl(hub, IOCTL_USB_GET_NODE_CONNECTION_NAME, - &ext_hub_name, sizeof(ext_hub_name), - &ext_hub_name, sizeof(ext_hub_name), &size, NULL)) - return NULL; - - /* allocate wide char external hub name string */ - size = ext_hub_name.ActualLength; - if (size <= sizeof(ext_hub_name) - || !(ext_hub_name_wc = malloc(size))) - return NULL; - - /* get the name of the external hub attached to the specified port */ - ext_hub_name_wc->ConnectionIndex = connection_index; - if (!DeviceIoControl(hub, IOCTL_USB_GET_NODE_CONNECTION_NAME, - ext_hub_name_wc, size, - ext_hub_name_wc, size, &size, NULL)) { - free(ext_hub_name_wc); - return NULL; - } - - /* convert the external hub name string to utf8 */ - ext_hub_name_utf8 = wc_to_utf8(ext_hub_name_wc->NodeName, size); - free(ext_hub_name_wc); - return ext_hub_name_utf8; -} - -static char *get_string_descriptor(HANDLE hub_device, ULONG connection_index, - UCHAR descriptor_index) -{ - char desc_req_buf[sizeof(USB_DESCRIPTOR_REQUEST) + - MAXIMUM_USB_STRING_LENGTH] = { 0 }; - PUSB_DESCRIPTOR_REQUEST desc_req = (void *) desc_req_buf; - PUSB_STRING_DESCRIPTOR desc = (void *) (desc_req + 1); - ULONG size = sizeof(desc_req_buf); - - desc_req->ConnectionIndex = connection_index; - desc_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) - | descriptor_index; - desc_req->SetupPacket.wIndex = 0; - desc_req->SetupPacket.wLength = size - sizeof(*desc_req); - - if (!DeviceIoControl(hub_device, - IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, - desc_req, size, desc_req, size, &size, NULL) - || size < 2 - || desc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE - || desc->bLength != size - sizeof(*desc_req) - || desc->bLength % 2) - return NULL; - - return wc_to_utf8(desc->bString, desc->bLength); -} - -static void enumerate_hub_ports(struct sp_port *port, HANDLE hub_device, - ULONG nb_ports, char *parent_path, DEVINST dev_inst) -{ - char path[MAX_USB_PATH]; - ULONG index = 0; - - for (index = 1; index <= nb_ports; index++) { - PUSB_NODE_CONNECTION_INFORMATION_EX connection_info_ex; - ULONG size = sizeof(*connection_info_ex) + 30*sizeof(USB_PIPE_INFO); - - if (!(connection_info_ex = malloc(size))) - break; - - connection_info_ex->ConnectionIndex = index; - if (!DeviceIoControl(hub_device, - IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, - connection_info_ex, size, - connection_info_ex, size, &size, NULL)) { - /* try to get CONNECTION_INFORMATION if CONNECTION_INFORMATION_EX - did not work */ - PUSB_NODE_CONNECTION_INFORMATION connection_info; - - size = sizeof(*connection_info) + 30*sizeof(USB_PIPE_INFO); - if (!(connection_info = malloc(size))) { - free(connection_info_ex); - continue; - } - connection_info->ConnectionIndex = index; - if (!DeviceIoControl(hub_device, - IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, - connection_info, size, - connection_info, size, &size, NULL)) { - free(connection_info); - free(connection_info_ex); - continue; - } - - connection_info_ex->ConnectionIndex = connection_info->ConnectionIndex; - connection_info_ex->DeviceDescriptor = connection_info->DeviceDescriptor; - connection_info_ex->DeviceIsHub = connection_info->DeviceIsHub; - connection_info_ex->DeviceAddress = connection_info->DeviceAddress; - free(connection_info); - } - - if (connection_info_ex->DeviceIsHub) { - /* recursively enumerate external hub */ - PCHAR ext_hub_name; - if ((ext_hub_name = get_external_hub_name(hub_device, index))) { - snprintf(path, sizeof(path), "%s%ld.", - parent_path, connection_info_ex->ConnectionIndex); - enumerate_hub(port, ext_hub_name, path, dev_inst); - } - free(connection_info_ex); - } else { - snprintf(path, sizeof(path), "%s%ld", - parent_path, connection_info_ex->ConnectionIndex); - - /* check if this device is the one we search for */ - if (strcmp(path, port->usb_path)) { - free(connection_info_ex); - continue; - } - - /* finally grab detailed informations regarding the device */ - port->usb_address = connection_info_ex->DeviceAddress + 1; - port->usb_vid = connection_info_ex->DeviceDescriptor.idVendor; - port->usb_pid = connection_info_ex->DeviceDescriptor.idProduct; - - if (connection_info_ex->DeviceDescriptor.iManufacturer) - port->usb_manufacturer = get_string_descriptor(hub_device,index, - connection_info_ex->DeviceDescriptor.iManufacturer); - if (connection_info_ex->DeviceDescriptor.iProduct) - port->usb_product = get_string_descriptor(hub_device, index, - connection_info_ex->DeviceDescriptor.iProduct); - if (connection_info_ex->DeviceDescriptor.iSerialNumber) { - port->usb_serial = get_string_descriptor(hub_device, index, - connection_info_ex->DeviceDescriptor.iSerialNumber); - if (port->usb_serial == NULL) { - //composite device, get the parent's serial number - char device_id[MAX_DEVICE_ID_LEN]; - if (CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS) { - if (CM_Get_Device_IDA(dev_inst, device_id, sizeof(device_id), 0) == CR_SUCCESS) - port->usb_serial = strdup(strrchr(device_id, '\\')+1); - } - } - } - - free(connection_info_ex); - break; - } - } -} - -static void enumerate_hub(struct sp_port *port, char *hub_name, - char *parent_path, DEVINST dev_inst) -{ - USB_NODE_INFORMATION hub_info; - HANDLE hub_device; - ULONG size = sizeof(hub_info); - char *device_name; - - /* open the hub with its full name */ - if (!(device_name = malloc(strlen("\\\\.\\") + strlen(hub_name) + 1))) - return; - strcpy(device_name, "\\\\.\\"); - strcat(device_name, hub_name); - hub_device = CreateFile(device_name, GENERIC_WRITE, FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, NULL); - free(device_name); - if (hub_device == INVALID_HANDLE_VALUE) - return; - - /* get the number of ports of the hub */ - if (DeviceIoControl(hub_device, IOCTL_USB_GET_NODE_INFORMATION, - &hub_info, size, &hub_info, size, &size, NULL)) - /* enumerate the ports of the hub */ - enumerate_hub_ports(port, hub_device, - hub_info.u.HubInformation.HubDescriptor.bNumberOfPorts, parent_path, dev_inst); - - CloseHandle(hub_device); -} - -static void enumerate_host_controller(struct sp_port *port, - HANDLE host_controller_device, - DEVINST dev_inst) -{ - char *root_hub_name; - - if (port->composite) { - //remove last part of the path - char * pch; - pch=strrchr(port->usb_path,'.'); - port->usb_path[pch-port->usb_path] = '\0'; - } - - if ((root_hub_name = get_root_hub_name(host_controller_device))) { - enumerate_hub(port, root_hub_name, "", dev_inst); - free(root_hub_name); - } -} - -static void get_usb_details(struct sp_port *port, DEVINST dev_inst_match) -{ - HDEVINFO device_info; - SP_DEVINFO_DATA device_info_data; - ULONG i, size = 0; - - device_info = SetupDiGetClassDevs(&GUID_CLASS_USB_HOST_CONTROLLER,NULL,NULL, - DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - device_info_data.cbSize = sizeof(device_info_data); - - for (i=0; SetupDiEnumDeviceInfo(device_info, i, &device_info_data); i++) { - SP_DEVICE_INTERFACE_DATA device_interface_data; - PSP_DEVICE_INTERFACE_DETAIL_DATA device_detail_data; - DEVINST dev_inst = dev_inst_match; - HANDLE host_controller_device; - - device_interface_data.cbSize = sizeof(device_interface_data); - if (!SetupDiEnumDeviceInterfaces(device_info, 0, - &GUID_CLASS_USB_HOST_CONTROLLER, - i, &device_interface_data)) - continue; - - if (!SetupDiGetDeviceInterfaceDetail(device_info,&device_interface_data, - NULL, 0, &size, NULL) - && GetLastError() != ERROR_INSUFFICIENT_BUFFER) - continue; - - if (!(device_detail_data = malloc(size))) - continue; - device_detail_data->cbSize = sizeof(*device_detail_data); - if (!SetupDiGetDeviceInterfaceDetail(device_info,&device_interface_data, - device_detail_data, size, &size, - NULL)) { - free(device_detail_data); - continue; - } - - while (CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS - && dev_inst != device_info_data.DevInst) { } - - if (dev_inst != device_info_data.DevInst) { - free(device_detail_data); - continue; - } - - port->usb_bus = i + 1; - - host_controller_device = CreateFile(device_detail_data->DevicePath, - GENERIC_WRITE, FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, NULL); - if (host_controller_device != INVALID_HANDLE_VALUE) { - enumerate_host_controller(port, host_controller_device, dev_inst_match); - CloseHandle(host_controller_device); - } - free(device_detail_data); - } - - SetupDiDestroyDeviceInfoList(device_info); - return; -} - -SP_PRIV enum sp_return get_port_details(struct sp_port *port) -{ - /* Description limited to 127 char, - anything longer would not be user friendly anyway */ - char description[128]; - SP_DEVINFO_DATA device_info_data = { .cbSize = sizeof(device_info_data) }; - HDEVINFO device_info; - int i; - - device_info = SetupDiGetClassDevs(NULL, 0, 0, - DIGCF_PRESENT | DIGCF_ALLCLASSES); - if (device_info == INVALID_HANDLE_VALUE) - RETURN_FAIL("SetupDiGetClassDevs() failed"); - - for (i=0; SetupDiEnumDeviceInfo(device_info, i, &device_info_data); i++) { - HKEY device_key; - DEVINST dev_inst; - char value[8], class[16]; - DWORD size, type; - CONFIGRET cr; - - port->composite = FALSE; - - /* check if this is the device we are looking for */ - device_key = SetupDiOpenDevRegKey(device_info, &device_info_data, - DICS_FLAG_GLOBAL, 0, - DIREG_DEV, KEY_QUERY_VALUE); - if (device_key == INVALID_HANDLE_VALUE) - continue; - size = sizeof(value); - if (RegQueryValueExA(device_key, "PortName", NULL, &type, (LPBYTE)value, - &size) != ERROR_SUCCESS || type != REG_SZ) { - RegCloseKey(device_key); - continue; - } - RegCloseKey(device_key); - value[sizeof(value)-1] = 0; - if (strcmp(value, port->name)) - continue; - - /* check port transport type */ - dev_inst = device_info_data.DevInst; - size = sizeof(class); - cr = CR_FAILURE; - while (CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS && - (cr = CM_Get_DevNode_Registry_PropertyA(dev_inst, - CM_DRP_CLASS, 0, class, &size, 0)) != CR_SUCCESS) { } - if (cr == CR_SUCCESS) { - if (!strcmp(class, "USB")) - port->transport = SP_TRANSPORT_USB; - } - - /* get port description (friendly name) */ - dev_inst = device_info_data.DevInst; - size = sizeof(description); - while ((cr = CM_Get_DevNode_Registry_PropertyA(dev_inst, - CM_DRP_FRIENDLYNAME, 0, description, &size, 0)) != CR_SUCCESS - && CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS) { } - if (cr == CR_SUCCESS) - port->description = strdup(description); - - /* get more informations for USB connected ports */ - if (port->transport == SP_TRANSPORT_USB) { - char usb_path[MAX_USB_PATH] = "", tmp[MAX_USB_PATH]; - char device_id[MAX_DEVICE_ID_LEN]; - - /* recurse over parents to build the USB device path */ - dev_inst = device_info_data.DevInst; - do { - /* verify that this layer of the tree is USB related */ - if (CM_Get_Device_IDA(dev_inst, device_id, - sizeof(device_id), 0) != CR_SUCCESS - || strncmp(device_id, "USB\\", 4)) - continue; - - /* discard one layer for composite devices */ - char compat_ids[512]; - char *p = compat_ids; - size = sizeof(compat_ids); - - if (CM_Get_DevNode_Registry_PropertyA(dev_inst, - CM_DRP_COMPATIBLEIDS, 0, - &compat_ids, - &size, 0) == CR_SUCCESS) { - while (*p) { - if (!strncmp(p, "USB\\COMPOSITE", 13)) { - port->composite = TRUE; - break; - } - p += strlen(p) + 1; - } - } - - /* stop the recursion when reaching the USB root */ - if (!strncmp(device_id, "USB\\ROOT", 8)) - break; - - /* prepend the address of current USB layer to the USB path */ - DWORD address; - size = sizeof(address); - if (CM_Get_DevNode_Registry_PropertyA(dev_inst, CM_DRP_ADDRESS, - 0, &address, &size, 0) == CR_SUCCESS) { - strcpy(tmp, usb_path); - snprintf(usb_path, sizeof(usb_path), "%d%s%s", - (int)address, *tmp ? "." : "", tmp); - } - } while (CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS); - - port->usb_path = strdup(usb_path); - - /* retrieve USB device details from the device descriptor */ - get_usb_details(port, device_info_data.DevInst); - } - break; - } - - SetupDiDestroyDeviceInfoList(device_info); - - RETURN_OK(); -} - -SP_PRIV enum sp_return list_ports(struct sp_port ***list) -{ - HKEY key; - TCHAR *value, *data; - DWORD max_value_len, max_data_size, max_data_len; - DWORD value_len, data_size, data_len; - DWORD type, index = 0; - char *name; - int name_len; - int ret = SP_OK; - - DEBUG("Opening registry key"); - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"), - 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) { - SET_FAIL(ret, "RegOpenKeyEx() failed"); - goto out_done; - } - DEBUG("Querying registry key value and data sizes"); - if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) { - SET_FAIL(ret, "RegQueryInfoKey() failed"); - goto out_close; - } - max_data_len = max_data_size / sizeof(TCHAR); - if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR)))) { - SET_ERROR(ret, SP_ERR_MEM, "registry value malloc failed"); - goto out_close; - } - if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR)))) { - SET_ERROR(ret, SP_ERR_MEM, "registry data malloc failed"); - goto out_free_value; - } - DEBUG("Iterating over values"); - while ( - value_len = max_value_len + 1, - data_size = max_data_size, - RegEnumValue(key, index, value, &value_len, - NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS) - { - if (type == REG_SZ) { - data_len = data_size / sizeof(TCHAR); - data[data_len] = '\0'; -#ifdef UNICODE - name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL); -#else - name_len = data_len + 1; -#endif - if (!(name = malloc(name_len))) { - SET_ERROR(ret, SP_ERR_MEM, "registry port name malloc failed"); - goto out; - } -#ifdef UNICODE - WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL); -#else - strcpy(name, data); -#endif - DEBUG_FMT("Found port %s", name); - if (!(*list = list_append(*list, name))) { - SET_ERROR(ret, SP_ERR_MEM, "list append failed"); - free(name); - goto out; - } - free(name); - } - index++; - } -out: - free(data); -out_free_value: - free(value); -out_close: - RegCloseKey(key); -out_done: - - return ret; -} - -#endif diff --git a/vendor/github.com/facchinm/go-serial/LICENSE b/vendor/github.com/facchinm/go-serial/LICENSE deleted file mode 100644 index 565e93b27..000000000 --- a/vendor/github.com/facchinm/go-serial/LICENSE +++ /dev/null @@ -1,33 +0,0 @@ - -Copyright (c) 2014, Cristian Maglie. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - diff --git a/vendor/github.com/facchinm/go-serial/doc.go b/vendor/github.com/facchinm/go-serial/doc.go deleted file mode 100644 index b80999d82..000000000 --- a/vendor/github.com/facchinm/go-serial/doc.go +++ /dev/null @@ -1,85 +0,0 @@ -// -// Copyright 2014 Cristian Maglie. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// - -/* -This is a cross-platform serial library for go. - -The canonical import for this library is go.bug.st/serial so the import line -is the following: - - import "go.bug.st/serial" - -It is possibile to get the list of available serial ports with the -GetPortsList function: - - ports, err := serial.GetPortsList() - if err != nil { - log.Fatal(err) - } - if len(ports) == 0 { - log.Fatal("No serial ports found!") - } - for _, port := range ports { - fmt.Printf("Found port: %v\n", port) - } - -The serial port can be opened with the OpenPort function: - - mode := &serial.Mode{ - BaudRate: 115200, - } - port, err := serial.OpenPort("/dev/ttyUSB0", mode) - if err != nil { - log.Fatal(err) - } - -The OpenPort command needs a "mode" parameter that specifies the configuration -options for the serial port. If not specified the default options are 9600_N81, -in the example above only the speed is changed so the port is opened using 115200_N81. -The following snippets shows how to declare a configuration for 57600_E71: - - mode := &serial.Mode{ - BaudRate: 57600, - Parity: serial.PARITY_EVEN, - DataBits: 7, - StopBits: serial.STOPBITS_ONE, - } - -The configuration can be changed at any time with the SetMode function: - - err := port.SetMode(mode) - if err != nil { - log.Fatal(err) - } - -The port object implements the io.ReadWriteCloser interface, so we can use -the usual Read, Write and Close functions to send and receive data from the -serial port: - - n, err := port.Write([]byte("10,20,30\n\r")) - if err != nil { - log.Fatal(err) - } - fmt.Printf("Sent %v bytes\n", n) - - buff := make([]byte, 100) - for { - n, err := port.Read(buff) - if err != nil { - log.Fatal(err) - break - } - if n == 0 { - fmt.Println("\nEOF") - break - } - fmt.Printf("%v", string(buff[:n])) - } - -This library doesn't make use of cgo and "C" package, so it's a pure go library -that can be easily cross compiled. -*/ -package serial diff --git a/vendor/github.com/facchinm/go-serial/serial.go b/vendor/github.com/facchinm/go-serial/serial.go deleted file mode 100644 index a5cf40b3f..000000000 --- a/vendor/github.com/facchinm/go-serial/serial.go +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright 2014 Cristian Maglie. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// - -package serial - -// This structure describes a serial port configuration. -type Mode struct { - BaudRate int // The serial port bitrate (aka Baudrate) - DataBits int // Size of the character (must be 5, 6, 7 or 8) - Parity Parity // Parity (see Parity type for more info) - StopBits StopBits // Stop bits (see StopBits type for more info) - Vmin uint8 // Vmin (minimum characters to receive before returning) - Vtimeout uint8 // VTimeout (minimum time to wait before returning) -} - -type Parity int - -const ( - PARITY_NONE Parity = iota // No parity (default) - PARITY_ODD // Odd parity - PARITY_EVEN // Even parity - PARITY_MARK // Mark parity (always 1) - PARITY_SPACE // Space parity (always 0) -) - -type StopBits int - -const ( - STOPBITS_ONE StopBits = iota // 1 Stop bit - STOPBITS_ONEPOINTFIVE // 1.5 Stop bits - STOPBITS_TWO // 2 Stop bits -) - -// Platform independent error type for serial ports -type SerialPortError struct { - err string - code int -} - -const ( - ERROR_PORT_BUSY = iota - ERROR_PORT_NOT_FOUND - ERROR_INVALID_SERIAL_PORT - ERROR_PERMISSION_DENIED - ERROR_INVALID_PORT_SPEED - ERROR_INVALID_PORT_DATA_BITS - ERROR_ENUMERATING_PORTS - ERROR_OTHER -) - -func (e SerialPortError) Error() string { - switch e.code { - case ERROR_PORT_BUSY: - return "Serial port busy" - case ERROR_PORT_NOT_FOUND: - return "Serial port not found" - case ERROR_INVALID_SERIAL_PORT: - return "Invalid serial port" - case ERROR_PERMISSION_DENIED: - return "Permission denied" - case ERROR_INVALID_PORT_SPEED: - return "Invalid port speed" - case ERROR_INVALID_PORT_DATA_BITS: - return "Invalid port data bits" - case ERROR_ENUMERATING_PORTS: - return "Could not enumerate serial ports" - } - return e.err -} - -func (e SerialPortError) Code() int { - return e.code -} - -// vi:ts=2 diff --git a/vendor/github.com/facchinm/go-serial/serial_darwin.go b/vendor/github.com/facchinm/go-serial/serial_darwin.go deleted file mode 100644 index ce26174d8..000000000 --- a/vendor/github.com/facchinm/go-serial/serial_darwin.go +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2014 Cristian Maglie. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// - -package serial - -import "syscall" - -const devFolder = "/dev" -const regexFilter = "^(cu|tty)\\..*" - -// termios manipulation functions - -var baudrateMap = map[int]int{ - 0: syscall.B9600, // Default to 9600 - 50: syscall.B50, - 75: syscall.B75, - 110: syscall.B110, - 134: syscall.B134, - 150: syscall.B150, - 200: syscall.B200, - 300: syscall.B300, - 600: syscall.B600, - 1200: syscall.B1200, - 1800: syscall.B1800, - 2400: syscall.B2400, - 4800: syscall.B4800, - 9600: syscall.B9600, - 19200: syscall.B19200, - 38400: syscall.B38400, - 57600: syscall.B57600, - 115200: syscall.B115200, - 230400: syscall.B230400, -} - -var databitsMap = map[int]int{ - 0: syscall.CS8, // Default to 8 bits - 5: syscall.CS5, - 6: syscall.CS6, - 7: syscall.CS7, - 8: syscall.CS8, -} - -const tc_CMSPAR int = 0 // may be CMSPAR or PAREXT -const tc_IUCLC int = 0 - -// syscall wrappers - -//sys ioctl(fd int, req uint64, data uintptr) (err error) - -const ioctl_tcgetattr = syscall.TIOCGETA -const ioctl_tcsetattr = syscall.TIOCSETA diff --git a/vendor/github.com/facchinm/go-serial/serial_darwin_386.go b/vendor/github.com/facchinm/go-serial/serial_darwin_386.go deleted file mode 100644 index ce70d4ef3..000000000 --- a/vendor/github.com/facchinm/go-serial/serial_darwin_386.go +++ /dev/null @@ -1,11 +0,0 @@ -// -// Copyright 2014 Cristian Maglie. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// - -package serial - -func termiosMask(data int) uint32 { - return uint32(data) -} diff --git a/vendor/github.com/facchinm/go-serial/serial_darwin_amd64.go b/vendor/github.com/facchinm/go-serial/serial_darwin_amd64.go deleted file mode 100644 index 0529e03a8..000000000 --- a/vendor/github.com/facchinm/go-serial/serial_darwin_amd64.go +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright 2014 Cristian Maglie. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// - -package serial - -// termios manipulation functions - -func termiosMask(data int) uint64 { - return uint64(data) -} diff --git a/vendor/github.com/facchinm/go-serial/serial_linux.go b/vendor/github.com/facchinm/go-serial/serial_linux.go deleted file mode 100644 index 4149fb885..000000000 --- a/vendor/github.com/facchinm/go-serial/serial_linux.go +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copyright 2014 Cristian Maglie. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// - -package serial - -import "syscall" - -const devFolder = "/dev" -const regexFilter = "(ttyS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO)[0-9]{1,3}" - -// termios manipulation functions - -var baudrateMap = map[int]int{ - 0: syscall.B9600, // Default to 9600 - 50: syscall.B50, - 75: syscall.B75, - 110: syscall.B110, - 134: syscall.B134, - 150: syscall.B150, - 200: syscall.B200, - 300: syscall.B300, - 600: syscall.B600, - 1200: syscall.B1200, - 1800: syscall.B1800, - 2400: syscall.B2400, - 4800: syscall.B4800, - 9600: syscall.B9600, - 19200: syscall.B19200, - 38400: syscall.B38400, - 57600: syscall.B57600, - 115200: syscall.B115200, - 230400: syscall.B230400, - 460800: syscall.B460800, - 500000: syscall.B500000, - 576000: syscall.B576000, - 921600: syscall.B921600, - 1000000: syscall.B1000000, - 1152000: syscall.B1152000, - 1500000: syscall.B1500000, - 2000000: syscall.B2000000, - 2500000: syscall.B2500000, - 3000000: syscall.B3000000, - 3500000: syscall.B3500000, - 4000000: syscall.B4000000, -} - -var databitsMap = map[int]int{ - 0: syscall.CS8, // Default to 8 bits - 5: syscall.CS5, - 6: syscall.CS6, - 7: syscall.CS7, - 8: syscall.CS8, -} - -const tc_CMSPAR int = 0 // may be CMSPAR or PAREXT -const tc_IUCLC = syscall.IUCLC - -func termiosMask(data int) uint32 { - return uint32(data) -} - -// syscall wrappers - -//sys ioctl(fd int, req uint64, data uintptr) (err error) - -const ioctl_tcgetattr = syscall.TCGETS -const ioctl_tcsetattr = syscall.TCSETS -const ioctl_tiocmdtr = syscall.TIOCM_DTR diff --git a/vendor/github.com/facchinm/go-serial/serial_unix.go b/vendor/github.com/facchinm/go-serial/serial_unix.go deleted file mode 100644 index bba7ae8f8..000000000 --- a/vendor/github.com/facchinm/go-serial/serial_unix.go +++ /dev/null @@ -1,268 +0,0 @@ -// -// Copyright 2014 Cristian Maglie. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// - -// +build linux darwin - -package serial - -import "io/ioutil" -import "regexp" -import "strings" -import "syscall" -import "unsafe" - -// Opaque type that implements SerialPort interface for linux -type SerialPort struct { - handle int -} - -// Close the serial port -func (port *SerialPort) Close() error { - port.releaseExclusiveAccess() - return syscall.Close(port.handle) -} - -// Stores data received from the serial port into the provided byte array -// buffer. The function returns the number of bytes read. -// -// The Read function blocks until (at least) one byte is received from -// the serial port or an error occurs. -func (port *SerialPort) Read(p []byte) (n int, err error) { - return syscall.Read(port.handle, p) -} - -// Send the content of the data byte array to the serial port. -// Returns the number of bytes written. -func (port *SerialPort) Write(p []byte) (n int, err error) { - return syscall.Write(port.handle, p) -} - -// Set all parameters of the serial port. See the Mode structure for more -// info. -func (port *SerialPort) SetMode(mode *Mode) error { - settings, err := port.getTermSettings() - if err != nil { - return err - } - if err := setTermSettingsBaudrate(mode.BaudRate, settings); err != nil { - return err - } - if err := setTermSettingsParity(mode.Parity, settings); err != nil { - return err - } - if err := setTermSettingsDataBits(mode.DataBits, settings); err != nil { - return err - } - if err := setTermSettingsStopBits(mode.StopBits, settings); err != nil { - return err - } - return port.setTermSettings(settings) -} - -// Open the serial port using the specified modes -func OpenPort(portName string, mode *Mode) (*SerialPort, error) { - h, err := syscall.Open(portName, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY, 0) - if err != nil { - switch err { - case syscall.EBUSY: - return nil, &SerialPortError{code: ERROR_PORT_BUSY} - case syscall.EACCES: - return nil, &SerialPortError{code: ERROR_PERMISSION_DENIED} - } - return nil, err - } - port := &SerialPort{ - handle: h, - } - - // Setup serial port - if port.SetMode(mode) != nil { - port.Close() - return nil, &SerialPortError{code: ERROR_INVALID_SERIAL_PORT} - } - - // Set raw mode - settings, err := port.getTermSettings() - if err != nil { - port.Close() - return nil, &SerialPortError{code: ERROR_INVALID_SERIAL_PORT} - } - setRawMode(settings, mode) - if port.setTermSettings(settings) != nil { - port.Close() - return nil, &SerialPortError{code: ERROR_INVALID_SERIAL_PORT} - } - - syscall.SetNonblock(h, false) - - port.acquireExclusiveAccess() - - return port, nil -} - -func GetPortsList() ([]string, error) { - files, err := ioutil.ReadDir(devFolder) - if err != nil { - return nil, err - } - - ports := make([]string, 0, len(files)) - for _, f := range files { - // Skip folders - if f.IsDir() { - continue - } - - // Keep only devices with the correct name - match, err := regexp.MatchString(regexFilter, f.Name()) - if err != nil { - return nil, err - } - if !match { - continue - } - - portName := devFolder + "/" + f.Name() - - // Check if serial port is real or is a placeholder serial port "ttySxx" - if strings.HasPrefix(f.Name(), "ttyS") { - port, err := OpenPort(portName, &Mode{}) - if err != nil { - serr, ok := err.(*SerialPortError) - if ok && serr.Code() == ERROR_INVALID_SERIAL_PORT { - continue - } - } else { - port.Close() - } - } - - // Save serial port in the resulting list - ports = append(ports, portName) - } - - return ports, nil -} - -// termios manipulation functions - -func setTermSettingsBaudrate(speed int, settings *syscall.Termios) error { - baudrate, ok := baudrateMap[speed] - if !ok { - return &SerialPortError{code: ERROR_INVALID_PORT_SPEED} - } - // revert old baudrate - BAUDMASK := 0 - for _, rate := range baudrateMap { - BAUDMASK |= rate - } - settings.Cflag &= ^termiosMask(BAUDMASK) - // set new baudrate - settings.Cflag |= termiosMask(baudrate) - settings.Ispeed = termiosMask(baudrate) - settings.Ospeed = termiosMask(baudrate) - return nil -} - -func setTermSettingsParity(parity Parity, settings *syscall.Termios) error { - switch parity { - case PARITY_NONE: - settings.Cflag &= ^termiosMask(syscall.PARENB | syscall.PARODD | tc_CMSPAR) - settings.Iflag &= ^termiosMask(syscall.INPCK) - case PARITY_ODD: - settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD) - settings.Cflag &= ^termiosMask(tc_CMSPAR) - settings.Iflag |= termiosMask(syscall.INPCK) - case PARITY_EVEN: - settings.Cflag &= ^termiosMask(syscall.PARODD | tc_CMSPAR) - settings.Cflag |= termiosMask(syscall.PARENB) - settings.Iflag |= termiosMask(syscall.INPCK) - case PARITY_MARK: - settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD | tc_CMSPAR) - settings.Iflag |= termiosMask(syscall.INPCK) - case PARITY_SPACE: - settings.Cflag &= ^termiosMask(syscall.PARODD) - settings.Cflag |= termiosMask(syscall.PARENB | tc_CMSPAR) - settings.Iflag |= termiosMask(syscall.INPCK) - } - return nil -} - -func setTermSettingsDataBits(bits int, settings *syscall.Termios) error { - databits, ok := databitsMap[bits] - if !ok { - return &SerialPortError{code: ERROR_INVALID_PORT_DATA_BITS} - } - settings.Cflag &= ^termiosMask(syscall.CSIZE) - settings.Cflag |= termiosMask(databits) - return nil -} - -func setTermSettingsStopBits(bits StopBits, settings *syscall.Termios) error { - switch bits { - case STOPBITS_ONE: - settings.Cflag &= ^termiosMask(syscall.CSTOPB) - case STOPBITS_ONEPOINTFIVE, STOPBITS_TWO: - settings.Cflag |= termiosMask(syscall.CSTOPB) - } - return nil -} - -func setRawMode(settings *syscall.Termios, mode *Mode) { - // Set local mode - settings.Cflag |= termiosMask(syscall.CREAD | syscall.CLOCAL) - - // Set raw mode - settings.Lflag &= ^termiosMask(syscall.ICANON | syscall.ECHO | syscall.ECHOE | syscall.ECHOK | - syscall.ECHONL | syscall.ECHOCTL | syscall.ECHOPRT | syscall.ECHOKE | syscall.ISIG | syscall.IEXTEN) - settings.Iflag &= ^termiosMask(syscall.IXON | syscall.IXOFF | syscall.IXANY | syscall.INPCK | - syscall.IGNPAR | syscall.PARMRK | syscall.ISTRIP | syscall.IGNBRK | syscall.BRKINT | syscall.INLCR | - syscall.IGNCR | syscall.ICRNL | tc_IUCLC) - settings.Oflag &= ^termiosMask(syscall.OPOST) - - if mode.Vmin == 0 && mode.Vtimeout == 0 { - // Switch to default mode - // Block reads until at least one char is available (no timeout) - mode.Vmin = 1 - } - - settings.Cc[syscall.VMIN] = mode.Vmin - settings.Cc[syscall.VTIME] = mode.Vtimeout -} - -// native syscall wrapper functions - -func (port *SerialPort) getTermSettings() (*syscall.Termios, error) { - settings := &syscall.Termios{} - err := ioctl(port.handle, ioctl_tcgetattr, uintptr(unsafe.Pointer(settings))) - return settings, err -} - -func (port *SerialPort) setTermSettings(settings *syscall.Termios) error { - return ioctl(port.handle, ioctl_tcsetattr, uintptr(unsafe.Pointer(settings))) -} - -func (port *SerialPort) acquireExclusiveAccess() error { - return ioctl(port.handle, syscall.TIOCEXCL, 0) -} - -func (port *SerialPort) releaseExclusiveAccess() error { - return ioctl(port.handle, syscall.TIOCNXCL, 0) -} - -func (port *SerialPort) SetDTR(level bool) error { - var status uint - _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(port.handle), uintptr(syscall.TIOCMGET), uintptr(unsafe.Pointer(&status))) - if err == 0 { - if level == false { - status &= ^uint(syscall.TIOCM_DTR) - } else { - status |= syscall.TIOCM_DTR - } - _, _, err = syscall.Syscall(syscall.SYS_IOCTL, uintptr(port.handle), uintptr(syscall.TIOCMSET), uintptr(unsafe.Pointer(&status))) - } - return err -} diff --git a/vendor/github.com/facchinm/go-serial/serial_windows.go b/vendor/github.com/facchinm/go-serial/serial_windows.go deleted file mode 100644 index 5043be460..000000000 --- a/vendor/github.com/facchinm/go-serial/serial_windows.go +++ /dev/null @@ -1,360 +0,0 @@ -// +build windows - -package serial - -import ( - "fmt" - "os" - "sync" - "syscall" - "time" - "unsafe" -) - -type SerialPort struct { - p *Port -} - -type Port struct { - f *os.File - fd syscall.Handle - rl sync.Mutex - wl sync.Mutex - ro *syscall.Overlapped - wo *syscall.Overlapped -} - -type structDCB struct { - DCBlength, BaudRate uint32 - flags [4]byte - wReserved, XonLim, XoffLim uint16 - ByteSize, Parity, StopBits byte - XonChar, XoffChar, ErrorChar, EofChar, EvtChar byte - wReserved1 uint16 -} - -type structTimeouts struct { - ReadIntervalTimeout uint32 - ReadTotalTimeoutMultiplier uint32 - ReadTotalTimeoutConstant uint32 - WriteTotalTimeoutMultiplier uint32 - WriteTotalTimeoutConstant uint32 -} - -func GetPortsList() ([]string, error) { - subKey, err := syscall.UTF16PtrFromString("HARDWARE\\DEVICEMAP\\SERIALCOMM\\") - if err != nil { - return nil, &SerialPortError{code: ERROR_ENUMERATING_PORTS} - } - - var h syscall.Handle - if syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, subKey, 0, syscall.KEY_READ, &h) != nil { - return nil, &SerialPortError{code: ERROR_ENUMERATING_PORTS} - } - defer syscall.RegCloseKey(h) - - var valuesCount uint32 - if syscall.RegQueryInfoKey(h, nil, nil, nil, nil, nil, nil, &valuesCount, nil, nil, nil, nil) != nil { - return nil, &SerialPortError{code: ERROR_ENUMERATING_PORTS} - } - - list := make([]string, valuesCount) - for i := range list { - var data [1024]uint16 - dataSize := uint32(len(data)) - var name [1024]uint16 - nameSize := uint32(len(name)) - if RegEnumValue(h, uint32(i), &name[0], &nameSize, nil, nil, &data[0], &dataSize) != nil { - return nil, &SerialPortError{code: ERROR_ENUMERATING_PORTS} - } - list[i] = syscall.UTF16ToString(data[:]) - } - return list, nil -} - -func OpenPort(portName string, mode *Mode) (*SerialPort, error) { - p, err := openPort(portName, mode.BaudRate, time.Duration(mode.Vtimeout)*time.Millisecond) - if err == nil { - port := new(SerialPort) - port.p = p - return port, err - } - return nil, err -} - -func openPort(name string, baud int, readTimeout time.Duration) (p *Port, err error) { - if len(name) > 0 && name[0] != '\\' { - name = "\\\\.\\" + name - } - - h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(name), - syscall.GENERIC_READ|syscall.GENERIC_WRITE, - 0, - nil, - syscall.OPEN_EXISTING, - syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, - 0) - if err != nil { - return nil, err - } - f := os.NewFile(uintptr(h), name) - defer func() { - if err != nil { - f.Close() - } - }() - - if err = setCommState(h, baud); err != nil { - return - } - if err = setupComm(h, 64, 64); err != nil { - return - } - if err = setCommTimeouts(h, readTimeout); err != nil { - return - } - if err = setCommMask(h); err != nil { - return - } - - ro, err := newOverlapped() - if err != nil { - return - } - wo, err := newOverlapped() - if err != nil { - return - } - port := new(Port) - port.f = f - port.fd = h - port.ro = ro - port.wo = wo - - return port, nil -} - -func (p *SerialPort) Close() error { - return p.p.f.Close() -} - -func (p *SerialPort) Write(buf []byte) (int, error) { - p.p.wl.Lock() - defer p.p.wl.Unlock() - - if err := resetEvent(p.p.wo.HEvent); err != nil { - return 0, err - } - var n uint32 - err := syscall.WriteFile(p.p.fd, buf, &n, p.p.wo) - if err != nil && err != syscall.ERROR_IO_PENDING { - return int(n), err - } - return getOverlappedResult(p.p.fd, p.p.wo) -} - -func (p *SerialPort) Read(buf []byte) (int, error) { - if p.p == nil || p.p.f == nil { - return 0, fmt.Errorf("Invalid port on read %v %v", p.p, p.p.f) - } - - p.p.rl.Lock() - defer p.p.rl.Unlock() - - if err := resetEvent(p.p.ro.HEvent); err != nil { - return 0, err - } - var done uint32 - err := syscall.ReadFile(p.p.fd, buf, &done, p.p.ro) - if err != nil && err != syscall.ERROR_IO_PENDING { - return int(done), err - } - return getOverlappedResult(p.p.fd, p.p.ro) -} - -// Discards data written to the port but not transmitted, -// or data received but not read -func (p *SerialPort) Flush() error { - return purgeComm(p.p.fd) -} - -var ( - nSetCommState, - nSetCommTimeouts, - nSetCommMask, - nSetupComm, - nGetOverlappedResult, - nCreateEvent, - nResetEvent, - nPurgeComm, - nFlushFileBuffers uintptr - modadvapi32 = syscall.NewLazyDLL("advapi32.dll") - procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW") -) - -func RegEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(valueLen)), 0) - if r0 != 0 { - regerrno = syscall.Errno(r0) - } - return -} - -func init() { - k32, err := syscall.LoadLibrary("kernel32.dll") - if err != nil { - panic("LoadLibrary " + err.Error()) - } - defer syscall.FreeLibrary(k32) - - nSetCommState = getProcAddr(k32, "SetCommState") - nSetCommTimeouts = getProcAddr(k32, "SetCommTimeouts") - nSetCommMask = getProcAddr(k32, "SetCommMask") - nSetupComm = getProcAddr(k32, "SetupComm") - nGetOverlappedResult = getProcAddr(k32, "GetOverlappedResult") - nCreateEvent = getProcAddr(k32, "CreateEventW") - nResetEvent = getProcAddr(k32, "ResetEvent") - nPurgeComm = getProcAddr(k32, "PurgeComm") - nFlushFileBuffers = getProcAddr(k32, "FlushFileBuffers") -} - -func getProcAddr(lib syscall.Handle, name string) uintptr { - addr, err := syscall.GetProcAddress(lib, name) - if err != nil { - panic(name + " " + err.Error()) - } - return addr -} - -func setCommState(h syscall.Handle, baud int) error { - var params structDCB - params.DCBlength = uint32(unsafe.Sizeof(params)) - - params.flags[0] = 0x01 // fBinary - params.flags[0] |= 0x10 // Assert DSR - - params.BaudRate = uint32(baud) - params.ByteSize = 8 - - r, _, err := syscall.Syscall(nSetCommState, 2, uintptr(h), uintptr(unsafe.Pointer(¶ms)), 0) - if r == 0 { - return err - } - return nil -} - -func setCommTimeouts(h syscall.Handle, readTimeout time.Duration) error { - var timeouts structTimeouts - const MAXDWORD = 1<<32 - 1 - - if readTimeout > 0 { - // non-blocking read - timeoutMs := readTimeout.Nanoseconds() / 1e6 - if timeoutMs < 1 { - timeoutMs = 1 - } else if timeoutMs > MAXDWORD { - timeoutMs = MAXDWORD - } - timeouts.ReadIntervalTimeout = 0 - timeouts.ReadTotalTimeoutMultiplier = 0 - timeouts.ReadTotalTimeoutConstant = uint32(timeoutMs) - } else { - // blocking read - timeouts.ReadIntervalTimeout = MAXDWORD - timeouts.ReadTotalTimeoutMultiplier = MAXDWORD - timeouts.ReadTotalTimeoutConstant = MAXDWORD - 1 - } - - /* From http://msdn.microsoft.com/en-us/library/aa363190(v=VS.85).aspx - - For blocking I/O see below: - - Remarks: - - If an application sets ReadIntervalTimeout and - ReadTotalTimeoutMultiplier to MAXDWORD and sets - ReadTotalTimeoutConstant to a value greater than zero and - less than MAXDWORD, one of the following occurs when the - ReadFile function is called: - - If there are any bytes in the input buffer, ReadFile returns - immediately with the bytes in the buffer. - - If there are no bytes in the input buffer, ReadFile waits - until a byte arrives and then returns immediately. - - If no bytes arrive within the time specified by - ReadTotalTimeoutConstant, ReadFile times out. - */ - - r, _, err := syscall.Syscall(nSetCommTimeouts, 2, uintptr(h), uintptr(unsafe.Pointer(&timeouts)), 0) - if r == 0 { - return err - } - return nil -} - -func setupComm(h syscall.Handle, in, out int) error { - r, _, err := syscall.Syscall(nSetupComm, 3, uintptr(h), uintptr(in), uintptr(out)) - if r == 0 { - return err - } - return nil -} - -func setCommMask(h syscall.Handle) error { - const EV_RXCHAR = 0x0001 - r, _, err := syscall.Syscall(nSetCommMask, 2, uintptr(h), EV_RXCHAR, 0) - if r == 0 { - return err - } - return nil -} - -func resetEvent(h syscall.Handle) error { - r, _, err := syscall.Syscall(nResetEvent, 1, uintptr(h), 0, 0) - if r == 0 { - return err - } - return nil -} - -func purgeComm(h syscall.Handle) error { - const PURGE_TXABORT = 0x0001 - const PURGE_RXABORT = 0x0002 - const PURGE_TXCLEAR = 0x0004 - const PURGE_RXCLEAR = 0x0008 - r, _, err := syscall.Syscall(nPurgeComm, 2, uintptr(h), - PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR, 0) - if r == 0 { - return err - } - return nil -} - -func newOverlapped() (*syscall.Overlapped, error) { - var overlapped syscall.Overlapped - r, _, err := syscall.Syscall6(nCreateEvent, 4, 0, 1, 0, 0, 0, 0) - if r == 0 { - return nil, err - } - overlapped.HEvent = syscall.Handle(r) - return &overlapped, nil -} - -func getOverlappedResult(h syscall.Handle, overlapped *syscall.Overlapped) (int, error) { - var n int - r, _, err := syscall.Syscall6(nGetOverlappedResult, 4, - uintptr(h), - uintptr(unsafe.Pointer(overlapped)), - uintptr(unsafe.Pointer(&n)), 1, 0, 0) - if r == 0 { - return n, err - } - - return n, nil -} - -func (port *SerialPort) SetDTR(_ bool) error { - return nil -} diff --git a/vendor/github.com/getlantern/context/.travis.yml b/vendor/github.com/getlantern/context/.travis.yml deleted file mode 100644 index cc2835a08..000000000 --- a/vendor/github.com/getlantern/context/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go - -go: - - 1.6.2 - -install: - - go get -d -t -v ./... - - go build -v ./... - - go get golang.org/x/tools/cmd/cover - - go get -v github.com/axw/gocov/gocov - - go get -v github.com/mattn/goveralls - -script: - - go test -race -v -covermode=atomic -coverprofile=profile.cov - - $HOME/gopath/bin/goveralls -coverprofile=profile.cov -service=travis-ci diff --git a/vendor/github.com/getlantern/context/README.md b/vendor/github.com/getlantern/context/README.md deleted file mode 100644 index 978c9e05a..000000000 --- a/vendor/github.com/getlantern/context/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# context [![Travis CI Status](https://travis-ci.org/getlantern/context.svg?branch=master)](https://travis-ci.org/getlantern/context) [![Coverage Status](https://coveralls.io/repos/getlantern/context/badge.png?branch=master)](https://coveralls.io/r/getlantern/context) - -Provides goroutine-based context state inspired by https://github.com/tylerb/gls -and https://github.com/jtolds/gls. It uses the same basic hack as tylerb's -library, but adds a stack abstraction that allows nested contexts similar to -jtolds' library, but using `Enter()` and `Exit()` instead of callback functions. diff --git a/vendor/github.com/getlantern/context/context_test.go b/vendor/github.com/getlantern/context/context_test.go deleted file mode 100644 index ada9304ac..000000000 --- a/vendor/github.com/getlantern/context/context_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package context - -import ( - "sync" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestStack(t *testing.T) { - cm := NewManager() - _cm := cm.(*manager) - // Put globals first - cm.PutGlobal("a", -1) // This will get overriden in specific contexts - cm.PutGlobal("ga", "i") - cm.PutGlobalDynamic("gb", func() interface{} { return "ii" }) - - // Use a Map as a Contextual - var contextual = Map{ - "a": 0, // This will override whatever is in specific contexts - "contextual": "special", - } - - c := cm.Enter() - c.Put("a", 1) - penultimate := cm.Enter(). - Put("b", 2) - c = cm.Enter(). - PutDynamic("c", func() interface{} { return 4 }). - PutIfAbsent("d", 5). - PutIfAbsent("a", 11) - - // Put something in the penultimate context and make sure it doesn't override - // what's set in the ultimate context - penultimate.Put("c", 3) - - var assertMutex sync.Mutex - doAssertContents := func(expected Map, actual Map, scope string) { - assertMutex.Lock() - assert.Equal(t, expected, actual, scope) - assertMutex.Unlock() - } - - assertContents := func(expected Map) { - doAssertContents(expected, cm.AsMap(nil, false), "AsMapwith(nil, false)") - expected["ga"] = "i" - expected["gb"] = "ii" - _, exists := expected["a"] - if !exists { - expected["a"] = -1 - } - doAssertContents(expected, cm.AsMap(nil, true), "AsMap(nil, true)") - expected["a"] = 0 - expected["contextual"] = "special" - doAssertContents(expected, cm.AsMap(contextual, true), "AsMapWith(contextual, true)") - delete(expected, "ga") - delete(expected, "gb") - doAssertContents(expected, cm.AsMap(contextual, false), "AsMapWith(contextual, false)") - } - - assertContents(Map{ - "a": 1, - "b": 2, - "c": 4, - "d": 5, - }) - - var wg sync.WaitGroup - wg.Add(1) - cm.Go(func() { - defer cm.Enter().Put("e", 6).Exit() - assertContents(Map{ - "a": 1, - "b": 2, - "c": 4, - "d": 5, - "e": 6, - }) - wg.Done() - }) - wg.Wait() - - wg.Add(1) - cm.Go(func() { - // This goroutine doesn't Exit. Still, we shouldn't leak anything. - wg.Done() - }) - wg.Wait() - - assertContents(Map{ - "a": 1, - "b": 2, - "c": 4, - "d": 5, - }) - - c.Exit() - c = _cm.currentContext() - assert.NotNil(t, c) - assertContents(Map{ - "a": 1, - "b": 2, - "c": 3, - }) - - c.Exit() - c = _cm.currentContext() - assert.NotNil(t, c) - assertContents(Map{ - "a": 1, - }) - - // Last exit - c.Exit() - assert.Nil(t, _cm.currentContext()) - assertContents(Map{}) - - // Exit again, just for good measure - c.Exit() - assert.Nil(t, _cm.currentContext()) - assertContents(Map{}) - - // Spawn a goroutine with no existing contexts - wg.Add(1) - cm.Go(func() { - defer cm.Enter().Put("f", 7).Exit() - assertContents(Map{ - "f": 7, - }) - wg.Done() - }) - wg.Wait() - - _cm.allmx.RLock() - assert.Empty(t, _cm.contexts, "No contexts should be left") - _cm.allmx.RUnlock() -} - -func BenchmarkPut(b *testing.B) { - cm := NewManager() - c := cm.Enter() - b.ResetTimer() - for i := 0; i < b.N; i++ { - c.Put("key", "value") - } -} - -func BenchmarkAsMap(b *testing.B) { - cm := NewManager() - cm.Enter().Put("a", 1).Put("b", 2) - b.ResetTimer() - for i := 0; i < b.N; i++ { - cm.AsMap(nil, true) - } -} diff --git a/vendor/github.com/getlantern/errors/errors.go b/vendor/github.com/getlantern/errors/errors.go index 4896addec..8b2b84fdc 100644 --- a/vendor/github.com/getlantern/errors/errors.go +++ b/vendor/github.com/getlantern/errors/errors.go @@ -83,7 +83,7 @@ import ( "github.com/getlantern/context" "github.com/getlantern/hidden" "github.com/getlantern/ops" - "github.com/getlantern/stack" + "github.com/go-stack/stack" ) // Error wraps system and application defined errors in unified structure for diff --git a/vendor/github.com/getlantern/errors/errors_test.go b/vendor/github.com/getlantern/errors/errors_test.go deleted file mode 100644 index a5d5afbc7..000000000 --- a/vendor/github.com/getlantern/errors/errors_test.go +++ /dev/null @@ -1,119 +0,0 @@ -package errors - -import ( - "bytes" - "fmt" - "regexp" - "testing" - - "github.com/getlantern/context" - "github.com/getlantern/hidden" - "github.com/getlantern/ops" - "github.com/stretchr/testify/assert" -) - -var ( - replaceNumbers = regexp.MustCompile("[0-9]+") -) - -func TestFull(t *testing.T) { - var firstErr Error - - // Iterate past the size of the hidden buffer - for i := 0; i < len(hiddenErrors)*2; i++ { - op := ops.Begin("op1").Set("ca", 100).Set("cd", 100) - e := New("Hello %v", "There").Op("My Op").With("DaTa_1", 1) - op.End() - if firstErr == nil { - firstErr = e - } - assert.Equal(t, "Hello There", e.Error()[:11]) - op = ops.Begin("op2").Set("ca", 200).Set("cb", 200).Set("cc", 200) - e3 := Wrap(fmt.Errorf("I'm wrapping your text: %v", e)).Op("outer op").With("dATA+1", i).With("cb", 300) - op.End() - assert.Equal(t, e, e3.(*structured).cause, "Wrapping a regular error should have extracted the contained *Error") - m := make(context.Map) - e3.Fill(m) - assert.Equal(t, i, m["data_1"], "Error's data should dominate all") - assert.Equal(t, 200, m["ca"], "Error's context should dominate cause") - assert.Equal(t, 300, m["cb"], "Error's data should dominate its context") - assert.Equal(t, 200, m["cc"], "Error's context should come through") - assert.Equal(t, 100, m["cd"], "Cause's context should come through") - assert.Equal(t, "My Op", e.(*structured).data["error_op"], "Op should be available from cause") - - for _, call := range e3.(*structured).callStack { - t.Logf("at %v", call) - } - } - - e3 := Wrap(fmt.Errorf("I'm wrapping your text: %v", firstErr)).With("a", 2) - assert.Nil(t, e3.(*structured).cause, "Wrapping an *Error that's no longer buffered should have yielded no cause") -} - -func TestNewWithCause(t *testing.T) { - cause := buildCause() - outer := New("Hello %v", cause) - assert.Equal(t, "Hello World", hidden.Clean(outer.Error())) - assert.Equal(t, "Hello %v", outer.(*structured).ErrorClean()) - assert.Equal(t, - "github.com/getlantern/errors.TestNewWithCause (errors_test.go:999)", - replaceNumbers.ReplaceAllString(outer.(*structured).data["error_location"].(string), "999")) - assert.Equal(t, cause, outer.(*structured).cause) - - // Make sure that stacktrace prints out okay - buf := &bytes.Buffer{} - print := outer.MultiLinePrinter() - for { - more := print(buf) - buf.WriteByte('\n') - if !more { - break - } - } - expected := `Hello World - at github.com/getlantern/errors.TestNewWithCause (errors_test.go:999) - at testing.tRunner (testing.go:999) - at runtime.goexit (asm_amd999.s:999) -Caused by: World - at github.com/getlantern/errors.buildCause (errors_test.go:999) - at github.com/getlantern/errors.TestNewWithCause (errors_test.go:999) - at testing.tRunner (testing.go:999) - at runtime.goexit (asm_amd999.s:999) -Caused by: orld -Caused by: ld - at github.com/getlantern/errors.buildSubSubCause (errors_test.go:999) - at github.com/getlantern/errors.buildSubCause (errors_test.go:999) - at github.com/getlantern/errors.buildCause (errors_test.go:999) - at github.com/getlantern/errors.TestNewWithCause (errors_test.go:999) - at testing.tRunner (testing.go:999) - at runtime.goexit (asm_amd999.s:999) -Caused by: d -` - - assert.Equal(t, expected, replaceNumbers.ReplaceAllString(hidden.Clean(buf.String()), "999")) - assert.Equal(t, buildSubSubSubCause(), outer.RootCause()) -} - -func buildCause() Error { - return New("W%v", buildSubCause()) -} - -func buildSubCause() error { - return fmt.Errorf("or%v", buildSubSubCause()) -} - -func buildSubSubCause() error { - return New("l%v", buildSubSubSubCause()) -} - -func buildSubSubSubCause() error { - return fmt.Errorf("d") -} - -func TestWrapNil(t *testing.T) { - assert.Nil(t, doWrapNil()) -} - -func doWrapNil() error { - return Wrap(nil) -} diff --git a/vendor/github.com/getlantern/errors/hide.go b/vendor/github.com/getlantern/errors/hide.go index 3349bddfa..f10d863f2 100644 --- a/vendor/github.com/getlantern/errors/hide.go +++ b/vendor/github.com/getlantern/errors/hide.go @@ -29,7 +29,7 @@ func (e *structured) save() { hiddenMutex.Unlock() } -func get(hiddenID []byte) *structured { +func get(hiddenID []byte) Error { if len(hiddenID) != 8 { return nil } diff --git a/vendor/github.com/getlantern/filepersist/filepersist.go b/vendor/github.com/getlantern/filepersist/filepersist.go deleted file mode 100644 index 716167dfb..000000000 --- a/vendor/github.com/getlantern/filepersist/filepersist.go +++ /dev/null @@ -1,116 +0,0 @@ -// package filepersist provdies a mechanism for persisting data to a file at a -// permanent location -package filepersist - -import ( - "fmt" - "io" - "os" - - "github.com/getlantern/golog" -) - -var ( - log = golog.LoggerFor("filepersist") -) - -// Save saves the given data to the file at filename. If an existing file at -// that filename already exists, this simply chmods the existing file to match -// the given fileMode and otherwise leaves it alone. -func Save(filename string, data []byte, fileMode os.FileMode) error { - log.Tracef("Attempting to open %v for creating, but only if it doesn't already exist", filename) - file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, fileMode) - if err != nil { - if !os.IsExist(err) { - return fmt.Errorf("Unexpected error opening %s: %s", filename, err) - } - - log.Tracef("%s already exists, check to make sure contents is the same", filename) - if dataMatches(filename, data) { - log.Tracef("Data in %s matches expected, using existing", filename) - chmod(filename, fileMode) - // TODO - maybe don't swallow the error, but returning something - // unique so the caller can decide whether or not to ignore it. - return nil - } - - log.Tracef("Data in %s doesn't match expected, truncating file", filename) - file, err = openAndTruncate(filename, fileMode, true) - if err != nil { - return fmt.Errorf("Unable to truncate %s: %s", filename, err) - } - } - - log.Tracef("Created new file at %s, writing data", filename) - _, err = file.Write(data) - if err != nil { - os.Remove(filename) - return fmt.Errorf("Unable to write to file at %s: %s", filename, err) - } - file.Sync() - file.Close() - - log.Trace("File saved") - return nil -} - -func openAndTruncate(filename string, fileMode os.FileMode, removeIfNecessary bool) (*os.File, error) { - file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, fileMode) - if err != nil && os.IsPermission(err) && removeIfNecessary { - log.Tracef("Permission denied truncating file %v, try to remove", filename) - err = os.Remove(filename) - if err != nil { - return nil, fmt.Errorf("Unable to remove file %v: %v", filename, err) - } - return openAndTruncate(filename, fileMode, false) - } - - return file, err -} - -// dataMatches compares the file at filename byte for byte with the given data -func dataMatches(filename string, data []byte) bool { - file, err := os.OpenFile(filename, os.O_RDONLY, 0) - if err != nil { - log.Tracef("Unable to open existing file at %s for reading: %s", filename, err) - return false - } - fileInfo, err := file.Stat() - if err != nil { - log.Tracef("Unable to stat file %s", filename) - return false - } - if fileInfo.Size() != int64(len(data)) { - return false - } - b := make([]byte, 65536) - i := 0 - for { - n, err := file.Read(b) - if err != nil && err != io.EOF { - log.Tracef("Error reading %s for comparison: %s", filename, err) - return false - } - for j := 0; j < n; j++ { - if b[j] != data[i] { - return false - } - i = i + 1 - } - if err == io.EOF { - break - } - } - return true -} - -func chmod(filename string, fileMode os.FileMode) { - fi, err := os.Stat(filename) - if err != nil || fi.Mode() != fileMode { - log.Tracef("Chmodding %v", filename) - err = os.Chmod(filename, fileMode) - if err != nil { - log.Debugf("Warning - unable to chmod %v: %v", filename, err) - } - } -} diff --git a/vendor/github.com/getlantern/golog/README.md b/vendor/github.com/getlantern/golog/README.md deleted file mode 100644 index 88fe677d1..000000000 --- a/vendor/github.com/getlantern/golog/README.md +++ /dev/null @@ -1,6 +0,0 @@ -golog [![Travis CI Status](https://travis-ci.org/getlantern/golog.svg?branch=master)](https://travis-ci.org/getlantern/golog) [![Coverage Status](https://coveralls.io/repos/getlantern/golog/badge.png)](https://coveralls.io/r/getlantern/golog) [![GoDoc](https://godoc.org/github.com/getlantern/golog?status.png)](http://godoc.org/github.com/getlantern/golog) -========== -Provides logging used in many getlantern components. - -[GoDoc](https://godoc.org/github.com/getlantern/golog) - diff --git a/vendor/github.com/getlantern/golog/golog.go b/vendor/github.com/getlantern/golog/golog.go index 8870376a4..143e904a6 100644 --- a/vendor/github.com/getlantern/golog/golog.go +++ b/vendor/github.com/getlantern/golog/golog.go @@ -1,31 +1,73 @@ -// package golog implements logging functions that log errors to stderr and -// debug messages to stdout. Trace logging is also supported. Trace logs go to -// stdout as well, but they are only written if the program is run with -// environment variable "TRACE=true" +// Package golog implements logging functions that log errors to stderr and +// debug messages to stdout. Trace logging is also supported. +// Trace logs go to stdout as well, but they are only written if the program +// is run with environment variable "TRACE=true". +// A stack dump will be printed after the message if "PRINT_STACK=true". package golog import ( "bufio" + "bytes" "fmt" "io" "io/ioutil" + "log" "os" + "path/filepath" + "runtime" + "sort" "strconv" + "strings" + "sync" "sync/atomic" + + "github.com/getlantern/errors" + "github.com/getlantern/hidden" + "github.com/getlantern/ops" + "github.com/oxtoacart/bpool" +) + +const ( + // ERROR is an error Severity + ERROR = 500 + + // FATAL is an error Severity + FATAL = 600 ) var ( - outs atomic.Value + outs atomic.Value + reporters []ErrorReporter + reportersMutex sync.RWMutex + + bufferPool = bpool.NewBufferPool(200) + + onFatal atomic.Value ) +// Severity is a level of error (higher values are more severe) +type Severity int + +func (s Severity) String() string { + switch s { + case ERROR: + return "ERROR" + case FATAL: + return "FATAL" + default: + return "UNKNOWN" + } +} + func init() { + DefaultOnFatal() ResetOutputs() } func SetOutputs(errorOut io.Writer, debugOut io.Writer) { outs.Store(&outputs{ - errorOut: errorOut, - debugOut: debugOut, + ErrorOut: errorOut, + DebugOut: debugOut, }) } @@ -33,15 +75,53 @@ func ResetOutputs() { SetOutputs(os.Stderr, os.Stdout) } -func getOutputs() *outputs { +func GetOutputs() *outputs { return outs.Load().(*outputs) } +// RegisterReporter registers the given ErrorReporter. All logged Errors are +// sent to this reporter. +func RegisterReporter(reporter ErrorReporter) { + reportersMutex.Lock() + reporters = append(reporters, reporter) + reportersMutex.Unlock() +} + +// OnFatal configures golog to call the given function on any FATAL error. By +// default, golog calls os.Exit(1) on any FATAL error. +func OnFatal(fn func(err error)) { + onFatal.Store(fn) +} + +// DefaultOnFatal enables the default behavior for OnFatal +func DefaultOnFatal() { + onFatal.Store(func(err error) { + os.Exit(1) + }) +} + type outputs struct { - errorOut io.Writer - debugOut io.Writer + ErrorOut io.Writer + DebugOut io.Writer } +// MultiLine is an interface for arguments that support multi-line output. +type MultiLine interface { + // MultiLinePrinter returns a function that can be used to print the + // multi-line output. The returned function writes one line to the buffer and + // returns true if there are more lines to write. This function does not need + // to take care of trailing carriage returns, golog handles that + // automatically. + MultiLinePrinter() func(buf *bytes.Buffer) bool +} + +// ErrorReporter is a function to which the logger will report errors. +// It the given error and corresponding message along with associated ops +// context. This should return quickly as it executes on the critical code +// path. The recommended approach is to buffer as much as possible and discard +// new reports if the buffer becomes saturated. +type ErrorReporter func(err error, linePrefix string, severity Severity, ctx map[string]interface{}) + type Logger interface { // Debug logs to stdout Debug(arg interface{}) @@ -49,9 +129,10 @@ type Logger interface { Debugf(message string, args ...interface{}) // Error logs to stderr - Error(arg interface{}) - // Errorf logs to stderr - Errorf(message string, args ...interface{}) + Error(arg interface{}) error + // Errorf logs to stderr. It returns the first argument that's an error, or + // a new error built using fmt.Errorf if none of the arguments are errors. + Errorf(message string, args ...interface{}) error // Fatal logs to stderr and then exits with status 1 Fatal(arg interface{}) @@ -73,76 +154,177 @@ type Logger interface { // IsTraceEnabled() indicates whether or not tracing is enabled for this // logger. IsTraceEnabled() bool + + // AsStdLogger returns an standard logger + AsStdLogger() *log.Logger } func LoggerFor(prefix string) Logger { l := &logger{ prefix: prefix + ": ", + pc: make([]uintptr, 10), + } + + trace := os.Getenv("TRACE") + l.traceOn, _ = strconv.ParseBool(trace) + if !l.traceOn { + prefixes := strings.Split(trace, ",") + for _, p := range prefixes { + if prefix == strings.Trim(p, " ") { + l.traceOn = true + break + } + } } - l.traceOn, _ = strconv.ParseBool(os.Getenv("TRACE")) if l.traceOn { l.traceOut = l.newTraceWriter() } else { l.traceOut = ioutil.Discard } + printStack := os.Getenv("PRINT_STACK") + l.printStack, _ = strconv.ParseBool(printStack) + return l } type logger struct { - prefix string - traceOn bool - traceOut io.Writer - outs atomic.Value + prefix string + traceOn bool + traceOut io.Writer + printStack bool + outs atomic.Value + pc []uintptr + funcForPc *runtime.Func } -func (l *logger) Debug(arg interface{}) { - _, err := fmt.Fprintf(getOutputs().debugOut, l.prefix+"%s\n", arg) - if err != nil { - errorOnLogging(err) - } +// attaches the file and line number corresponding to +// the log message +func (l *logger) linePrefix(skipFrames int) string { + runtime.Callers(skipFrames, l.pc) + funcForPc := runtime.FuncForPC(l.pc[0]) + file, line := funcForPc.FileLine(l.pc[0] - 1) + return fmt.Sprintf("%s%s:%d ", l.prefix, filepath.Base(file), line) } -func (l *logger) Debugf(message string, args ...interface{}) { - _, err := fmt.Fprintf(getOutputs().debugOut, l.prefix+message+"\n", args...) +func (l *logger) print(out io.Writer, skipFrames int, severity string, arg interface{}) string { + buf := bufferPool.Get() + defer bufferPool.Put(buf) + + linePrefix := l.linePrefix(skipFrames) + writeHeader := func() { + buf.WriteString(severity) + buf.WriteString(" ") + buf.WriteString(linePrefix) + } + if arg != nil { + ml, isMultiline := arg.(MultiLine) + if !isMultiline { + writeHeader() + fmt.Fprintf(buf, "%v", arg) + printContext(buf, arg) + buf.WriteByte('\n') + } else { + mlp := ml.MultiLinePrinter() + first := true + for { + writeHeader() + more := mlp(buf) + if first { + printContext(buf, arg) + first = false + } + buf.WriteByte('\n') + if !more { + break + } + } + } + } + b := []byte(hidden.Clean(buf.String())) + _, err := out.Write(b) if err != nil { errorOnLogging(err) } + if l.printStack { + l.doPrintStack() + } + + return linePrefix } -func (l *logger) Error(arg interface{}) { - _, err := fmt.Fprintf(getOutputs().errorOut, l.prefix+"%s\n", arg) - if err != nil { +func (l *logger) printf(out io.Writer, skipFrames int, severity string, err error, message string, args ...interface{}) string { + buf := bufferPool.Get() + defer bufferPool.Put(buf) + + linePrefix := l.linePrefix(skipFrames) + buf.WriteString(severity) + buf.WriteString(" ") + buf.WriteString(linePrefix) + fmt.Fprintf(buf, message, args...) + printContext(buf, err) + buf.WriteByte('\n') + b := []byte(hidden.Clean(buf.String())) + _, err2 := out.Write(b) + if err2 != nil { errorOnLogging(err) } + if l.printStack { + l.doPrintStack() + } + return linePrefix } -func (l *logger) Errorf(message string, args ...interface{}) { - _, err := fmt.Fprintf(getOutputs().errorOut, l.prefix+message+"\n", args...) - if err != nil { - errorOnLogging(err) - } +func (l *logger) Debug(arg interface{}) { + l.print(GetOutputs().DebugOut, 4, "DEBUG", arg) +} + +func (l *logger) Debugf(message string, args ...interface{}) { + l.printf(GetOutputs().DebugOut, 4, "DEBUG", nil, message, args...) +} + +func (l *logger) Error(arg interface{}) error { + return l.errorSkipFrames(arg, 1, ERROR) +} + +func (l *logger) Errorf(message string, args ...interface{}) error { + return l.errorSkipFrames(errors.NewOffset(1, message, args...), 1, ERROR) } func (l *logger) Fatal(arg interface{}) { - l.Error(arg) - os.Exit(1) + fatal(l.errorSkipFrames(arg, 1, FATAL)) } func (l *logger) Fatalf(message string, args ...interface{}) { - l.Errorf(message, args...) - os.Exit(1) + fatal(l.errorSkipFrames(errors.NewOffset(1, message, args...), 1, FATAL)) +} + +func fatal(err error) { + fn := onFatal.Load().(func(err error)) + fn(err) +} + +func (l *logger) errorSkipFrames(arg interface{}, skipFrames int, severity Severity) error { + var err error + switch e := arg.(type) { + case error: + err = e + default: + err = fmt.Errorf("%v", e) + } + linePrefix := l.print(GetOutputs().ErrorOut, skipFrames+4, severity.String(), err) + return report(err, linePrefix, severity) } func (l *logger) Trace(arg interface{}) { if l.traceOn { - l.Debug(arg) + l.print(GetOutputs().DebugOut, 4, "TRACE", arg) } } -func (l *logger) Tracef(fmt string, args ...interface{}) { +func (l *logger) Tracef(message string, args ...interface{}) { if l.traceOn { - l.Debugf(fmt, args...) + l.printf(GetOutputs().DebugOut, 4, "TRACE", nil, message, args...) } } @@ -158,17 +340,28 @@ func (l *logger) newTraceWriter() io.Writer { pr, pw := io.Pipe() br := bufio.NewReader(pr) + if !l.traceOn { + return pw + } go func() { - defer pr.Close() - defer pw.Close() + defer func() { + if err := pr.Close(); err != nil { + errorOnLogging(err) + } + }() + defer func() { + if err := pw.Close(); err != nil { + errorOnLogging(err) + } + }() for { line, err := br.ReadString('\n') if err == nil { // Log the line (minus the trailing newline) - l.Trace(line[:len(line)-1]) + l.print(GetOutputs().DebugOut, 6, "TRACE", line[:len(line)-1]) } else { - l.Tracef("TraceWriter closed due to unexpected error: %v", err) + l.printf(GetOutputs().DebugOut, 6, "TRACE", nil, "TraceWriter closed due to unexpected error: %v", err) return } } @@ -177,6 +370,89 @@ func (l *logger) newTraceWriter() io.Writer { return pw } +type errorWriter struct { + l *logger +} + +// Write implements method of io.Writer, due to different call depth, +// it will not log correct file and line prefix +func (w *errorWriter) Write(p []byte) (n int, err error) { + s := string(p) + if s[len(s)-1] == '\n' { + s = s[:len(s)-1] + } + w.l.print(GetOutputs().ErrorOut, 6, "ERROR", s) + return len(p), nil +} + +func (l *logger) AsStdLogger() *log.Logger { + return log.New(&errorWriter{l}, "", 0) +} + +func (l *logger) doPrintStack() { + var b []byte + buf := bytes.NewBuffer(b) + for _, pc := range l.pc { + funcForPc := runtime.FuncForPC(pc) + if funcForPc == nil { + break + } + name := funcForPc.Name() + if strings.HasPrefix(name, "runtime.") { + break + } + file, line := funcForPc.FileLine(pc) + fmt.Fprintf(buf, "\t%s\t%s: %d\n", name, file, line) + } + if _, err := buf.WriteTo(os.Stderr); err != nil { + errorOnLogging(err) + } +} + func errorOnLogging(err error) { fmt.Fprintf(os.Stderr, "Unable to log: %v\n", err) } + +func printContext(buf *bytes.Buffer, err interface{}) { + // Note - we don't include globals when printing in order to avoid polluting the text log + values := ops.AsMap(err, false) + if len(values) == 0 { + return + } + buf.WriteString(" [") + var keys []string + for key := range values { + keys = append(keys, key) + } + sort.Strings(keys) + for i, key := range keys { + value := values[key] + if i > 0 { + buf.WriteString(" ") + } + buf.WriteString(key) + buf.WriteString("=") + fmt.Fprintf(buf, "%v", value) + } + buf.WriteByte(']') +} + +func report(err error, linePrefix string, severity Severity) error { + var reportersCopy []ErrorReporter + reportersMutex.RLock() + if len(reporters) > 0 { + reportersCopy = make([]ErrorReporter, len(reporters)) + copy(reportersCopy, reporters) + } + reportersMutex.RUnlock() + + if len(reportersCopy) > 0 { + ctx := ops.AsMap(err, true) + ctx["severity"] = severity.String() + for _, reporter := range reportersCopy { + // We include globals when reporting + reporter(err, linePrefix, severity, ctx) + } + } + return err +} diff --git a/vendor/github.com/getlantern/hidden/hidden_test.go b/vendor/github.com/getlantern/hidden/hidden_test.go deleted file mode 100644 index 420ce64cd..000000000 --- a/vendor/github.com/getlantern/hidden/hidden_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package hidden - -import ( - "encoding/binary" - "fmt" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestRoundTrip(t *testing.T) { - str := "H" - encoded := ToString([]byte(str)) - rt, err := FromString(encoded) - if assert.NoError(t, err) { - assert.Equal(t, str, string(rt)) - } -} - -func TestExtract(t *testing.T) { - a := []byte("Here is my string") - b := make([]byte, 8) - binary.BigEndian.PutUint64(b, 56) - str := fmt.Sprintf("hidden%s data%s is fun", ToString(a), ToString(b)) - t.Log(str) - out, err := Extract(str) - if assert.NoError(t, err) { - if assert.Len(t, out, 2) { - assert.Equal(t, out, [][]byte{a, b}) - } - } - assert.Equal(t, "hidden data is fun", Clean(str)) -} diff --git a/vendor/github.com/getlantern/ops/ops.go b/vendor/github.com/getlantern/ops/ops.go index 24710f8df..136302db9 100644 --- a/vendor/github.com/getlantern/ops/ops.go +++ b/vendor/github.com/getlantern/ops/ops.go @@ -35,6 +35,10 @@ type Op interface { // or failure to all registered Reporters. End() + // Cancel cancels this op so that even if End() is called later, it will not + // report its success or failure. + Cancel() + // Set puts a key->value pair into the current Op's context. Set(key string, value interface{}) Op @@ -49,8 +53,9 @@ type Op interface { } type op struct { - ctx context.Context - failure atomic.Value + ctx context.Context + canceled bool + failure atomic.Value } // RegisterReporter registers the given reporter. @@ -78,7 +83,15 @@ func Go(fn func()) { cm.Go(fn) } +func (o *op) Cancel() { + o.canceled = true +} + func (o *op) End() { + if o.canceled { + return + } + var reportersCopy []Reporter reportersMutex.RLock() if len(reporters) > 0 { diff --git a/vendor/github.com/getlantern/ops/ops_test.go b/vendor/github.com/getlantern/ops/ops_test.go deleted file mode 100644 index 65f7dbc88..000000000 --- a/vendor/github.com/getlantern/ops/ops_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package ops_test - -import ( - "sync" - "testing" - - "github.com/getlantern/errors" - "github.com/getlantern/ops" - "github.com/stretchr/testify/assert" -) - -func TestSuccess(t *testing.T) { - var reportedFailure error - var reportedCtx map[string]interface{} - report := func(failure error, ctx map[string]interface{}) { - reportedFailure = failure - reportedCtx = ctx - } - - ops.RegisterReporter(report) - ops.SetGlobal("g", "g1") - op := ops.Begin("test_success").Set("a", 1).SetDynamic("b", func() interface{} { return 2 }) - defer op.End() - innerOp := op.Begin("inside") - innerOp.FailIf(nil) - innerOp.End() - - assert.Nil(t, reportedFailure) - expectedCtx := map[string]interface{}{ - "op": "inside", - "root_op": "test_success", - "g": "g1", - "a": 1, - "b": 2, - } - assert.Equal(t, expectedCtx, reportedCtx) -} - -func TestFailure(t *testing.T) { - var reportedFailure error - var reportedCtx map[string]interface{} - report := func(failure error, ctx map[string]interface{}) { - reportedFailure = failure - reportedCtx = ctx - } - - ops.RegisterReporter(report) - op := ops.Begin("test_failure") - var wg sync.WaitGroup - wg.Add(1) - op.Go(func() { - op.FailIf(errors.New("I failed").With("errorcontext", 5)) - wg.Done() - }) - wg.Wait() - op.End() - - assert.Contains(t, reportedFailure.Error(), "I failed") - assert.Equal(t, 5, reportedCtx["errorcontext"]) -} diff --git a/vendor/github.com/getlantern/stack/.travis.yml b/vendor/github.com/getlantern/stack/.travis.yml deleted file mode 100644 index 46a817090..000000000 --- a/vendor/github.com/getlantern/stack/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: go - -go: - - 1.0.3 - - 1.1.2 - - 1.2.2 - - 1.3.3 - - 1.4.3 - - 1.5.3 - - release - - tip diff --git a/vendor/github.com/getlantern/stack/README.md b/vendor/github.com/getlantern/stack/README.md deleted file mode 100644 index 1d12468c3..000000000 --- a/vendor/github.com/getlantern/stack/README.md +++ /dev/null @@ -1,35 +0,0 @@ -[![GoDoc](https://godoc.org/github.com/go-stack/stack?status.svg)](https://godoc.org/github.com/go-stack/stack) [![Go Report Card](https://goreportcard.com/badge/go-stack/stack)](https://goreportcard.com/report/go-stack/stack) - -# stack - -Package stack implements utilities to capture, manipulate, and format call -stacks. It provides a simpler API than package runtime. - -The implementation takes care of the minutia and special cases of interpreting -the program counter (pc) values returned by runtime.Callers. - -## Versioning - -Package stack publishes releases via [semver](http://semver.org/) compatible Git -tags prefixed with a single 'v'. The master branch always contains the latest -release. The develop branch contains unreleased commits. - -## Formatting - -Package stack's types implement fmt.Formatter, which provides a simple and -flexible way to declaratively configure formatting when used with logging or -error tracking packages. - -```go -func DoTheThing() { - c := stack.Caller(0) - log.Print(c) // "source.go:10" - log.Printf("%+v", c) // "pkg/path/source.go:10" - log.Printf("%n", c) // "DoTheThing" - - s := stack.Trace().TrimRuntime() - log.Print(s) // "[source.go:15 caller.go:42 main.go:14]" -} -``` - -See the docs for all of the supported formatting options. diff --git a/vendor/github.com/getlantern/stack/format_test.go b/vendor/github.com/getlantern/stack/format_test.go deleted file mode 100644 index 59360b54a..000000000 --- a/vendor/github.com/getlantern/stack/format_test.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build go1.2 - -package stack_test - -import ( - "fmt" - - "github.com/getlantern/stack" -) - -func Example_callFormat() { - logCaller("%+s") - logCaller("%v %[1]n()") - // Output: - // github.com/getlantern/stack/format_test.go - // format_test.go:13 Example_callFormat() -} - -func logCaller(format string) { - fmt.Printf(format+"\n", stack.Caller(1)) -} diff --git a/vendor/github.com/getlantern/stack/stack.go b/vendor/github.com/getlantern/stack/stack.go deleted file mode 100644 index 222deff7f..000000000 --- a/vendor/github.com/getlantern/stack/stack.go +++ /dev/null @@ -1,349 +0,0 @@ -// Package stack implements utilities to capture, manipulate, and format call -// stacks. It provides a simpler API than package runtime. -// -// The implementation takes care of the minutia and special cases of -// interpreting the program counter (pc) values returned by runtime.Callers. -// -// Package stack's types implement fmt.Formatter, which provides a simple and -// flexible way to declaratively configure formatting when used with logging -// or error tracking packages. -package stack - -import ( - "bytes" - "errors" - "fmt" - "io" - "path/filepath" - "runtime" - "strconv" - "strings" -) - -// Call records a single function invocation from a goroutine stack. -type Call struct { - fn *runtime.Func - pc uintptr -} - -// Caller returns a Call from the stack of the current goroutine. The argument -// skip is the number of stack frames to ascend, with 0 identifying the -// calling function. -func Caller(skip int) Call { - var pcs [2]uintptr - n := runtime.Callers(skip+1, pcs[:]) - - var c Call - - if n < 2 { - return c - } - - c.pc = pcs[1] - if runtime.FuncForPC(pcs[0]) != sigpanic { - c.pc-- - } - c.fn = runtime.FuncForPC(c.pc) - return c -} - -// String implements fmt.Stinger. It is equivalent to fmt.Sprintf("%v", c). -func (c Call) String() string { - return fmt.Sprint(c) -} - -// MarshalText implements encoding.TextMarshaler. It formats the Call the same -// as fmt.Sprintf("%v", c). -func (c Call) MarshalText() ([]byte, error) { - if c.fn == nil { - return nil, ErrNoFunc - } - buf := bytes.Buffer{} - fmt.Fprint(&buf, c) - return buf.Bytes(), nil -} - -// ErrNoFunc means that the Call has a nil *runtime.Func. The most likely -// cause is a Call with the zero value. -var ErrNoFunc = errors.New("no call stack information") - -// Format implements fmt.Formatter with support for the following verbs. -// -// %s source file -// %d line number -// %n function name -// %k package name -// %v equivalent to %s:%d -// -// It accepts the '+' and '#' flags for most of the verbs as follows. -// -// %+s path of source file relative to the compile time GOPATH -// %#s full path of source file -// %+n import path qualified function name -// %+k full package path -// %+v equivalent to %+s:%d -// %#v equivalent to %#s:%d -func (c Call) Format(s fmt.State, verb rune) { - if c.fn == nil { - fmt.Fprintf(s, "%%!%c(NOFUNC)", verb) - return - } - - switch verb { - case 's', 'v': - file, line := c.fn.FileLine(c.pc) - switch { - case s.Flag('#'): - // done - case s.Flag('+'): - // Here we want to get the source file path relative to the - // compile time GOPATH. As of Go 1.4.x there is no direct way to - // know the compiled GOPATH at runtime, but we can infer the - // number of path segments in the GOPATH. We note that fn.Name() - // returns the function name qualified by the import path, which - // does not include the GOPATH. Thus we can trim segments from the - // beginning of the file path until the number of path separators - // remaining is one more than the number of path separators in the - // function name. For example, given: - // - // GOPATH /home/user - // file /home/user/src/pkg/sub/file.go - // fn.Name() pkg/sub.Type.Method - // - // We want to produce: - // - // pkg/sub/file.go - // - // From this we can easily see that fn.Name() has one less path - // separator than our desired output. We count separators from the - // end of the file path until it finds two more than in the - // function name and then move one character forward to preserve - // the initial path segment without a leading separator. - const sep = "/" - goal := strings.Count(c.fn.Name(), sep) + 2 - pathCnt := 0 - i := len(file) - for pathCnt < goal { - i = strings.LastIndex(file[:i], sep) - if i == -1 { - i = -len(sep) - break - } - pathCnt++ - } - // get back to 0 or trim the leading seperator - file = file[i+len(sep):] - default: - const sep = "/" - if i := strings.LastIndex(file, sep); i != -1 { - file = file[i+len(sep):] - } - } - io.WriteString(s, file) - if verb == 'v' { - buf := [7]byte{':'} - s.Write(strconv.AppendInt(buf[:1], int64(line), 10)) - } - - case 'd': - _, line := c.fn.FileLine(c.pc) - buf := [6]byte{} - s.Write(strconv.AppendInt(buf[:0], int64(line), 10)) - - case 'n', 'k': - name := c.fn.Name() - var path, pkg string - if !s.Flag('+') || verb == 'k' { - const pathSep = "/" - if i := strings.LastIndex(name, pathSep); i != -1 { - path, name = name[:i], name[i+len(pathSep):] - } - const pkgSep = "." - if i := strings.Index(name, pkgSep); i != -1 { - pkg, name = name[:i], name[i+len(pkgSep):] - } - } - if verb == 'n' { - io.WriteString(s, name) - return - } - if s.Flag('+') && path != "" { - pkg = path + "/" + pkg - } - io.WriteString(s, pkg) - } -} - -// PC returns the program counter for this call frame; multiple frames may -// have the same PC value. -func (c Call) PC() uintptr { - return c.pc -} - -// name returns the import path qualified name of the function containing the -// call. -func (c Call) name() string { - if c.fn == nil { - return "???" - } - return c.fn.Name() -} - -func (c Call) file() string { - if c.fn == nil { - return "???" - } - file, _ := c.fn.FileLine(c.pc) - return file -} - -func (c Call) line() int { - if c.fn == nil { - return 0 - } - _, line := c.fn.FileLine(c.pc) - return line -} - -// CallStack records a sequence of function invocations from a goroutine -// stack. -type CallStack []Call - -// String implements fmt.Stinger. It is equivalent to fmt.Sprintf("%v", cs). -func (cs CallStack) String() string { - return fmt.Sprint(cs) -} - -var ( - openBracketBytes = []byte("[") - closeBracketBytes = []byte("]") - spaceBytes = []byte(" ") -) - -// MarshalText implements encoding.TextMarshaler. It formats the CallStack the -// same as fmt.Sprintf("%v", cs). -func (cs CallStack) MarshalText() ([]byte, error) { - buf := bytes.Buffer{} - buf.Write(openBracketBytes) - for i, pc := range cs { - if pc.fn == nil { - return nil, ErrNoFunc - } - if i > 0 { - buf.Write(spaceBytes) - } - fmt.Fprint(&buf, pc) - } - buf.Write(closeBracketBytes) - return buf.Bytes(), nil -} - -// Format implements fmt.Formatter by printing the CallStack as square brackes -// ([, ]) surrounding a space separated list of Calls each formatted with the -// supplied verb and options. -func (cs CallStack) Format(s fmt.State, verb rune) { - s.Write(openBracketBytes) - for i, pc := range cs { - if i > 0 { - s.Write(spaceBytes) - } - pc.Format(s, verb) - } - s.Write(closeBracketBytes) -} - -// findSigpanic intentionally executes faulting code to generate a stack trace -// containing an entry for runtime.sigpanic. -func findSigpanic() *runtime.Func { - var fn *runtime.Func - var p *int - func() int { - defer func() { - if p := recover(); p != nil { - var pcs [512]uintptr - n := runtime.Callers(2, pcs[:]) - for _, pc := range pcs[:n] { - f := runtime.FuncForPC(pc) - if f.Name() == "runtime.sigpanic" { - fn = f - break - } - } - } - }() - // intentional nil pointer dereference to trigger sigpanic - return *p - }() - return fn -} - -var sigpanic = findSigpanic() - -// Trace returns a CallStack for the current goroutine with element 0 -// identifying the calling function. -func Trace() CallStack { - var pcs [512]uintptr - n := runtime.Callers(2, pcs[:]) - cs := make([]Call, n) - - for i, pc := range pcs[:n] { - pcFix := pc - if i > 0 && cs[i-1].fn != sigpanic { - pcFix-- - } - cs[i] = Call{ - fn: runtime.FuncForPC(pcFix), - pc: pcFix, - } - } - - return cs -} - -// TrimBelow returns a slice of the CallStack with all entries below c -// removed. -func (cs CallStack) TrimBelow(c Call) CallStack { - for len(cs) > 0 && cs[0].pc != c.pc { - cs = cs[1:] - } - return cs -} - -// TrimAbove returns a slice of the CallStack with all entries above c -// removed. -func (cs CallStack) TrimAbove(c Call) CallStack { - for len(cs) > 0 && cs[len(cs)-1].pc != c.pc { - cs = cs[:len(cs)-1] - } - return cs -} - -var goroot string - -func init() { - goroot = filepath.ToSlash(runtime.GOROOT()) - if runtime.GOOS == "windows" { - goroot = strings.ToLower(goroot) - } -} - -func inGoroot(c Call) bool { - file := c.file() - if len(file) == 0 || file[0] == '?' { - return true - } - if runtime.GOOS == "windows" { - file = strings.ToLower(file) - } - return strings.HasPrefix(file, goroot) || strings.HasSuffix(file, "/_testmain.go") -} - -// TrimRuntime returns a slice of the CallStack with the topmost entries from -// the go runtime removed. It considers any calls originating from unknown -// files, files under GOROOT, or _testmain.go as part of the runtime. -func (cs CallStack) TrimRuntime() CallStack { - for len(cs) > 0 && inGoroot(cs[len(cs)-1]) { - cs = cs[:len(cs)-1] - } - return cs -} diff --git a/vendor/github.com/getlantern/stack/stack_test.go b/vendor/github.com/getlantern/stack/stack_test.go deleted file mode 100644 index 722f7c6dd..000000000 --- a/vendor/github.com/getlantern/stack/stack_test.go +++ /dev/null @@ -1,401 +0,0 @@ -package stack_test - -import ( - "fmt" - "io/ioutil" - "path" - "path/filepath" - "reflect" - "runtime" - "strings" - "testing" - - "github.com/getlantern/stack" -) - -const importPath = "github.com/getlantern/stack" - -type testType struct{} - -func (tt testType) testMethod() (c stack.Call, pc uintptr, file string, line int, ok bool) { - c = stack.Caller(0) - pc, file, line, ok = runtime.Caller(0) - line-- - return -} - -func TestCallFormat(t *testing.T) { - t.Parallel() - - c := stack.Caller(0) - pc, file, line, ok := runtime.Caller(0) - line-- - if !ok { - t.Fatal("runtime.Caller(0) failed") - } - relFile := path.Join(importPath, filepath.Base(file)) - - c2, pc2, file2, line2, ok2 := testType{}.testMethod() - if !ok2 { - t.Fatal("runtime.Caller(0) failed") - } - relFile2 := path.Join(importPath, filepath.Base(file2)) - fullFunc := runtime.FuncForPC(pc2).Name() - - data := []struct { - c stack.Call - desc string - fmt string - out string - }{ - {stack.Call{}, "error", "%s", "%!s(NOFUNC)"}, - - {c, "func", "%s", path.Base(file)}, - {c, "func", "%+s", relFile}, - {c, "func", "%#s", file}, - {c, "func", "%d", fmt.Sprint(line)}, - {c, "func", "%n", "TestCallFormat"}, - {c, "func", "%+n", runtime.FuncForPC(pc - 1).Name()}, - {c, "func", "%v", fmt.Sprint(path.Base(file), ":", line)}, - {c, "func", "%+v", fmt.Sprint(relFile, ":", line)}, - {c, "func", "%#v", fmt.Sprint(file, ":", line)}, - - {c2, "meth", "%s", path.Base(file2)}, - {c2, "meth", "%+s", relFile2}, - {c2, "meth", "%#s", file2}, - {c2, "meth", "%d", fmt.Sprint(line2)}, - {c2, "meth", "%n", "testType.testMethod"}, - {c2, "meth", "%+n", fullFunc}, - {c2, "meth", "%k", "stack_test"}, - {c2, "meth", "%+k", fullFunc[:strings.LastIndex(fullFunc, "/")+1] + "stack_test"}, - {c2, "meth", "%v", fmt.Sprint(path.Base(file2), ":", line2)}, - {c2, "meth", "%+v", fmt.Sprint(relFile2, ":", line2)}, - {c2, "meth", "%#v", fmt.Sprint(file2, ":", line2)}, - } - - for _, d := range data { - got := fmt.Sprintf(d.fmt, d.c) - if got != d.out { - t.Errorf("fmt.Sprintf(%q, Call(%s)) = %s, want %s", d.fmt, d.desc, got, d.out) - } - } -} - -func TestCallString(t *testing.T) { - t.Parallel() - - c := stack.Caller(0) - _, file, line, ok := runtime.Caller(0) - line-- - if !ok { - t.Fatal("runtime.Caller(0) failed") - } - - c2, _, file2, line2, ok2 := testType{}.testMethod() - if !ok2 { - t.Fatal("runtime.Caller(0) failed") - } - - data := []struct { - c stack.Call - desc string - out string - }{ - {stack.Call{}, "error", "%!v(NOFUNC)"}, - {c, "func", fmt.Sprint(path.Base(file), ":", line)}, - {c2, "meth", fmt.Sprint(path.Base(file2), ":", line2)}, - } - - for _, d := range data { - got := d.c.String() - if got != d.out { - t.Errorf("got %s, want %s", got, d.out) - } - } -} - -func TestCallMarshalText(t *testing.T) { - t.Parallel() - - c := stack.Caller(0) - _, file, line, ok := runtime.Caller(0) - line-- - if !ok { - t.Fatal("runtime.Caller(0) failed") - } - - c2, _, file2, line2, ok2 := testType{}.testMethod() - if !ok2 { - t.Fatal("runtime.Caller(0) failed") - } - - data := []struct { - c stack.Call - desc string - out []byte - err error - }{ - {stack.Call{}, "error", nil, stack.ErrNoFunc}, - {c, "func", []byte(fmt.Sprint(path.Base(file), ":", line)), nil}, - {c2, "meth", []byte(fmt.Sprint(path.Base(file2), ":", line2)), nil}, - } - - for _, d := range data { - text, err := d.c.MarshalText() - if got, want := err, d.err; got != want { - t.Errorf("%s: got err %v, want err %v", d.desc, got, want) - } - if got, want := text, d.out; !reflect.DeepEqual(got, want) { - t.Errorf("%s: got %s, want %s", d.desc, got, want) - } - } -} - -func TestCallStackString(t *testing.T) { - cs, line0 := getTrace(t) - _, file, line1, ok := runtime.Caller(0) - line1-- - if !ok { - t.Fatal("runtime.Caller(0) failed") - } - file = path.Base(file) - if got, want := cs.String(), fmt.Sprintf("[%s:%d %s:%d]", file, line0, file, line1); got != want { - t.Errorf("\n got %v\nwant %v", got, want) - } -} - -func TestCallStackMarshalText(t *testing.T) { - cs, line0 := getTrace(t) - _, file, line1, ok := runtime.Caller(0) - line1-- - if !ok { - t.Fatal("runtime.Caller(0) failed") - } - file = path.Base(file) - text, _ := cs.MarshalText() - if got, want := text, []byte(fmt.Sprintf("[%s:%d %s:%d]", file, line0, file, line1)); !reflect.DeepEqual(got, want) { - t.Errorf("\n got %v\nwant %v", got, want) - } -} -func getTrace(t *testing.T) (stack.CallStack, int) { - cs := stack.Trace().TrimRuntime() - _, _, line, ok := runtime.Caller(0) - line-- - if !ok { - t.Fatal("runtime.Caller(0) failed") - } - return cs, line -} - -func TestTrimAbove(t *testing.T) { - trace := trimAbove() - if got, want := len(trace), 2; got != want { - t.Errorf("got len(trace) == %v, want %v, trace: %n", got, want, trace) - } - if got, want := fmt.Sprintf("%n", trace[1]), "TestTrimAbove"; got != want { - t.Errorf("got %q, want %q", got, want) - } -} - -func trimAbove() stack.CallStack { - call := stack.Caller(1) - trace := stack.Trace() - return trace.TrimAbove(call) -} - -func TestTrimBelow(t *testing.T) { - trace := trimBelow() - if got, want := fmt.Sprintf("%n", trace[0]), "TestTrimBelow"; got != want { - t.Errorf("got %q, want %q", got, want) - } -} - -func trimBelow() stack.CallStack { - call := stack.Caller(1) - trace := stack.Trace() - return trace.TrimBelow(call) -} - -func TestTrimRuntime(t *testing.T) { - trace := stack.Trace().TrimRuntime() - if got, want := len(trace), 1; got != want { - t.Errorf("got len(trace) == %v, want %v, goroot: %q, trace: %#v", got, want, runtime.GOROOT(), trace) - } -} - -func BenchmarkCallVFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprint(ioutil.Discard, c) - } -} - -func BenchmarkCallPlusVFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprintf(ioutil.Discard, "%+v", c) - } -} - -func BenchmarkCallSharpVFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprintf(ioutil.Discard, "%#v", c) - } -} - -func BenchmarkCallSFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprintf(ioutil.Discard, "%s", c) - } -} - -func BenchmarkCallPlusSFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprintf(ioutil.Discard, "%+s", c) - } -} - -func BenchmarkCallSharpSFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprintf(ioutil.Discard, "%#s", c) - } -} - -func BenchmarkCallDFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprintf(ioutil.Discard, "%d", c) - } -} - -func BenchmarkCallNFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprintf(ioutil.Discard, "%n", c) - } -} - -func BenchmarkCallPlusNFmt(b *testing.B) { - c := stack.Caller(0) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fmt.Fprintf(ioutil.Discard, "%+n", c) - } -} - -func BenchmarkCaller(b *testing.B) { - for i := 0; i < b.N; i++ { - stack.Caller(0) - } -} - -func BenchmarkTrace(b *testing.B) { - for i := 0; i < b.N; i++ { - stack.Trace() - } -} - -func deepStack(depth int, b *testing.B) stack.CallStack { - if depth > 0 { - return deepStack(depth-1, b) - } - b.StartTimer() - s := stack.Trace() - return s -} - -func BenchmarkTrace10(b *testing.B) { - for i := 0; i < b.N; i++ { - b.StopTimer() - deepStack(10, b) - } -} - -func BenchmarkTrace50(b *testing.B) { - b.StopTimer() - for i := 0; i < b.N; i++ { - deepStack(50, b) - } -} - -func BenchmarkTrace100(b *testing.B) { - b.StopTimer() - for i := 0; i < b.N; i++ { - deepStack(100, b) - } -} - -//////////////// -// Benchmark functions followed by formatting -//////////////// - -func BenchmarkCallerAndVFmt(b *testing.B) { - for i := 0; i < b.N; i++ { - fmt.Fprint(ioutil.Discard, stack.Caller(0)) - } -} - -func BenchmarkTraceAndVFmt(b *testing.B) { - for i := 0; i < b.N; i++ { - fmt.Fprint(ioutil.Discard, stack.Trace()) - } -} - -func BenchmarkTrace10AndVFmt(b *testing.B) { - for i := 0; i < b.N; i++ { - b.StopTimer() - fmt.Fprint(ioutil.Discard, deepStack(10, b)) - } -} - -//////////////// -// Baseline against package runtime. -//////////////// - -func BenchmarkRuntimeCaller(b *testing.B) { - for i := 0; i < b.N; i++ { - runtime.Caller(0) - } -} - -func BenchmarkRuntimeCallerAndFmt(b *testing.B) { - for i := 0; i < b.N; i++ { - _, file, line, _ := runtime.Caller(0) - const sep = "/" - if i := strings.LastIndex(file, sep); i != -1 { - file = file[i+len(sep):] - } - fmt.Fprint(ioutil.Discard, file, ":", line) - } -} - -func BenchmarkFuncForPC(b *testing.B) { - pc, _, _, _ := runtime.Caller(0) - pc-- - b.ResetTimer() - for i := 0; i < b.N; i++ { - runtime.FuncForPC(pc) - } -} - -func BenchmarkFuncFileLine(b *testing.B) { - pc, _, _, _ := runtime.Caller(0) - pc-- - fn := runtime.FuncForPC(pc) - b.ResetTimer() - for i := 0; i < b.N; i++ { - fn.FileLine(pc) - } -} diff --git a/vendor/github.com/getlantern/stack/stackinternal_test.go b/vendor/github.com/getlantern/stack/stackinternal_test.go deleted file mode 100644 index 902b19576..000000000 --- a/vendor/github.com/getlantern/stack/stackinternal_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package stack - -import ( - "runtime" - "testing" -) - -func TestFindSigpanic(t *testing.T) { - t.Parallel() - sp := findSigpanic() - if got, want := sp.Name(), "runtime.sigpanic"; got != want { - t.Errorf("got == %v, want == %v", got, want) - } -} - -func TestCaller(t *testing.T) { - t.Parallel() - - c := Caller(0) - _, file, line, ok := runtime.Caller(0) - line-- - if !ok { - t.Fatal("runtime.Caller(0) failed") - } - - if got, want := c.file(), file; got != want { - t.Errorf("got file == %v, want file == %v", got, want) - } - - if got, want := c.line(), line; got != want { - t.Errorf("got line == %v, want line == %v", got, want) - } -} - -type fholder struct { - f func() CallStack -} - -func (fh *fholder) labyrinth() CallStack { - for { - return fh.f() - } -} - -func TestTrace(t *testing.T) { - t.Parallel() - - fh := fholder{ - f: func() CallStack { - cs := Trace() - return cs - }, - } - - cs := fh.labyrinth() - - lines := []int{50, 41, 55} - - for i, line := range lines { - if got, want := cs[i].line(), line; got != want { - t.Errorf("got line[%d] == %v, want line[%d] == %v", i, got, i, want) - } - } -} diff --git a/vendor/github.com/getlantern/systray/.gitignore b/vendor/github.com/getlantern/systray/.gitignore deleted file mode 100644 index 6fb7ba948..000000000 --- a/vendor/github.com/getlantern/systray/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -example/example -*~ -*.swp -*.exe -Release -Debug -*.sdf -dll/systray_unsigned.dll diff --git a/vendor/github.com/getlantern/systray/README.md b/vendor/github.com/getlantern/systray/README.md deleted file mode 100644 index b4f2c1a45..000000000 --- a/vendor/github.com/getlantern/systray/README.md +++ /dev/null @@ -1,57 +0,0 @@ -Package systray is a cross platfrom Go library to place an icon and menu in the notification area. -Tested on Windows 8, Mac OSX, Ubuntu 14.10 and Debian 7.6. - -## Usage -```go -func main() { - // Should be called at the very beginning of main(). - systray.Run(onReady) -} - -func onReady() { - systray.SetIcon(icon.Data) - systray.SetTitle("Awesome App") - systray.SetTooltip("Pretty awesome超级棒") - mQuit := systray.AddMenuItem("Quit", "Quit the whole app") -} -``` -Menu item can be checked and / or disabled. Methods except `Run()` can be invoked from any goroutine. See demo code under `example` folder. - -## Platform specific concerns - -### Linux - -```sh -sudo apt-get install libgtk-3-dev libappindicator3-dev -``` -Checked menu item not implemented on Linux yet. - -### Windows - -Use the Visual Studio solution to build systray.dll. Make sure to target Windows -XP and build for Release (not Debug). Put the resulting dll in -`dll/systray_unsigned.dll` and then run `./signdll.bash` to sign it. Check the -resulting dll into git at Git at dll/systray.dll and run ./embeddll.bash to -generate the systraydll_windows.go file. - -The solution is configured to build with platform toolset v90 and dynamic -linking to save on size and support Windows XP. To get platform toolset v90, -you need to install Visual Studio 2008 (express edition is okay). You can -build with a more recent Visual Studio, you just need the old one for the -toolset. - -## Try - -Under `example` folder. -Place tray icon under `icon`, and use `make_icon.bat` or `make_icon.sh`, whichever suit for your os, to convert the icon to byte array. -Your icon should be .ico file under Windows, whereas .ico, .jpg and .png is supported on other platform. - -```sh -go get -go run main.go -``` - -## Credits - -- https://github.com/xilp/systray -- https://github.com/cratonica/trayhost diff --git a/vendor/github.com/getlantern/systray/dll/systray386.dll b/vendor/github.com/getlantern/systray/dll/systray386.dll deleted file mode 100644 index a6f3cf3cb..000000000 Binary files a/vendor/github.com/getlantern/systray/dll/systray386.dll and /dev/null differ diff --git a/vendor/github.com/getlantern/systray/dll/systrayamd64.dll b/vendor/github.com/getlantern/systray/dll/systrayamd64.dll deleted file mode 100644 index f7061f4fb..000000000 Binary files a/vendor/github.com/getlantern/systray/dll/systrayamd64.dll and /dev/null differ diff --git a/vendor/github.com/getlantern/systray/embeddll.bash b/vendor/github.com/getlantern/systray/embeddll.bash deleted file mode 100755 index 7efbd7b29..000000000 --- a/vendor/github.com/getlantern/systray/embeddll.bash +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -############################################################################### -# -# This script regenerates the source file that embeds systray.dll -# -############################################################################### - -go get github.com/jteeuwen/go-bindata/go-bindata -go-bindata -nomemcopy -nocompress -pkg systray -prefix dll -o systraydll_windows.go dll \ No newline at end of file diff --git a/vendor/github.com/getlantern/systray/example/icon/icon.png b/vendor/github.com/getlantern/systray/example/icon/icon.png deleted file mode 100644 index 420c61877..000000000 Binary files a/vendor/github.com/getlantern/systray/example/icon/icon.png and /dev/null differ diff --git a/vendor/github.com/getlantern/systray/example/icon/iconunix.go b/vendor/github.com/getlantern/systray/example/icon/iconunix.go deleted file mode 100644 index eb80cb90f..000000000 --- a/vendor/github.com/getlantern/systray/example/icon/iconunix.go +++ /dev/null @@ -1,196 +0,0 @@ -//+build linux darwin - -// File generated by 2goarray (http://github.com/cratonica/2goarray) - -package icon - -var Data []byte = []byte { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, - 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, - 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, 0xf4, 0x00, 0x00, 0x00, - 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, - 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, - 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xc9, 0x65, 0x3c, 0x00, 0x00, - 0x03, 0x66, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, - 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3f, 0x78, 0x70, 0x61, 0x63, 0x6b, 0x65, - 0x74, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x3d, 0x22, 0xef, 0xbb, 0xbf, - 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x57, 0x35, 0x4d, 0x30, 0x4d, 0x70, - 0x43, 0x65, 0x68, 0x69, 0x48, 0x7a, 0x72, 0x65, 0x53, 0x7a, 0x4e, 0x54, - 0x63, 0x7a, 0x6b, 0x63, 0x39, 0x64, 0x22, 0x3f, 0x3e, 0x20, 0x3c, 0x78, - 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, - 0x6e, 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, - 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, - 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x41, 0x64, 0x6f, 0x62, 0x65, - 0x20, 0x58, 0x4d, 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, - 0x30, 0x2d, 0x63, 0x30, 0x36, 0x30, 0x20, 0x36, 0x31, 0x2e, 0x31, 0x33, - 0x34, 0x37, 0x37, 0x37, 0x2c, 0x20, 0x32, 0x30, 0x31, 0x30, 0x2f, 0x30, - 0x32, 0x2f, 0x31, 0x32, 0x2d, 0x31, 0x37, 0x3a, 0x33, 0x32, 0x3a, 0x30, - 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x3e, 0x20, - 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, - 0x6e, 0x73, 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, - 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, - 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, - 0x6e, 0x73, 0x23, 0x22, 0x3e, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, - 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x20, - 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x4d, 0x4d, 0x3d, - 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, - 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x6d, 0x6d, 0x2f, 0x22, 0x20, 0x78, 0x6d, - 0x6c, 0x6e, 0x73, 0x3a, 0x73, 0x74, 0x52, 0x65, 0x66, 0x3d, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, - 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, - 0x2e, 0x30, 0x2f, 0x73, 0x54, 0x79, 0x70, 0x65, 0x2f, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x23, 0x22, 0x20, 0x78, - 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, - 0x30, 0x2f, 0x22, 0x20, 0x78, 0x6d, 0x70, 0x4d, 0x4d, 0x3a, 0x4f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x49, 0x44, 0x3d, 0x22, 0x78, 0x6d, 0x70, 0x2e, 0x64, 0x69, - 0x64, 0x3a, 0x36, 0x37, 0x32, 0x34, 0x42, 0x45, 0x31, 0x35, 0x45, 0x44, - 0x32, 0x30, 0x36, 0x38, 0x31, 0x31, 0x38, 0x38, 0x43, 0x36, 0x46, 0x32, - 0x38, 0x31, 0x35, 0x44, 0x41, 0x33, 0x43, 0x35, 0x35, 0x35, 0x22, 0x20, - 0x78, 0x6d, 0x70, 0x4d, 0x4d, 0x3a, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x49, 0x44, 0x3d, 0x22, 0x78, 0x6d, 0x70, 0x2e, 0x64, 0x69, - 0x64, 0x3a, 0x41, 0x33, 0x42, 0x34, 0x46, 0x42, 0x36, 0x36, 0x33, 0x41, - 0x41, 0x38, 0x31, 0x31, 0x45, 0x32, 0x42, 0x32, 0x43, 0x41, 0x39, 0x37, - 0x42, 0x44, 0x33, 0x34, 0x34, 0x31, 0x45, 0x46, 0x33, 0x32, 0x22, 0x20, - 0x78, 0x6d, 0x70, 0x4d, 0x4d, 0x3a, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x49, 0x44, 0x3d, 0x22, 0x78, 0x6d, 0x70, 0x2e, 0x69, 0x69, - 0x64, 0x3a, 0x41, 0x33, 0x42, 0x34, 0x46, 0x42, 0x36, 0x35, 0x33, 0x41, - 0x41, 0x38, 0x31, 0x31, 0x45, 0x32, 0x42, 0x32, 0x43, 0x41, 0x39, 0x37, - 0x42, 0x44, 0x33, 0x34, 0x34, 0x31, 0x45, 0x46, 0x33, 0x32, 0x22, 0x20, - 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3d, 0x22, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x50, - 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20, 0x43, 0x53, 0x35, - 0x20, 0x4d, 0x61, 0x63, 0x69, 0x6e, 0x74, 0x6f, 0x73, 0x68, 0x22, 0x3e, - 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x4d, 0x4d, 0x3a, 0x44, 0x65, 0x72, 0x69, - 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x73, 0x74, 0x52, 0x65, - 0x66, 0x3a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x44, - 0x3d, 0x22, 0x78, 0x6d, 0x70, 0x2e, 0x69, 0x69, 0x64, 0x3a, 0x45, 0x36, - 0x38, 0x31, 0x34, 0x43, 0x36, 0x41, 0x45, 0x45, 0x32, 0x30, 0x36, 0x38, - 0x31, 0x31, 0x38, 0x38, 0x43, 0x36, 0x46, 0x32, 0x38, 0x31, 0x35, 0x44, - 0x41, 0x33, 0x43, 0x35, 0x35, 0x35, 0x22, 0x20, 0x73, 0x74, 0x52, 0x65, - 0x66, 0x3a, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, - 0x3d, 0x22, 0x78, 0x6d, 0x70, 0x2e, 0x64, 0x69, 0x64, 0x3a, 0x36, 0x37, - 0x32, 0x34, 0x42, 0x45, 0x31, 0x35, 0x45, 0x44, 0x32, 0x30, 0x36, 0x38, - 0x31, 0x31, 0x38, 0x38, 0x43, 0x36, 0x46, 0x32, 0x38, 0x31, 0x35, 0x44, - 0x41, 0x33, 0x43, 0x35, 0x35, 0x35, 0x22, 0x2f, 0x3e, 0x20, 0x3c, 0x2f, - 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x3e, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, - 0x44, 0x46, 0x3e, 0x20, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, - 0x65, 0x74, 0x61, 0x3e, 0x20, 0x3c, 0x3f, 0x78, 0x70, 0x61, 0x63, 0x6b, - 0x65, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x3d, 0x22, 0x72, 0x22, 0x3f, 0x3e, - 0x5d, 0xed, 0x35, 0xe2, 0x00, 0x00, 0x04, 0xee, 0x49, 0x44, 0x41, 0x54, - 0x78, 0xda, 0xc4, 0x57, 0xcf, 0x6f, 0x55, 0x45, 0x18, 0x3d, 0xf3, 0xe3, - 0xfe, 0xea, 0x7b, 0xaf, 0xa5, 0x6d, 0x0a, 0xd8, 0x34, 0xbe, 0x16, 0x83, - 0x69, 0x8c, 0x2e, 0x04, 0xe2, 0x86, 0xb8, 0x70, 0xe1, 0x06, 0x35, 0x18, - 0x13, 0x5d, 0x60, 0x8c, 0xd1, 0x68, 0xe2, 0xca, 0xb8, 0x33, 0x31, 0xf1, - 0x6f, 0x70, 0x67, 0x5c, 0xb1, 0x62, 0xe1, 0x46, 0x42, 0x8c, 0x0b, 0xe3, - 0x46, 0x34, 0x25, 0x11, 0x41, 0x14, 0xa4, 0x24, 0xa4, 0x08, 0x58, 0x0a, - 0x29, 0x14, 0x0a, 0x6d, 0xe9, 0xeb, 0xbb, 0xef, 0xce, 0x9d, 0xf1, 0xcc, - 0xbd, 0xaf, 0xa5, 0x44, 0x63, 0x49, 0xee, 0x4b, 0x78, 0xc9, 0xf7, 0xee, - 0x9d, 0x3b, 0x33, 0x77, 0xce, 0x77, 0xbe, 0xf3, 0x7d, 0x33, 0x57, 0x38, - 0xe7, 0xf0, 0x38, 0x7f, 0x7a, 0xab, 0x01, 0xe2, 0xd9, 0x37, 0xff, 0xeb, - 0xb1, 0xa2, 0x7d, 0x46, 0xdb, 0xeb, 0x87, 0xd0, 0x8e, 0xd3, 0xbe, 0xf8, - 0xd7, 0x28, 0x6b, 0xe1, 0x2e, 0x7c, 0xf3, 0xbf, 0xef, 0x97, 0x5b, 0x42, - 0x34, 0x06, 0xf0, 0x2c, 0x6d, 0x36, 0xe0, 0x43, 0xda, 0x88, 0x90, 0xf2, - 0x90, 0xea, 0x6f, 0xbc, 0x0b, 0x21, 0x9e, 0x67, 0xfb, 0x8d, 0xa2, 0xcf, - 0x76, 0xc7, 0x70, 0x5e, 0xff, 0x40, 0x7f, 0x75, 0x06, 0xc6, 0x27, 0x9a, - 0xb8, 0x76, 0x63, 0xbe, 0x70, 0x53, 0xf0, 0x2f, 0xe7, 0x02, 0xd6, 0xda, - 0x71, 0x36, 0xaf, 0xd1, 0x0e, 0xcb, 0x38, 0x16, 0x5c, 0xf4, 0x7a, 0xbe, - 0xbc, 0xd2, 0x14, 0x71, 0x04, 0x19, 0x68, 0xf8, 0xb0, 0x4a, 0xda, 0x2e, - 0xce, 0xad, 0x0c, 0x60, 0xf7, 0x53, 0xbb, 0x90, 0x87, 0x11, 0x76, 0x8f, - 0xee, 0x40, 0xa8, 0x35, 0xfe, 0x9a, 0xbf, 0x35, 0x36, 0x73, 0xf9, 0xea, - 0x24, 0xd2, 0xf4, 0x20, 0x5d, 0x2d, 0xbc, 0x15, 0x49, 0x0c, 0x1d, 0x86, - 0xdf, 0x09, 0x25, 0x7f, 0x80, 0x14, 0xd3, 0x8e, 0x20, 0x93, 0x30, 0x44, - 0xa3, 0xd1, 0xd8, 0x12, 0x80, 0xdc, 0x3a, 0x02, 0x06, 0xa4, 0xba, 0xb0, - 0x5a, 0x12, 0x2b, 0x2e, 0xf4, 0x35, 0xb4, 0x3e, 0x58, 0x84, 0xde, 0xb3, - 0x91, 0xa6, 0x64, 0x86, 0xf7, 0x4a, 0xbe, 0x4a, 0xcf, 0x8f, 0xe4, 0x26, - 0x0f, 0x42, 0xa5, 0xf0, 0xcc, 0xe8, 0x13, 0x50, 0xfe, 0x79, 0x65, 0x11, - 0xf2, 0x1d, 0x86, 0x62, 0x9a, 0x9a, 0xbe, 0x88, 0xa7, 0x77, 0x8e, 0x04, - 0x9d, 0x34, 0x1b, 0x45, 0xda, 0x81, 0xf7, 0xde, 0x53, 0x9d, 0x77, 0x32, - 0x04, 0x49, 0x82, 0x88, 0x1e, 0x67, 0xb9, 0xa9, 0x37, 0xe2, 0x44, 0x3c, - 0x39, 0x3c, 0x84, 0xa8, 0x1b, 0x8a, 0xca, 0x00, 0xba, 0xbf, 0x28, 0x35, - 0xe6, 0xc0, 0x9f, 0x17, 0x2f, 0x7d, 0x20, 0xad, 0x6d, 0xc2, 0xe4, 0xd8, - 0x10, 0x45, 0x10, 0x20, 0xd0, 0x01, 0xfa, 0x09, 0xa2, 0x16, 0x85, 0x13, - 0xf5, 0x28, 0x3a, 0x1a, 0x28, 0x75, 0x98, 0x4b, 0x7f, 0xcf, 0xde, 0x56, - 0xe5, 0x10, 0xf0, 0xf7, 0x36, 0x6d, 0x4a, 0x0a, 0x71, 0x14, 0x4a, 0x1d, - 0xb0, 0x7e, 0xce, 0x3a, 0xb5, 0xbc, 0x2a, 0xea, 0x22, 0x50, 0x92, 0x11, - 0x90, 0xd0, 0x8a, 0xdc, 0x0b, 0xbc, 0xc2, 0x1e, 0x9f, 0x7b, 0xbf, 0xd0, - 0x3e, 0xea, 0x05, 0x80, 0x8f, 0x69, 0xfb, 0x7c, 0x76, 0x81, 0x8e, 0x23, - 0x75, 0xa5, 0x75, 0x31, 0x68, 0x0f, 0x80, 0x66, 0xac, 0x44, 0x9a, 0x09, - 0x38, 0x5b, 0xbe, 0x92, 0xdd, 0xcf, 0xd1, 0xde, 0xab, 0x1c, 0x82, 0x95, - 0x54, 0xdf, 0x58, 0x5a, 0xe3, 0xab, 0x3a, 0x0e, 0xf5, 0xc8, 0x61, 0x72, - 0x4c, 0x53, 0x5c, 0x0e, 0x27, 0x67, 0xb2, 0x62, 0x76, 0x28, 0x55, 0x51, - 0x97, 0xf6, 0x8c, 0x4b, 0xf4, 0x45, 0xc0, 0xad, 0x7b, 0xe4, 0xbd, 0x23, - 0xb0, 0xda, 0x21, 0x51, 0x10, 0x57, 0x2a, 0x03, 0x38, 0xb4, 0xf7, 0xef, - 0x99, 0xe0, 0x85, 0x35, 0x34, 0x87, 0x15, 0x26, 0x77, 0x0e, 0xa3, 0x39, - 0x5e, 0x73, 0xc7, 0x7e, 0x5a, 0xc5, 0x5b, 0x9f, 0xcf, 0x09, 0xd4, 0x15, - 0x19, 0x50, 0x94, 0x84, 0xc4, 0xfb, 0x2f, 0x25, 0x78, 0x6d, 0x9f, 0xc4, - 0xed, 0x85, 0x0c, 0x73, 0xf7, 0x52, 0xcc, 0x2e, 0x38, 0x5c, 0x5f, 0x74, - 0xe7, 0x2a, 0x03, 0xf8, 0xe4, 0xe5, 0x9b, 0xe7, 0xa0, 0xb7, 0xd1, 0xc9, - 0x41, 0x0a, 0xbf, 0x8f, 0x2e, 0xf7, 0x09, 0xa9, 0x38, 0x4d, 0xcc, 0x16, - 0x9e, 0xfb, 0xb0, 0x07, 0x5a, 0x50, 0x8b, 0x75, 0x48, 0x1d, 0x61, 0x64, - 0xb0, 0x8d, 0xed, 0x43, 0x6d, 0xec, 0x99, 0xa0, 0xfe, 0x4c, 0x6b, 0xba, - 0x32, 0x80, 0xd4, 0xec, 0xb8, 0x2c, 0x5c, 0x9d, 0x45, 0xbd, 0x21, 0x21, - 0x6b, 0x2c, 0x46, 0x35, 0xa6, 0x9d, 0x7d, 0xa0, 0x01, 0x0a, 0x30, 0x24, - 0x0b, 0x51, 0x5c, 0x67, 0x23, 0x41, 0x26, 0x42, 0x6a, 0xc5, 0x9b, 0x36, - 0x70, 0xe1, 0xb5, 0xb0, 0x72, 0x1d, 0x08, 0x86, 0x66, 0xa1, 0xe2, 0x25, - 0xe8, 0x81, 0x41, 0xa1, 0x6a, 0x64, 0xa0, 0x1f, 0x41, 0xdc, 0x59, 0xef, - 0xa5, 0xfa, 0x15, 0x42, 0x0f, 0xa2, 0x00, 0xe0, 0x59, 0x08, 0xe0, 0xf8, - 0xcc, 0x09, 0x71, 0x9b, 0x20, 0x66, 0xab, 0xd7, 0x01, 0x99, 0xdc, 0xa4, - 0xe7, 0x57, 0x84, 0x6e, 0x0c, 0xd2, 0x98, 0xf7, 0x83, 0xf4, 0x76, 0x6d, - 0x23, 0x7f, 0x7c, 0x0a, 0xfa, 0x10, 0xc4, 0x31, 0xfb, 0x14, 0x37, 0x1f, - 0x4d, 0xf1, 0x51, 0x13, 0xac, 0x42, 0x97, 0x9d, 0x50, 0x8b, 0xd5, 0x2b, - 0x61, 0x30, 0x90, 0x41, 0x86, 0x97, 0xe8, 0xfd, 0x9e, 0x02, 0x80, 0xda, - 0x46, 0x6f, 0x57, 0x8b, 0x52, 0xe0, 0x33, 0xd3, 0xe7, 0x3f, 0x0b, 0x0f, - 0xa2, 0x64, 0x80, 0x8d, 0x3a, 0x84, 0x66, 0x85, 0x2c, 0xc2, 0x93, 0xcf, - 0x08, 0x17, 0xd9, 0xea, 0x75, 0x40, 0x51, 0x78, 0x32, 0xfa, 0x83, 0x61, - 0x80, 0xf0, 0xf7, 0x5c, 0x24, 0x8c, 0x06, 0x20, 0x65, 0x39, 0xd5, 0xd7, - 0xfb, 0x52, 0x03, 0x04, 0xa7, 0xfd, 0xd8, 0x84, 0xe0, 0x22, 0xee, 0x1d, - 0xd1, 0x19, 0x7f, 0xad, 0xce, 0x80, 0xf2, 0x2f, 0x91, 0x67, 0x79, 0xe3, - 0xe9, 0xf0, 0x60, 0x10, 0x84, 0x0d, 0x36, 0x65, 0xb1, 0x1f, 0x48, 0xd1, - 0x65, 0x20, 0x68, 0xa0, 0x18, 0x23, 0x03, 0x7f, 0x65, 0x47, 0x78, 0x1e, - 0xc2, 0x55, 0xdf, 0x0d, 0xfd, 0x82, 0x7c, 0xe9, 0x79, 0xde, 0x2d, 0x95, - 0xdb, 0xaf, 0x45, 0x18, 0xf8, 0xf4, 0x2b, 0xa7, 0x7a, 0x22, 0x22, 0xb6, - 0x83, 0x90, 0x0b, 0x93, 0xfb, 0x32, 0x39, 0xe4, 0x02, 0x41, 0x9c, 0x2f, - 0xc0, 0xf4, 0xa0, 0x14, 0x7b, 0x4f, 0xe7, 0xe0, 0xb2, 0x0b, 0xb0, 0x54, - 0x7f, 0xbe, 0x46, 0x00, 0xe9, 0x03, 0x00, 0x3e, 0x04, 0xdc, 0xf9, 0x22, - 0xc5, 0xca, 0xc8, 0x7e, 0xe7, 0x7c, 0xbd, 0xce, 0x09, 0x58, 0x2c, 0x6c, - 0xe4, 0x6a, 0x25, 0x00, 0x8e, 0x2f, 0x76, 0xc6, 0x72, 0xe3, 0x3f, 0xed, - 0xf2, 0x55, 0x96, 0xe4, 0x65, 0xc4, 0xaa, 0xc5, 0xb8, 0xcb, 0x82, 0x10, - 0x81, 0x32, 0x0b, 0x22, 0xc1, 0xcc, 0x30, 0x34, 0xdb, 0x26, 0x88, 0xec, - 0xd7, 0x62, 0x2f, 0x76, 0xb6, 0x3a, 0x00, 0x97, 0x67, 0xa5, 0x99, 0xd6, - 0x94, 0x33, 0xcb, 0x04, 0x70, 0x17, 0x7d, 0x62, 0x85, 0x27, 0x9e, 0x2e, - 0x80, 0x42, 0x84, 0xac, 0x07, 0xee, 0x3e, 0x01, 0xac, 0x70, 0x6c, 0xcb, - 0x33, 0x71, 0x82, 0x13, 0x50, 0x58, 0xe5, 0x3a, 0x60, 0x56, 0xd7, 0xa1, - 0x9c, 0x76, 0xb6, 0x73, 0x1f, 0xc2, 0xd4, 0x7d, 0x75, 0xeb, 0x5b, 0x07, - 0x00, 0x0f, 0x80, 0xd9, 0x60, 0xb9, 0xb8, 0x3f, 0xc0, 0x9a, 0xb5, 0x3b, - 0x44, 0x71, 0xa6, 0x67, 0xc7, 0x72, 0x97, 0xaf, 0xac, 0xdf, 0x5e, 0x45, - 0xee, 0xce, 0x5a, 0xb4, 0xf7, 0x2b, 0xab, 0x91, 0x6c, 0xe8, 0x8b, 0x00, - 0x28, 0x7a, 0x91, 0x2f, 0x77, 0x99, 0x4a, 0x7f, 0x23, 0xb1, 0x37, 0x7a, - 0x06, 0x00, 0xd9, 0xbd, 0x8d, 0x53, 0xbe, 0x3f, 0x98, 0x38, 0xdb, 0xda, - 0xaf, 0x84, 0x46, 0xac, 0x5d, 0xa9, 0x7a, 0x86, 0x40, 0x4b, 0x02, 0x30, - 0x4b, 0x3c, 0x2d, 0xb3, 0xfc, 0x5b, 0x73, 0xbc, 0xa7, 0x1f, 0x26, 0x96, - 0x9e, 0x6d, 0xa2, 0xe3, 0x47, 0x61, 0xe5, 0xa7, 0x42, 0x05, 0x3c, 0x03, - 0x5a, 0x94, 0x25, 0xcf, 0x33, 0xc0, 0xfb, 0x9c, 0x59, 0x9a, 0x53, 0xac, - 0xce, 0xfd, 0xfc, 0x28, 0xea, 0x7f, 0xf4, 0x10, 0x64, 0xf3, 0x9b, 0x9b, - 0xa7, 0xb8, 0xc9, 0xcc, 0x91, 0x81, 0xb1, 0x7a, 0x68, 0x4a, 0x00, 0xc2, - 0xef, 0x86, 0x06, 0x8a, 0xa1, 0xe2, 0xfa, 0x97, 0xa8, 0x86, 0xdf, 0x7b, - 0xca, 0x80, 0xcb, 0x16, 0x36, 0x37, 0x17, 0x73, 0x67, 0x4e, 0xf2, 0x14, - 0x34, 0x56, 0x8f, 0x92, 0xf2, 0x7c, 0x40, 0x6f, 0x7d, 0x0d, 0x10, 0xf9, - 0x5d, 0x8e, 0x75, 0x27, 0x18, 0x8c, 0x56, 0x6f, 0x01, 0x98, 0xf9, 0x87, - 0xdb, 0xce, 0x1c, 0x81, 0x69, 0xbf, 0x58, 0x8b, 0x9b, 0xdb, 0x81, 0x7a, - 0x91, 0xc9, 0xa1, 0x6c, 0x51, 0x03, 0x77, 0xce, 0xb8, 0x5c, 0x7f, 0xe5, - 0x8a, 0xcf, 0xc6, 0x1e, 0x02, 0x78, 0x38, 0x9e, 0xfe, 0xde, 0x1c, 0x83, - 0x5d, 0x38, 0x55, 0x0b, 0x87, 0x5f, 0x67, 0xfb, 0x1d, 0x3e, 0x68, 0x2b, - 0x61, 0xbe, 0x84, 0x6b, 0x7f, 0xeb, 0x50, 0x6b, 0x97, 0x63, 0x1e, 0xfd, - 0x8b, 0x5b, 0x3c, 0xee, 0xcf, 0xf3, 0x7f, 0x04, 0x18, 0x00, 0xe0, 0x6e, - 0xdd, 0x63, 0x24, 0x57, 0x80, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, -} - diff --git a/vendor/github.com/getlantern/systray/example/icon/iconwin.go b/vendor/github.com/getlantern/systray/example/icon/iconwin.go deleted file mode 100644 index 80203eaea..000000000 --- a/vendor/github.com/getlantern/systray/example/icon/iconwin.go +++ /dev/null @@ -1,366 +0,0 @@ -//+build windows - -// File generated by 2goarray v0.1.0 (http://github.com/cratonica/2goarray) - -package icon - -var Data []byte = []byte{ - 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x00, 0xa8, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x09, 0xc6, 0xf5, 0x1b, 0x34, 0x69, 0x66, 0x6b, 0x5a, 0x24, - 0x00, 0xc8, 0x8a, 0x5a, 0x30, 0xc0, 0x7a, 0x88, 0x7d, 0x56, 0x40, 0xbf, - 0xdf, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xc6, 0xf2, 0x50, 0x22, 0xcf, - 0xfe, 0xe9, 0x42, 0x64, 0x5e, 0xff, 0x5b, 0x25, 0x00, 0xff, 0x8b, 0x5b, - 0x30, 0xff, 0x7f, 0x8a, 0x7b, 0xff, 0x5d, 0xd6, 0xfd, 0xcd, 0x5e, 0xd0, - 0xf5, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x43, 0xc9, 0xf4, 0xac, 0x46, 0xd4, 0xff, 0xff, 0x4f, 0x5c, - 0x53, 0xff, 0x59, 0x25, 0x00, 0xff, 0x89, 0x5b, 0x30, 0xff, 0x86, 0x88, - 0x75, 0xff, 0x71, 0xdb, 0xfe, 0xff, 0x6f, 0xd3, 0xf7, 0x9e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xc6, 0xf1, 0x12, 0x5c, 0xd1, - 0xf7, 0xe3, 0x61, 0xd8, 0xfc, 0xff, 0x57, 0x55, 0x47, 0xff, 0x58, 0x26, - 0x00, 0xff, 0x88, 0x5b, 0x30, 0xff, 0x8b, 0x85, 0x6e, 0xff, 0x82, 0xde, - 0xfd, 0xff, 0x7f, 0xd8, 0xf7, 0xd9, 0x7f, 0xcc, 0xe5, 0x0a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6f, 0xd4, 0xf4, 0x47, 0x73, 0xd7, 0xfa, 0xff, 0x78, 0xda, - 0xf9, 0xff, 0x5b, 0x4f, 0x3b, 0xff, 0x57, 0x27, 0x00, 0xff, 0x86, 0x5a, - 0x30, 0xff, 0x8f, 0x81, 0x68, 0xff, 0x93, 0xe1, 0xfa, 0xff, 0x8e, 0xdd, - 0xfa, 0xfd, 0x8a, 0xd8, 0xf6, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xd8, - 0xf7, 0x88, 0x87, 0xdc, 0xfc, 0xff, 0x8b, 0xdd, 0xf8, 0xff, 0x5d, 0x49, - 0x34, 0xff, 0x56, 0x28, 0x00, 0xff, 0x85, 0x5a, 0x30, 0xff, 0x91, 0x7e, - 0x62, 0xff, 0xa2, 0xe4, 0xfa, 0xff, 0x9e, 0xe2, 0xfb, 0xff, 0x98, 0xdd, - 0xf6, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x02, 0x90, 0xdc, 0xf7, 0xc4, 0x9a, 0xe3, - 0xfd, 0xff, 0x9e, 0xe0, 0xf5, 0xff, 0x5e, 0x45, 0x2c, 0xff, 0x55, 0x29, - 0x00, 0xff, 0x84, 0x59, 0x2f, 0xff, 0x92, 0x7c, 0x5e, 0xff, 0xb1, 0xe8, - 0xf9, 0xff, 0xac, 0xe8, 0xfd, 0xff, 0xa4, 0xe1, 0xf7, 0xb9, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0xd9, - 0xf7, 0x22, 0xa0, 0xe1, 0xf8, 0xf3, 0xad, 0xe9, 0xff, 0xff, 0xad, 0xe2, - 0xf2, 0xff, 0x5e, 0x40, 0x23, 0xff, 0x55, 0x29, 0x00, 0xff, 0x83, 0x59, - 0x2f, 0xff, 0x93, 0x79, 0x58, 0xff, 0xbf, 0xeb, 0xf8, 0xff, 0xbb, 0xed, - 0xfe, 0xff, 0xb1, 0xe6, 0xf9, 0xec, 0xa7, 0xe2, 0xf5, 0x1a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xe1, 0xf6, 0x56, 0xb1, 0xe8, - 0xfb, 0xff, 0xbf, 0xef, 0xff, 0xff, 0xbc, 0xe2, 0xec, 0xff, 0x5c, 0x3a, - 0x19, 0xff, 0x55, 0x2a, 0x00, 0xff, 0x82, 0x59, 0x2e, 0xff, 0x93, 0x75, - 0x52, 0xff, 0xcc, 0xed, 0xf5, 0xff, 0xc9, 0xf1, 0xff, 0xff, 0xbe, 0xec, - 0xfb, 0xff, 0xb5, 0xe7, 0xf8, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xb0, 0xe6, 0xfa, 0x92, 0xbf, 0xec, 0xfc, 0xff, 0xd0, 0xf5, - 0xff, 0xff, 0xc9, 0xe1, 0xe2, 0xff, 0x5a, 0x34, 0x10, 0xff, 0x55, 0x2b, - 0x00, 0xff, 0x81, 0x58, 0x2d, 0xff, 0x92, 0x71, 0x4c, 0xff, 0xd8, 0xee, - 0xf2, 0xff, 0xd6, 0xf5, 0xff, 0xff, 0xc8, 0xef, 0xfc, 0xff, 0xbb, 0xea, - 0xf9, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x02, 0xb8, 0xe9, - 0xf9, 0xc6, 0xca, 0xef, 0xfd, 0xff, 0xde, 0xfb, 0xff, 0xff, 0xd3, 0xde, - 0xda, 0xff, 0x58, 0x30, 0x0a, 0xff, 0x55, 0x2c, 0x00, 0xff, 0x7f, 0x58, - 0x2c, 0xff, 0x91, 0x6d, 0x47, 0xff, 0xe1, 0xed, 0xeb, 0xff, 0xdf, 0xf9, - 0xff, 0xff, 0xd0, 0xf1, 0xfc, 0xff, 0xc1, 0xea, 0xfb, 0xbd, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xb2, 0xe5, 0xf6, 0x1e, 0xbd, 0xeb, 0xfa, 0xf0, 0xd0, 0xf1, - 0xfd, 0xff, 0xe7, 0xfe, 0xff, 0xff, 0xda, 0xd9, 0xd4, 0xff, 0x56, 0x2d, - 0x07, 0xff, 0x55, 0x2c, 0x00, 0xff, 0x7e, 0x57, 0x2a, 0xff, 0x8d, 0x68, - 0x41, 0xff, 0xe6, 0xea, 0xe4, 0xff, 0xe5, 0xfb, 0xff, 0xff, 0xd3, 0xf2, - 0xfd, 0xff, 0xc4, 0xeb, 0xfa, 0xe9, 0xb9, 0xe8, 0xf3, 0x16, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0xe3, - 0xf8, 0x4a, 0xbe, 0xec, 0xfb, 0xff, 0xd1, 0xf1, 0xfd, 0xff, 0xe9, 0xff, - 0xff, 0xff, 0xd7, 0xd4, 0xce, 0xff, 0x54, 0x2a, 0x04, 0xff, 0x55, 0x2c, - 0x00, 0xff, 0x7e, 0x55, 0x28, 0xff, 0x8a, 0x63, 0x3a, 0xff, 0xe1, 0xe4, - 0xdf, 0xff, 0xe4, 0xfc, 0xff, 0xff, 0xd3, 0xf2, 0xfc, 0xff, 0xc2, 0xec, - 0xfb, 0xfe, 0xb6, 0xe8, 0xf7, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xe3, 0xf8, 0x79, 0xbb, 0xeb, - 0xfb, 0xff, 0xcc, 0xf0, 0xfd, 0xff, 0xe2, 0xfd, 0xff, 0xff, 0xca, 0xce, - 0xc9, 0xff, 0x52, 0x27, 0x03, 0xff, 0x56, 0x2c, 0x00, 0xff, 0x7c, 0x54, - 0x26, 0xff, 0x87, 0x60, 0x35, 0xff, 0xd4, 0xdf, 0xd8, 0xff, 0xdd, 0xfb, - 0xff, 0xff, 0xce, 0xf0, 0xfc, 0xff, 0xc0, 0xec, 0xfc, 0xff, 0xb0, 0xe8, - 0xf8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xa0, 0xe1, 0xf9, 0xa9, 0xb3, 0xe8, 0xfb, 0xff, 0xc2, 0xed, - 0xfc, 0xff, 0xd6, 0xfa, 0xff, 0xff, 0xbb, 0xc7, 0xc3, 0xff, 0x50, 0x25, - 0x01, 0xff, 0x56, 0x2c, 0x00, 0xff, 0x7b, 0x53, 0x23, 0xff, 0x84, 0x5c, - 0x2f, 0xff, 0xc7, 0xd7, 0xd1, 0xff, 0xd3, 0xf7, 0xff, 0xff, 0xc5, 0xee, - 0xfc, 0xff, 0xb9, 0xeb, 0xfb, 0xff, 0xab, 0xe5, 0xf9, 0xa0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xcc, 0xcc, 0x05, 0x96, 0xdd, - 0xf7, 0xcd, 0xa8, 0xe5, 0xfa, 0xff, 0xb5, 0xe9, 0xfb, 0xff, 0xc6, 0xf7, - 0xff, 0xff, 0xab, 0xbf, 0xbd, 0xff, 0x50, 0x24, 0x00, 0xff, 0x56, 0x2c, - 0x00, 0xff, 0x79, 0x51, 0x20, 0xff, 0x81, 0x59, 0x2a, 0xff, 0xb8, 0xce, - 0xca, 0xff, 0xc6, 0xf4, 0xff, 0xff, 0xb9, 0xea, 0xfb, 0xff, 0xaf, 0xe7, - 0xfb, 0xff, 0xa0, 0xe1, 0xf8, 0xc5, 0x7f, 0x7f, 0x7f, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xd1, 0xf6, 0x1c, 0x8b, 0xdb, 0xf7, 0xee, 0x9b, 0xe1, - 0xf9, 0xff, 0xa6, 0xe4, 0xfa, 0xff, 0xb4, 0xf2, 0xff, 0xff, 0x9b, 0xb7, - 0xb6, 0xff, 0x50, 0x22, 0x00, 0xff, 0x56, 0x2c, 0x00, 0xff, 0x77, 0x4e, - 0x1b, 0xff, 0x80, 0x55, 0x25, 0xff, 0xab, 0xc6, 0xc2, 0xff, 0xb7, 0xf1, - 0xff, 0xff, 0xad, 0xe6, 0xfb, 0xff, 0xa3, 0xe4, 0xfa, 0xff, 0x98, 0xdf, - 0xf7, 0xe7, 0x8c, 0xd9, 0xf2, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xd3, - 0xf6, 0x3a, 0x7d, 0xd7, 0xf8, 0xfd, 0x8b, 0xdc, 0xf9, 0xff, 0x96, 0xde, - 0xf9, 0xff, 0xa1, 0xec, 0xff, 0xff, 0x8c, 0xaf, 0xb1, 0xff, 0x50, 0x22, - 0x00, 0xff, 0x55, 0x2c, 0x00, 0xff, 0x74, 0x4c, 0x18, 0xff, 0x7e, 0x52, - 0x1f, 0xff, 0x9f, 0xbe, 0xbc, 0xff, 0xa8, 0xed, 0xff, 0xff, 0xa0, 0xe2, - 0xf9, 0xff, 0x98, 0xdf, 0xf9, 0xff, 0x8d, 0xda, 0xf8, 0xfb, 0x85, 0xd6, - 0xf5, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xd5, 0xfc, 0x5c, 0x6b, 0xdd, - 0xff, 0xff, 0x7a, 0xe0, 0xff, 0xff, 0x84, 0xdf, 0xff, 0xff, 0x8e, 0xe8, - 0xff, 0xff, 0x7d, 0xa6, 0xac, 0xff, 0x50, 0x21, 0x00, 0xff, 0x55, 0x2c, - 0x00, 0xff, 0x72, 0x49, 0x14, 0xff, 0x7b, 0x4e, 0x19, 0xff, 0x93, 0xb6, - 0xb5, 0xff, 0x9a, 0xe9, 0xff, 0xff, 0x92, 0xe1, 0xfe, 0xff, 0x8a, 0xe2, - 0xff, 0xff, 0x80, 0xe1, 0xff, 0xff, 0x74, 0xdb, 0xfc, 0x4f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x71, 0x92, 0x8e, 0x8a, 0x69, 0x97, 0x94, 0xff, 0x67, 0xaa, - 0xb3, 0xff, 0x6e, 0xc2, 0xdb, 0xff, 0x78, 0xe1, 0xf9, 0xfe, 0x6d, 0xa2, - 0xa9, 0xfe, 0x52, 0x20, 0x00, 0xff, 0x55, 0x2c, 0x00, 0xff, 0x6f, 0x46, - 0x11, 0xff, 0x7a, 0x4a, 0x13, 0xff, 0x87, 0xb1, 0xb0, 0xff, 0x89, 0xe5, - 0xfd, 0xff, 0x84, 0xd0, 0xe9, 0xff, 0x80, 0xc0, 0xcd, 0xff, 0x7f, 0xab, - 0xaf, 0xff, 0x7d, 0x96, 0x92, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x60, - 0x34, 0xaf, 0x77, 0x45, 0x0b, 0xff, 0x64, 0x35, 0x00, 0xff, 0x5b, 0x37, - 0x0c, 0xff, 0x5a, 0x4c, 0x34, 0xff, 0x59, 0x4d, 0x37, 0xff, 0x54, 0x28, - 0x00, 0xff, 0x55, 0x2c, 0x00, 0xff, 0x6c, 0x42, 0x0d, 0xff, 0x78, 0x4d, - 0x17, 0xff, 0x7e, 0x70, 0x4e, 0xff, 0x82, 0x77, 0x58, 0xff, 0x87, 0x67, - 0x42, 0xff, 0x8a, 0x61, 0x38, 0xff, 0x8d, 0x5f, 0x33, 0xff, 0x8d, 0x5e, - 0x34, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x67, 0x41, 0xc9, 0x76, 0x4e, - 0x1a, 0xff, 0x65, 0x3b, 0x00, 0xff, 0x5c, 0x30, 0x00, 0xff, 0x56, 0x27, - 0x00, 0xff, 0x54, 0x24, 0x00, 0xff, 0x54, 0x2c, 0x00, 0xff, 0x55, 0x2c, - 0x00, 0xff, 0x69, 0x40, 0x07, 0xff, 0x75, 0x4d, 0x17, 0xff, 0x7c, 0x50, - 0x1c, 0xff, 0x82, 0x55, 0x25, 0xff, 0x87, 0x5d, 0x33, 0xff, 0x89, 0x62, - 0x3a, 0xff, 0x8b, 0x65, 0x3e, 0xff, 0x8a, 0x65, 0x3f, 0xc9, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x8c, 0x65, 0x40, 0x5b, 0x75, 0x4c, 0x19, 0xcb, 0x65, 0x3c, - 0x02, 0xff, 0x5c, 0x33, 0x00, 0xff, 0x57, 0x2e, 0x00, 0xff, 0x55, 0x2b, - 0x00, 0xff, 0x54, 0x2b, 0x00, 0xff, 0x55, 0x2c, 0x00, 0xff, 0x65, 0x3c, - 0x03, 0xff, 0x71, 0x49, 0x12, 0xff, 0x7a, 0x52, 0x20, 0xff, 0x81, 0x5a, - 0x2c, 0xff, 0x85, 0x5f, 0x34, 0xff, 0x89, 0x62, 0x3a, 0xff, 0x8a, 0x63, - 0x3d, 0xd2, 0x89, 0x64, 0x3d, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x6d, 0x49, 0x00, 0x07, 0x61, 0x39, 0x00, 0x51, 0x57, 0x2e, - 0x00, 0xb5, 0x56, 0x2d, 0x01, 0xfd, 0x54, 0x2a, 0x00, 0xff, 0x54, 0x2b, - 0x00, 0xff, 0x54, 0x2b, 0x00, 0xff, 0x61, 0x38, 0x00, 0xff, 0x6f, 0x46, - 0x0d, 0xff, 0x78, 0x50, 0x1d, 0xff, 0x7d, 0x56, 0x27, 0xfc, 0x84, 0x5d, - 0x33, 0xb4, 0x86, 0x60, 0x38, 0x52, 0x7f, 0x4c, 0x33, 0x0a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x40, 0x20, 0x08, 0x77, 0x4f, - 0x22, 0xde, 0x59, 0x2f, 0x00, 0xff, 0x54, 0x2b, 0x00, 0xff, 0x53, 0x2a, - 0x00, 0xff, 0x5c, 0x33, 0x00, 0xff, 0x6a, 0x42, 0x08, 0xff, 0x6f, 0x47, - 0x0f, 0xff, 0x6a, 0x44, 0x09, 0xdb, 0x55, 0x2a, 0x00, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x55, 0x55, 0x00, 0x03, 0x7f, 0x58, 0x28, 0xc4, 0x5f, 0x36, - 0x00, 0xff, 0x55, 0x2b, 0x00, 0xff, 0x54, 0x2b, 0x01, 0xff, 0x61, 0x39, - 0x03, 0xff, 0x69, 0x41, 0x05, 0xff, 0x68, 0x40, 0x04, 0xff, 0x66, 0x3e, - 0x04, 0xcf, 0x33, 0x33, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0x52, 0x24, 0x1c, 0x5a, 0x31, 0x00, 0xb0, 0x54, 0x2b, - 0x00, 0xff, 0x55, 0x2d, 0x01, 0xff, 0x68, 0x40, 0x05, 0xff, 0x68, 0x40, - 0x04, 0xff, 0x65, 0x3c, 0x03, 0xb3, 0x65, 0x3b, 0x00, 0x2b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x52, 0x29, 0x00, 0x88, 0x53, 0x29, 0x00, 0x75, 0x55, 0x2c, - 0x00, 0xa8, 0x68, 0x3f, 0x05, 0xa9, 0x5f, 0x36, 0x02, 0x8e, 0x51, 0x29, - 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x2a, - 0x00, 0x68, 0x52, 0x2a, 0x00, 0x92, 0x4c, 0x19, 0x00, 0x0a, 0x60, 0x30, - 0x00, 0x10, 0x53, 0x2a, 0x00, 0xa2, 0x51, 0x28, 0x00, 0x52, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x54, 0x29, - 0x00, 0x7d, 0x52, 0x2a, 0x00, 0xb0, 0x53, 0x2a, 0x00, 0xb1, 0x53, 0x29, - 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x7f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf0, - 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xe0, - 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xc0, - 0x03, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xc0, - 0x03, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x80, - 0x01, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x80, - 0x01, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x00, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xf0, - 0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xfa, - 0x3f, 0xff, 0xff, 0xfd, 0xbf, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, - 0xff, 0xff, -} diff --git a/vendor/github.com/getlantern/systray/example/icon/iconwin.ico b/vendor/github.com/getlantern/systray/example/icon/iconwin.ico deleted file mode 100644 index 24539c712..000000000 Binary files a/vendor/github.com/getlantern/systray/example/icon/iconwin.ico and /dev/null differ diff --git a/vendor/github.com/getlantern/systray/example/icon/make_icon.bat b/vendor/github.com/getlantern/systray/example/icon/make_icon.bat deleted file mode 100644 index fa281132d..000000000 --- a/vendor/github.com/getlantern/systray/example/icon/make_icon.bat +++ /dev/null @@ -1,41 +0,0 @@ -@ECHO OFF - -IF "%GOPATH%"=="" GOTO NOGO -IF NOT EXIST %GOPATH%\bin\2goarray.exe GOTO INSTALL -:POSTINSTALL -IF "%1"=="" GOTO NOICO -IF NOT EXIST %1 GOTO BADFILE -ECHO Creating iconwin.go -ECHO //+build windows > iconwin.go -ECHO. >> iconwin.go -TYPE %1 | %GOPATH%\bin\2goarray Data icon >> iconwin.go -GOTO DONE - -:CREATEFAIL -ECHO Unable to create output file -GOTO DONE - -:INSTALL -ECHO Installing 2goarray... -go get github.com/cratonica/2goarray -IF ERRORLEVEL 1 GOTO GETFAIL -GOTO POSTINSTALL - -:GETFAIL -ECHO Failure running go get github.com/cratonica/2goarray. Ensure that go and git are in PATH -GOTO DONE - -:NOGO -ECHO GOPATH environment variable not set -GOTO DONE - -:NOICO -ECHO Please specify a .ico file -GOTO DONE - -:BADFILE -ECHO %1 is not a valid file -GOTO DONE - -:DONE - diff --git a/vendor/github.com/getlantern/systray/example/icon/make_icon.sh b/vendor/github.com/getlantern/systray/example/icon/make_icon.sh deleted file mode 100755 index e70737328..000000000 --- a/vendor/github.com/getlantern/systray/example/icon/make_icon.sh +++ /dev/null @@ -1,36 +0,0 @@ -#/bin/sh - -if [ -z "$GOPATH" ]; then - echo GOPATH environment variable not set - exit -fi - -if [ ! -e "$GOPATH/bin/2goarray" ]; then - echo "Installing 2goarray..." - go get github.com/cratonica/2goarray - if [ $? -ne 0 ]; then - echo Failure executing go get github.com/cratonica/2goarray - exit - fi -fi - -if [ -z "$1" ]; then - echo Please specify a PNG file - exit -fi - -if [ ! -f "$1" ]; then - echo $1 is not a valid file - exit -fi - -OUTPUT=iconunix.go -echo Generating $OUTPUT -echo "//+build linux darwin" > $OUTPUT -echo >> $OUTPUT -cat "$1" | $GOPATH/bin/2goarray Data icon >> $OUTPUT -if [ $? -ne 0 ]; then - echo Failure generating $OUTPUT - exit -fi -echo Finished diff --git a/vendor/github.com/getlantern/systray/example/main.go b/vendor/github.com/getlantern/systray/example/main.go deleted file mode 100644 index 01b9ee85c..000000000 --- a/vendor/github.com/getlantern/systray/example/main.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import ( - "fmt" - "github.com/getlantern/systray" - "github.com/getlantern/systray/example/icon" - "github.com/skratchdot/open-golang/open" -) - -func main() { - // Should be called at the very beginning of main(). - systray.Run(onReady) -} - -func onReady() { - systray.SetIcon(icon.Data) - systray.SetTitle("Awesome App") - systray.SetTooltip("Lantern") - mQuit := systray.AddMenuItem("Quit", "Quit the whole app") - go func() { - <-mQuit.ClickedCh - systray.Quit() - fmt.Println("Quit now...") - }() - - // We can manipulate the systray in other goroutines - go func() { - systray.SetIcon(icon.Data) - systray.SetTitle("Awesome App") - systray.SetTooltip("Pretty awesome棒棒嗒") - mChange := systray.AddMenuItem("Change Me", "Change Me") - mChecked := systray.AddMenuItem("Unchecked", "Check Me") - mEnabled := systray.AddMenuItem("Enabled", "Enabled") - systray.AddMenuItem("Ignored", "Ignored") - mUrl := systray.AddMenuItem("Open Lantern.org", "my home") - mQuit := systray.AddMenuItem("退出", "Quit the whole app") - for { - select { - case <-mChange.ClickedCh: - mChange.SetTitle("I've Changed") - case <-mChecked.ClickedCh: - if mChecked.Checked() { - mChecked.Uncheck() - mChecked.SetTitle("Unchecked") - } else { - mChecked.Check() - mChecked.SetTitle("Checked") - } - case <-mEnabled.ClickedCh: - mEnabled.SetTitle("Disabled") - mEnabled.Disable() - case <-mUrl.ClickedCh: - open.Run("https://www.getlantern.org") - case <-mQuit.ClickedCh: - systray.Quit() - fmt.Println("Quit2 now...") - return - } - } - }() -} diff --git a/vendor/github.com/getlantern/systray/signdll.bash b/vendor/github.com/getlantern/systray/signdll.bash deleted file mode 100755 index 1b0a11932..000000000 --- a/vendor/github.com/getlantern/systray/signdll.bash +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -if [ -z "$BNS_CERT" ] -then - die "$0: Please set BNS_CERT to the bns signing certificate for windows" -fi - -if [ -z "$BNS_CERT_PASS" ] -then - die "$0: Please set BNS_CERT_PASS to the password for the $BNS_CERT signing key" -fi - -which osslsigncode > /dev/null -if [ $? -ne 0 ] -then - echo "Installing osslsigncode" - brew install osslsigncode || die "Could not install osslsigncode" -fi -osslsigncode sign -pkcs12 "$BNS_CERT" -pass "$BNS_CERT_PASS" -in dll/systray_unsigned.dll -out dll/systray.dll || die "Could not sign windows dll" diff --git a/vendor/github.com/getlantern/systray/systray.go b/vendor/github.com/getlantern/systray/systray.go index 7abc072c5..d43317323 100644 --- a/vendor/github.com/getlantern/systray/systray.go +++ b/vendor/github.com/getlantern/systray/systray.go @@ -1,7 +1,9 @@ /* -Package systray is a cross platfrom Go library to place an icon and menu in the notification area. +Package systray is a cross platfrom Go library to place an icon and menu in the +notification area. Supports Windows, Mac OSX and Linux currently. -Methods can be called from any goroutine except Run(), which should be called at the very beginning of main() to lock at main thread. +Methods can be called from any goroutine except Run(), which should be called +at the very beginning of main() to lock at main thread. */ package systray @@ -13,11 +15,16 @@ import ( "github.com/getlantern/golog" ) +var ( + hasStarted = int64(0) + hasQuit = int64(0) +) + // MenuItem is used to keep track each menu item of systray // Don't create it directly, use the one systray.AddMenuItem() returned type MenuItem struct { // ClickedCh is the channel which will be notified when the menu item is clicked - ClickedCh chan interface{} + ClickedCh chan struct{} // id uniquely identify a menu item, not supposed to be modified id int32 @@ -34,31 +41,51 @@ type MenuItem struct { var ( log = golog.LoggerFor("systray") - readyCh = make(chan interface{}) - clickedCh = make(chan interface{}) + systrayReady func() + systrayExit func() menuItems = make(map[int32]*MenuItem) menuItemsLock sync.RWMutex - currentID int32 + currentID = int32(-1) ) // Run initializes GUI and starts the event loop, then invokes the onReady // callback. // It blocks until systray.Quit() is called. // Should be called at the very beginning of main() to lock at main thread. -func Run(onReady func()) { +func Run(onReady func(), onExit func()) { runtime.LockOSThread() - go func() { - <-readyCh - onReady() - }() + atomic.StoreInt64(&hasStarted, 1) + + if onReady == nil { + systrayReady = func() {} + } else { + // Run onReady on separate goroutine to avoid blocking event loop + readyCh := make(chan interface{}) + go func() { + <-readyCh + onReady() + }() + systrayReady = func() { + close(readyCh) + } + } + + // unlike onReady, onExit runs in the event loop to make sure it has time to + // finish before the process terminates + if onExit == nil { + onExit = func() {} + } + systrayExit = onExit nativeLoop() } // Quit the systray func Quit() { - quit() + if atomic.LoadInt64(&hasStarted) == 1 && atomic.CompareAndSwapInt64(&hasQuit, 0, 1) { + quit() + } } // AddMenuItem adds menu item with designated title and tooltip, returning a channel @@ -68,11 +95,16 @@ func Quit() { func AddMenuItem(title string, tooltip string) *MenuItem { id := atomic.AddInt32(¤tID, 1) item := &MenuItem{nil, id, title, tooltip, false, false} - item.ClickedCh = make(chan interface{}) + item.ClickedCh = make(chan struct{}) item.update() return item } +// AddSeparator adds a separator bar to the menu +func AddSeparator() { + addSeparator(atomic.AddInt32(¤tID, 1)) +} + // SetTitle set the text to display on a menu item func (item *MenuItem) SetTitle(title string) { item.title = title @@ -102,6 +134,16 @@ func (item *MenuItem) Disable() { item.update() } +// Hide hides a menu item +func (item *MenuItem) Hide() { + hideMenuItem(item) +} + +// Show shows a previously hidden menu item +func (item *MenuItem) Show() { + showMenuItem(item) +} + // Checked returns if the menu item has a check mark func (item *MenuItem) Checked() bool { return item.checked @@ -127,16 +169,12 @@ func (item *MenuItem) update() { addOrUpdateMenuItem(item) } -func systrayReady() { - readyCh <- nil -} - func systrayMenuItemSelected(id int32) { menuItemsLock.RLock() item := menuItems[id] menuItemsLock.RUnlock() select { - case item.ClickedCh <- nil: + case item.ClickedCh <- struct{}{}: // in case no one waiting for the channel default: } diff --git a/vendor/github.com/getlantern/systray/systray.h b/vendor/github.com/getlantern/systray/systray.h index 819b65ff7..36bcf9893 100644 --- a/vendor/github.com/getlantern/systray/systray.h +++ b/vendor/github.com/getlantern/systray/systray.h @@ -1,9 +1,14 @@ extern void systray_ready(); +extern void systray_on_exit(); extern void systray_menu_item_selected(int menu_id); int nativeLoop(void); void setIcon(const char* iconBytes, int length); +void setMenuItemIcon(const char* iconBytes, int length, int menuId); void setTitle(char* title); void setTooltip(char* tooltip); void add_or_update_menu_item(int menuId, char* title, char* tooltip, short disabled, short checked); +void add_separator(int menuId); +void hide_menu_item(int menuId); +void show_menu_item(int menuId); void quit(); diff --git a/vendor/github.com/getlantern/systray/systray/systray.sln b/vendor/github.com/getlantern/systray/systray/systray.sln deleted file mode 100755 index 30c2245b3..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "systray", "systray\systray.vcxproj", "{7DD84108-D77F-4F51-AC68-5DD13AC1E489}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7DD84108-D77F-4F51-AC68-5DD13AC1E489}.Debug|Win32.ActiveCfg = Debug|Win32 - {7DD84108-D77F-4F51-AC68-5DD13AC1E489}.Debug|Win32.Build.0 = Debug|Win32 - {7DD84108-D77F-4F51-AC68-5DD13AC1E489}.Release|Win32.ActiveCfg = Release|Win32 - {7DD84108-D77F-4F51-AC68-5DD13AC1E489}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/vendor/github.com/getlantern/systray/systray/systray.suo b/vendor/github.com/getlantern/systray/systray/systray.suo deleted file mode 100644 index 2af3ecd26..000000000 Binary files a/vendor/github.com/getlantern/systray/systray/systray.suo and /dev/null differ diff --git a/vendor/github.com/getlantern/systray/systray/systray/ReadMe.txt b/vendor/github.com/getlantern/systray/systray/systray/ReadMe.txt deleted file mode 100755 index 7e906df06..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/ReadMe.txt +++ /dev/null @@ -1,48 +0,0 @@ -======================================================================== - DYNAMIC LINK LIBRARY : systray Project Overview -======================================================================== - -AppWizard has created this systray DLL for you. - -This file contains a summary of what you will find in each of the files that -make up your systray application. - - -systray.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -systray.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -systray.cpp - This is the main DLL source file. - - When created, this DLL does not export any symbols. As a result, it - will not produce a .lib file when it is built. If you wish this project - to be a project dependency of some other project, you will either need to - add code to export some symbols from the DLL so that an export library - will be produced, or you can set the Ignore Input Library property to Yes - on the General propert page of the Linker folder in the project's Property - Pages dialog box. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named systray.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/vendor/github.com/getlantern/systray/systray/systray/dllmain.cpp b/vendor/github.com/getlantern/systray/systray/systray/dllmain.cpp deleted file mode 100755 index 8a4edd310..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/dllmain.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// dllmain.cpp : Defines the entry point for the DLL application. -#include "stdafx.h" - -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} - diff --git a/vendor/github.com/getlantern/systray/systray/systray/stdafx.cpp b/vendor/github.com/getlantern/systray/systray/systray/stdafx.cpp deleted file mode 100755 index a71cba8dc..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// systray.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/vendor/github.com/getlantern/systray/systray/systray/stdafx.h b/vendor/github.com/getlantern/systray/systray/systray/stdafx.h deleted file mode 100755 index 7e739d97b..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/stdafx.h +++ /dev/null @@ -1,17 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include -// Additional required headers -#include -#include -#include -#include diff --git a/vendor/github.com/getlantern/systray/systray/systray/systray.cpp b/vendor/github.com/getlantern/systray/systray/systray/systray.cpp deleted file mode 100755 index 8de2daa72..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/systray.cpp +++ /dev/null @@ -1,212 +0,0 @@ -// systray.cpp : Defines the exported functions for the DLL application. -// - -// dllmain.cpp : Defines the entry point for the DLL application. -#include "stdafx.h" -#include "systray.h" - -// Message posted into message loop when Notification Icon is clicked -#define WM_SYSTRAY_MESSAGE (WM_USER + 1) - -static NOTIFYICONDATA nid; -static HWND hWnd; -static HMENU hTrayMenu; - -void (*systray_menu_item_selected)(int menu_id); - -void reportWindowsError(const char* action) { - LPTSTR pErrMsg = NULL; - DWORD errCode = GetLastError(); - DWORD result = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| - FORMAT_MESSAGE_FROM_SYSTEM| - FORMAT_MESSAGE_ARGUMENT_ARRAY, - NULL, - errCode, - LANG_NEUTRAL, - pErrMsg, - 0, - NULL); - printf("Systray error %s: %d %s\n", action, errCode, pErrMsg); -} - -void ShowMenu(HWND hWnd) { - POINT p; - if (0 == GetCursorPos(&p)) { - reportWindowsError("get tray menu position"); - return; - }; - SetForegroundWindow(hWnd); // Win32 bug work-around - TrackPopupMenu(hTrayMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL); - -} - -int GetMenuItemId(int index) { - MENUITEMINFO menuItemInfo; - menuItemInfo.cbSize = sizeof(MENUITEMINFO); - menuItemInfo.fMask = MIIM_DATA; - if (0 == GetMenuItemInfo(hTrayMenu, index, TRUE, &menuItemInfo)) { - reportWindowsError("get menu item id"); - return -1; - } - return menuItemInfo.dwItemData; -} - -LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_MENUCOMMAND: - { - int menuId = GetMenuItemId(wParam); - if (menuId != -1) { - systray_menu_item_selected(menuId); - } - } - break; - case WM_DESTROY: - PostQuitMessage(0); - break; - case WM_SYSTRAY_MESSAGE: - switch(lParam) { - case WM_RBUTTONUP: - ShowMenu(hWnd); - break; - case WM_LBUTTONUP: - ShowMenu(hWnd); - break; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - }; - break; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; -} - -void MyRegisterClass(HINSTANCE hInstance, TCHAR* szWindowClass) { - WNDCLASSEX wcex; - - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = WndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = hInstance; - wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wcex.lpszMenuName = 0; - wcex.lpszClassName = szWindowClass; - wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); - - RegisterClassEx(&wcex); -} - -HWND InitInstance(HINSTANCE hInstance, int nCmdShow, TCHAR* szWindowClass) { - HWND hWnd = CreateWindow(szWindowClass, TEXT(""), WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); - if (!hWnd) { - return 0; - } - - ShowWindow(hWnd, nCmdShow); - UpdateWindow(hWnd); - - return hWnd; -} - - -BOOL createMenu() { - hTrayMenu = CreatePopupMenu(); - MENUINFO menuInfo; - menuInfo.cbSize = sizeof(MENUINFO); - menuInfo.fMask = MIM_APPLYTOSUBMENUS | MIM_STYLE; - menuInfo.dwStyle = MNS_NOTIFYBYPOS; - return SetMenuInfo(hTrayMenu, &menuInfo); -} - -BOOL addNotifyIcon() { - nid.cbSize = sizeof(NOTIFYICONDATA); - nid.hWnd = hWnd; - nid.uID = 100; - nid.uCallbackMessage = WM_SYSTRAY_MESSAGE; - nid.uFlags = NIF_MESSAGE; - return Shell_NotifyIcon(NIM_ADD, &nid); -} - -int nativeLoop(void (*systray_ready)(int ignored), void (*_systray_menu_item_selected)(int menu_id)) { - systray_menu_item_selected = _systray_menu_item_selected; - - HINSTANCE hInstance = GetModuleHandle(NULL); - TCHAR* szWindowClass = TEXT("SystrayClass"); - MyRegisterClass(hInstance, szWindowClass); - hWnd = InitInstance(hInstance, FALSE, szWindowClass); // Don't show window - if (!hWnd) { - return EXIT_FAILURE; - } - if (!createMenu() || !addNotifyIcon()) { - return EXIT_FAILURE; - } - systray_ready(0); - - MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return EXIT_SUCCESS; -} - - -void setIcon(const wchar_t* iconFile) { - HICON hIcon = (HICON) LoadImage(NULL, iconFile, IMAGE_ICON, 64, 64, LR_LOADFROMFILE); - if (hIcon == NULL) { - reportWindowsError("load icon image"); - } else { - nid.hIcon = hIcon; - nid.uFlags = NIF_ICON; - Shell_NotifyIcon(NIM_MODIFY, &nid); - } -} - -void setTooltip(const wchar_t* tooltip) { - wcsncpy_s(nid.szTip, tooltip, sizeof(nid.szTip)/sizeof(wchar_t)); - nid.uFlags = NIF_TIP; - Shell_NotifyIcon(NIM_MODIFY, &nid); -} - -void add_or_update_menu_item(int menuId, wchar_t* title, wchar_t* tooltip, short disabled, short checked) { - MENUITEMINFO menuItemInfo; - menuItemInfo.cbSize = sizeof(MENUITEMINFO); - menuItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_DATA | MIIM_STATE; - menuItemInfo.fType = MFT_STRING; - menuItemInfo.dwTypeData = title; - menuItemInfo.cch = wcslen(title) + 1; - menuItemInfo.dwItemData = (ULONG_PTR)menuId; - menuItemInfo.fState = 0; - if (disabled == 1) { - menuItemInfo.fState |= MFS_DISABLED; - } - if (checked == 1) { - menuItemInfo.fState |= MFS_CHECKED; - } - - int itemCount = GetMenuItemCount(hTrayMenu); - int i; - for (i = 0; i < itemCount; i++) { - int id = GetMenuItemId(i); - if (-1 == id) { - continue; - } - if (menuId == id) { - SetMenuItemInfo(hTrayMenu, i, TRUE, &menuItemInfo); - break; - } - } - if (i == itemCount) { - InsertMenuItem(hTrayMenu, -1, TRUE, &menuItemInfo); - } -} - -void quit() { - Shell_NotifyIcon(NIM_DELETE, &nid); -} diff --git a/vendor/github.com/getlantern/systray/systray/systray/systray.def b/vendor/github.com/getlantern/systray/systray/systray/systray.def deleted file mode 100755 index f8f67f186..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/systray.def +++ /dev/null @@ -1,8 +0,0 @@ -LIBRARY systray -DESCRIPTION "System Tray Support" -EXPORTS - nativeLoop @1 - setIcon @2 - setTooltip @3 - add_or_update_menu_item @4 - quit @5 \ No newline at end of file diff --git a/vendor/github.com/getlantern/systray/systray/systray/systray.h b/vendor/github.com/getlantern/systray/systray/systray/systray.h deleted file mode 100755 index 3a2a27335..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/systray.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -extern "C" { - __declspec(dllexport) int __cdecl nativeLoop(void (*systray_ready)(int ignored), void (*_systray_menu_item_selected)(int menu_id)); - - __declspec(dllexport) void __cdecl setIcon(const wchar_t* iconFile); - __declspec(dllexport) void __cdecl setTooltip(const wchar_t* tooltip); - __declspec(dllexport) void __cdecl add_or_update_menu_item(int menuId, wchar_t* title, wchar_t* tooltip, short disabled, short checked); - __declspec(dllexport) void __cdecl quit(); -} \ No newline at end of file diff --git a/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj b/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj deleted file mode 100755 index 84830e610..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj +++ /dev/null @@ -1,105 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {7DD84108-D77F-4F51-AC68-5DD13AC1E489} - Win32Proj - systray - - - - DynamicLibrary - true - Unicode - v90 - - - DynamicLibrary - false - true - Unicode - v90 - - - - - - - - - - - - - true - - - false - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;SYSTRAY_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Windows - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSTRAY_EXPORTS;%(PreprocessorDefinitions) - MultiThreaded - - - Windows - true - true - true - - - - - - - - - - - - - - false - - - false - - - - - Create - Create - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj.filters b/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj.filters deleted file mode 100755 index af0af7652..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj.filters +++ /dev/null @@ -1,45 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj.user b/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj.user deleted file mode 100755 index 695b5c78b..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/systray.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/vendor/github.com/getlantern/systray/systray/systray/targetver.h b/vendor/github.com/getlantern/systray/systray/systray/targetver.h deleted file mode 100755 index 90e767bfc..000000000 --- a/vendor/github.com/getlantern/systray/systray/systray/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/vendor/github.com/getlantern/systray/systray_darwin.m b/vendor/github.com/getlantern/systray/systray_darwin.m index 14bb3b9a6..e46694882 100644 --- a/vendor/github.com/getlantern/systray/systray_darwin.m +++ b/vendor/github.com/getlantern/systray/systray_darwin.m @@ -58,16 +58,36 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification systray_ready(); } +- (void)applicationWillTerminate:(NSNotification *)aNotification +{ + systray_on_exit(); +} + - (void)setIcon:(NSImage *)image { - [statusItem setImage:image]; + statusItem.button.image = image; + [self updateTitleButtonStyle]; } - (void)setTitle:(NSString *)title { - [statusItem setTitle:title]; + statusItem.button.title = title; + [self updateTitleButtonStyle]; +} + +-(void)updateTitleButtonStyle { + if (statusItem.button.image != nil) { + if ([statusItem.button.title length] == 0) { + statusItem.button.imagePosition = NSImageOnly; + } else { + statusItem.button.imagePosition = NSImageLeft; + } + } else { + statusItem.button.imagePosition = NSNoImage; + } } + - (void)setTooltip:(NSString *)tooltip { - [statusItem setToolTip:tooltip]; + statusItem.button.toolTip = tooltip; } - (IBAction)menuHandler:(id)sender @@ -92,20 +112,60 @@ - (void) add_or_update_menu_item:(MenuItem*) item } [menuItem setToolTip:item->tooltip]; if (item->disabled == 1) { - [menuItem setEnabled:FALSE]; + menuItem.enabled = FALSE; } else { - [menuItem setEnabled:TRUE]; + menuItem.enabled = TRUE; } if (item->checked == 1) { - [menuItem setState:NSOnState]; + menuItem.state = NSControlStateValueOn; } else { - [menuItem setState:NSOffState]; + menuItem.state = NSControlStateValueOff; + } +} + +- (void) add_separator:(NSNumber*) menuId +{ + [menu addItem: [NSMenuItem separatorItem]]; +} + +- (void) hide_menu_item:(NSNumber*) menuId +{ + NSMenuItem* menuItem; + int existedMenuIndex = [menu indexOfItemWithRepresentedObject: menuId]; + if (existedMenuIndex == -1) { + return; + } + menuItem = [menu itemAtIndex: existedMenuIndex]; + [menuItem setHidden:TRUE]; +} + +- (void)setMenuItemIcon:(NSArray*)imageAndMenuId { + NSImage* image = [imageAndMenuId objectAtIndex:0]; + NSNumber* menuId = [imageAndMenuId objectAtIndex:1]; + + NSMenuItem* menuItem; + int existedMenuIndex = [menu indexOfItemWithRepresentedObject: menuId]; + if (existedMenuIndex == -1) { + return; + } + menuItem = [menu itemAtIndex: existedMenuIndex]; + menuItem.image = image; +} + +- (void) show_menu_item:(NSNumber*) menuId +{ + NSMenuItem* menuItem; + int existedMenuIndex = [menu indexOfItemWithRepresentedObject: menuId]; + if (existedMenuIndex == -1) { + return; } + menuItem = [menu itemAtIndex: existedMenuIndex]; + [menuItem setHidden:FALSE]; } - (void) quit { - [[NSStatusBar systemStatusBar] removeStatusItem: statusItem]; + [NSApp terminate:self]; } @end @@ -127,9 +187,19 @@ void runInMainThread(SEL method, id object) { void setIcon(const char* iconBytes, int length) { NSData* buffer = [NSData dataWithBytes: iconBytes length:length]; NSImage *image = [[NSImage alloc] initWithData:buffer]; + [image setSize:NSMakeSize(16, 16)]; runInMainThread(@selector(setIcon:), (id)image); } +void setMenuItemIcon(const char* iconBytes, int length, int menuId) { + NSData* buffer = [NSData dataWithBytes: iconBytes length:length]; + NSImage *image = [[NSImage alloc] initWithData:buffer]; + [image setSize:NSMakeSize(16, 16)]; + + NSNumber *mId = [NSNumber numberWithInt:menuId]; + runInMainThread(@selector(setMenuItemIcon:), @[image, (id)mId]); +} + void setTitle(char* ctitle) { NSString* title = [[NSString alloc] initWithCString:ctitle encoding:NSUTF8StringEncoding]; @@ -151,6 +221,21 @@ void add_or_update_menu_item(int menuId, char* title, char* tooltip, short disab runInMainThread(@selector(add_or_update_menu_item:), (id)item); } +void add_separator(int menuId) { + NSNumber *mId = [NSNumber numberWithInt:menuId]; + runInMainThread(@selector(add_separator:), (id)mId); +} + +void hide_menu_item(int menuId) { + NSNumber *mId = [NSNumber numberWithInt:menuId]; + runInMainThread(@selector(hide_menu_item:), (id)mId); +} + +void show_menu_item(int menuId) { + NSNumber *mId = [NSNumber numberWithInt:menuId]; + runInMainThread(@selector(show_menu_item:), (id)mId); +} + void quit() { runInMainThread(@selector(quit), nil); } diff --git a/vendor/github.com/getlantern/systray/systray_linux.c b/vendor/github.com/getlantern/systray/systray_linux.c index 56c622977..72cd6140f 100644 --- a/vendor/github.com/getlantern/systray/systray_linux.c +++ b/vendor/github.com/getlantern/systray/systray_linux.c @@ -8,8 +8,7 @@ static AppIndicator *global_app_indicator; static GtkWidget *global_tray_menu = NULL; static GList *global_menu_items = NULL; -// Keep track of all generated temp files to remove when app quits -static GArray *global_temp_icon_file_names = NULL; +static char temp_file_name[PATH_MAX] = ""; typedef struct { GtkWidget *menu_item; @@ -31,23 +30,39 @@ int nativeLoop(void) { app_indicator_set_status(global_app_indicator, APP_INDICATOR_STATUS_ACTIVE); global_tray_menu = gtk_menu_new(); app_indicator_set_menu(global_app_indicator, GTK_MENU(global_tray_menu)); - global_temp_icon_file_names = g_array_new(TRUE, FALSE, sizeof(char*)); systray_ready(); gtk_main(); - return; + systray_on_exit(); + return 0; +} + +void _unlink_temp_file() { + if (strlen(temp_file_name) != 0) { + int ret = unlink(temp_file_name); + if (ret == -1) { + printf("failed to remove temp icon file %s: %s\n", temp_file_name, strerror(errno)); + } + temp_file_name[0] = '\0'; + } } // runs in main thread, should always return FALSE to prevent gtk to execute it again gboolean do_set_icon(gpointer data) { + _unlink_temp_file(); + char *tmpdir = getenv("TMPDIR"); + if (NULL == tmpdir) { + tmpdir = "/tmp"; + } + strncpy(temp_file_name, tmpdir, PATH_MAX-1); + strncat(temp_file_name, "/systray_XXXXXX", PATH_MAX-1); + temp_file_name[PATH_MAX-1] = '\0'; + GBytes* bytes = (GBytes*)data; - char* temp_file_name = malloc(PATH_MAX); - strcpy(temp_file_name, "/tmp/systray_XXXXXX"); int fd = mkstemp(temp_file_name); if (fd == -1) { printf("failed to create temp icon file %s: %s\n", temp_file_name, strerror(errno)); return FALSE; } - g_array_append_val(global_temp_icon_file_names, temp_file_name); gsize size = 0; gconstpointer icon_data = g_bytes_get_data(bytes, &size); ssize_t written = write(fd, icon_data, size); @@ -100,7 +115,7 @@ gboolean do_add_or_update_menu_item(gpointer data) { } GtkWidget * menu_item = GTK_WIDGET(((MenuItemNode*)(it->data))->menu_item); gtk_widget_set_sensitive(menu_item, mii->disabled == 1 ? FALSE : TRUE); - gtk_widget_show_all(global_tray_menu); + gtk_widget_show(menu_item); free(mii->title); free(mii->tooltip); @@ -108,21 +123,47 @@ gboolean do_add_or_update_menu_item(gpointer data) { return FALSE; } +gboolean do_add_separator(gpointer data) { + GtkWidget *separator = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(global_tray_menu), separator); + gtk_widget_show(separator); + return FALSE; +} + // runs in main thread, should always return FALSE to prevent gtk to execute it again -gboolean do_quit(gpointer data) { - int i; - for (i = 0; i < INT_MAX; ++i) { - char * temp_file_name = g_array_index(global_temp_icon_file_names, char*, i); - if (temp_file_name == NULL) { +gboolean do_hide_menu_item(gpointer data) { + MenuItemInfo *mii = (MenuItemInfo*)data; + GList* it; + for(it = global_menu_items; it != NULL; it = it->next) { + MenuItemNode* item = (MenuItemNode*)(it->data); + if(item->menu_id == mii->menu_id){ + gtk_widget_hide(GTK_WIDGET(item->menu_item)); break; } - int ret = unlink(temp_file_name); - if (ret == -1) { - printf("failed to remove temp icon file %s: %s\n", temp_file_name, strerror(errno)); + } + return FALSE; +} + +// runs in main thread, should always return FALSE to prevent gtk to execute it again +gboolean do_show_menu_item(gpointer data) { + MenuItemInfo *mii = (MenuItemInfo*)data; + GList* it; + for(it = global_menu_items; it != NULL; it = it->next) { + MenuItemNode* item = (MenuItemNode*)(it->data); + if(item->menu_id == mii->menu_id){ + gtk_widget_show(GTK_WIDGET(item->menu_item)); + break; } } + return FALSE; +} + +// runs in main thread, should always return FALSE to prevent gtk to execute it again +gboolean do_quit(gpointer data) { + _unlink_temp_file(); // app indicator doesn't provide a way to remove it, hide it as a workaround app_indicator_set_status(global_app_indicator, APP_INDICATOR_STATUS_PASSIVE); + gtk_main_quit(); return FALSE; } @@ -140,6 +181,9 @@ void setTooltip(char* ctooltip) { free(ctooltip); } +void setMenuItemIcon(const char* iconBytes, int length, int menuId) { +} + void add_or_update_menu_item(int menu_id, char* title, char* tooltip, short disabled, short checked) { MenuItemInfo *mii = malloc(sizeof(MenuItemInfo)); mii->menu_id = menu_id; @@ -150,6 +194,24 @@ void add_or_update_menu_item(int menu_id, char* title, char* tooltip, short disa g_idle_add(do_add_or_update_menu_item, mii); } +void add_separator(int menu_id) { + MenuItemInfo *mii = malloc(sizeof(MenuItemInfo)); + mii->menu_id = menu_id; + g_idle_add(do_add_separator, mii); +} + +void hide_menu_item(int menu_id) { + MenuItemInfo *mii = malloc(sizeof(MenuItemInfo)); + mii->menu_id = menu_id; + g_idle_add(do_hide_menu_item, mii); +} + +void show_menu_item(int menu_id) { + MenuItemInfo *mii = malloc(sizeof(MenuItemInfo)); + mii->menu_id = menu_id; + g_idle_add(do_show_menu_item, mii); +} + void quit() { g_idle_add(do_quit, NULL); } diff --git a/vendor/github.com/getlantern/systray/systray_nonwindows.go b/vendor/github.com/getlantern/systray/systray_nonwindows.go index ed060ca26..4868b554d 100644 --- a/vendor/github.com/getlantern/systray/systray_nonwindows.go +++ b/vendor/github.com/getlantern/systray/systray_nonwindows.go @@ -60,11 +60,39 @@ func addOrUpdateMenuItem(item *MenuItem) { ) } +// SetIcon sets the icon of a menu item. Only available on Mac. +// iconBytes should be the content of .ico/.jpg/.png +func (item *MenuItem) SetIcon(iconBytes []byte) { + cstr := (*C.char)(unsafe.Pointer(&iconBytes[0])) + C.setMenuItemIcon(cstr, (C.int)(len(iconBytes)), C.int(item.id)) +} + +func addSeparator(id int32) { + C.add_separator(C.int(id)) +} + +func hideMenuItem(item *MenuItem) { + C.hide_menu_item( + C.int(item.id), + ) +} + +func showMenuItem(item *MenuItem) { + C.show_menu_item( + C.int(item.id), + ) +} + //export systray_ready func systray_ready() { systrayReady() } +//export systray_on_exit +func systray_on_exit() { + systrayExit() +} + //export systray_menu_item_selected func systray_menu_item_selected(cID C.int) { systrayMenuItemSelected(int32(cID)) diff --git a/vendor/github.com/getlantern/systray/systray_windows.go b/vendor/github.com/getlantern/systray/systray_windows.go index 7630c8222..26a0f8074 100644 --- a/vendor/github.com/getlantern/systray/systray_windows.go +++ b/vendor/github.com/getlantern/systray/systray_windows.go @@ -1,90 +1,649 @@ +// +build windows + package systray import ( - "fmt" + "crypto/md5" + "encoding/hex" "io/ioutil" "os" "path/filepath" "syscall" - "runtime" "unsafe" - "github.com/getlantern/filepersist" + "golang.org/x/sys/windows" ) +// Helpful sources: https://github.com/golang/exp/blob/master/shiny/driver/internal/win32 + var ( - iconFiles = make([]*os.File, 0) - dllDir = filepath.Join(os.Getenv("APPDATA"), "systray") - dllFileName = "systray" + runtime.GOARCH + ".dll" - dllFile = filepath.Join(dllDir, dllFileName) - - - mod = syscall.NewLazyDLL(dllFile) - _nativeLoop = mod.NewProc("nativeLoop") - _quit = mod.NewProc("quit") - _setIcon = mod.NewProc("setIcon") - _setTitle = mod.NewProc("setTitle") - _setTooltip = mod.NewProc("setTooltip") - _add_or_update_menu_item = mod.NewProc("add_or_update_menu_item") + k32 = windows.NewLazySystemDLL("Kernel32.dll") + s32 = windows.NewLazySystemDLL("Shell32.dll") + u32 = windows.NewLazySystemDLL("User32.dll") + pGetModuleHandle = k32.NewProc("GetModuleHandleW") + pShellNotifyIcon = s32.NewProc("Shell_NotifyIconW") + pCreatePopupMenu = u32.NewProc("CreatePopupMenu") + pCreateWindowEx = u32.NewProc("CreateWindowExW") + pDefWindowProc = u32.NewProc("DefWindowProcW") + pDeleteMenu = u32.NewProc("DeleteMenu") + pDestroyWindow = u32.NewProc("DestroyWindow") + pDispatchMessage = u32.NewProc("DispatchMessageW") + pGetCursorPos = u32.NewProc("GetCursorPos") + pGetMenuItemID = u32.NewProc("GetMenuItemID") + pGetMessage = u32.NewProc("GetMessageW") + pInsertMenuItem = u32.NewProc("InsertMenuItemW") + pLoadIcon = u32.NewProc("LoadIconW") + pLoadImage = u32.NewProc("LoadImageW") + pLoadCursor = u32.NewProc("LoadCursorW") + pPostMessage = u32.NewProc("PostMessageW") + pPostQuitMessage = u32.NewProc("PostQuitMessage") + pRegisterClass = u32.NewProc("RegisterClassExW") + pRegisterWindowMessage = u32.NewProc("RegisterWindowMessageW") + pSetForegroundWindow = u32.NewProc("SetForegroundWindow") + pSetMenuInfo = u32.NewProc("SetMenuInfo") + pSetMenuItemInfo = u32.NewProc("SetMenuItemInfoW") + pShowWindow = u32.NewProc("ShowWindow") + pTrackPopupMenu = u32.NewProc("TrackPopupMenu") + pTranslateMessage = u32.NewProc("TranslateMessage") + pUnregisterClass = u32.NewProc("UnregisterClassW") + pUpdateWindow = u32.NewProc("UpdateWindow") ) -func init() { - // Write DLL to file - b, err := Asset(dllFileName) +// Contains window class information. +// It is used with the RegisterClassEx and GetClassInfoEx functions. +// https://msdn.microsoft.com/en-us/library/ms633577.aspx +type wndClassEx struct { + Size, Style uint32 + WndProc uintptr + ClsExtra, WndExtra int32 + Instance, Icon, Cursor, Background windows.Handle + MenuName, ClassName *uint16 + IconSm windows.Handle +} + +// Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function. +// https://msdn.microsoft.com/en-us/library/ms633587.aspx +func (w *wndClassEx) register() error { + w.Size = uint32(unsafe.Sizeof(*w)) + res, _, err := pRegisterClass.Call(uintptr(unsafe.Pointer(w))) + if res == 0 { + return err + } + return nil +} + +// Unregisters a window class, freeing the memory required for the class. +// https://msdn.microsoft.com/en-us/library/ms644899.aspx +func (w *wndClassEx) unregister() error { + res, _, err := pUnregisterClass.Call( + uintptr(unsafe.Pointer(w.ClassName)), + uintptr(w.Instance), + ) + if res == 0 { + return err + } + return nil +} + +// Contains information that the system needs to display notifications in the notification area. +// Used by Shell_NotifyIcon. +// https://msdn.microsoft.com/en-us/library/windows/desktop/bb773352(v=vs.85).aspx +// https://msdn.microsoft.com/en-us/library/windows/desktop/bb762159 +type notifyIconData struct { + Size uint32 + Wnd windows.Handle + ID, Flags, CallbackMessage uint32 + Icon windows.Handle + Tip [128]uint16 + State, StateMask uint32 + Info [256]uint16 + Timeout, Version uint32 + InfoTitle [64]uint16 + InfoFlags uint32 + GuidItem windows.GUID + BalloonIcon windows.Handle +} + +func (nid *notifyIconData) add() error { + const NIM_ADD = 0x00000000 + res, _, err := pShellNotifyIcon.Call( + uintptr(NIM_ADD), + uintptr(unsafe.Pointer(nid)), + ) + if res == 0 { + return err + } + return nil +} + +func (nid *notifyIconData) modify() error { + const NIM_MODIFY = 0x00000001 + res, _, err := pShellNotifyIcon.Call( + uintptr(NIM_MODIFY), + uintptr(unsafe.Pointer(nid)), + ) + if res == 0 { + return err + } + return nil +} + +func (nid *notifyIconData) delete() error { + const NIM_DELETE = 0x00000002 + res, _, err := pShellNotifyIcon.Call( + uintptr(NIM_DELETE), + uintptr(unsafe.Pointer(nid)), + ) + if res == 0 { + return err + } + return nil +} + +// Contains information about a menu item. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647578(v=vs.85).aspx +type menuItemInfo struct { + Size, Mask, Type, State uint32 + ID uint32 + SubMenu, Checked, Unchecked windows.Handle + ItemData uintptr + TypeData *uint16 + Cch uint32 + Item windows.Handle +} + +// The POINT structure defines the x- and y- coordinates of a point. +// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspx +type point struct { + X, Y int32 +} + +// Contains information about loaded resources +type winTray struct { + instance, + icon, + cursor, + window, + menu windows.Handle + + loadedImages map[string]windows.Handle + nid *notifyIconData + wcex *wndClassEx + + wmSystrayMessage, + wmTaskbarCreated uint32 +} + +// Loads an image from file and shows it in tray. +// LoadImage: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx +// Shell_NotifyIcon: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762159(v=vs.85).aspx +func (t *winTray) setIcon(src string) error { + const IMAGE_ICON = 1 // Loads an icon + const LR_LOADFROMFILE = 0x00000010 // Loads the stand-alone image from the file + const NIF_ICON = 0x00000002 + + // Save and reuse handles of loaded images + h, ok := t.loadedImages[src] + if !ok { + srcPtr, err := windows.UTF16PtrFromString(src) + if err != nil { + return err + } + res, _, err := pLoadImage.Call( + 0, + uintptr(unsafe.Pointer(srcPtr)), + IMAGE_ICON, + 64, + 64, + LR_LOADFROMFILE, + ) + if res == 0 { + return err + } + h = windows.Handle(res) + t.loadedImages[src] = h + } + + t.nid.Icon = h + t.nid.Flags |= NIF_ICON + t.nid.Size = uint32(unsafe.Sizeof(*t.nid)) + + return t.nid.modify() +} + +// Sets tooltip on icon. +// Shell_NotifyIcon: https://msdn.microsoft.com/en-us/library/windows/desktop/bb762159(v=vs.85).aspx +func (t *winTray) setTooltip(src string) error { + const NIF_TIP = 0x00000004 + b, err := windows.UTF16FromString(src) if err != nil { - panic(fmt.Errorf("Unable to read " + dllFileName + ": %v", err)) + return err + } + copy(t.nid.Tip[:], b[:]) + t.nid.Flags |= NIF_TIP + t.nid.Size = uint32(unsafe.Sizeof(*t.nid)) + + return t.nid.modify() +} + +var wt winTray + +// WindowProc callback function that processes messages sent to a window. +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx +func (t *winTray) wndProc(hWnd windows.Handle, message uint32, wParam, lParam uintptr) (lResult uintptr) { + const ( + WM_COMMAND = 0x0111 + WM_DESTROY = 0x0002 + WM_ENDSESSION = 0x16 + WM_RBUTTONUP = 0x0205 + WM_LBUTTONUP = 0x0202 + ) + switch message { + case WM_COMMAND: + menuId := int32(wParam) + if menuId != -1 { + systrayMenuItemSelected(menuId) + } + case WM_DESTROY: + // same as WM_ENDSESSION, but throws 0 exit code after all + defer pPostQuitMessage.Call(uintptr(int32(0))) + fallthrough + case WM_ENDSESSION: + if t.nid != nil { + t.nid.delete() + } + systrayExit() + case t.wmSystrayMessage: + switch lParam { + case WM_RBUTTONUP, WM_LBUTTONUP: + t.showMenu() + } + case t.wmTaskbarCreated: // on explorer.exe restarts + t.nid.add() + default: + // Calls the default window procedure to provide default processing for any window messages that an application does not process. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms633572(v=vs.85).aspx + lResult, _, _ = pDefWindowProc.Call( + uintptr(hWnd), + uintptr(message), + uintptr(wParam), + uintptr(lParam), + ) + } + return +} + +func (t *winTray) initInstance() error { + const IDI_APPLICATION = 32512 + const IDC_ARROW = 32512 // Standard arrow + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx + const SW_HIDE = 0 + const CW_USEDEFAULT = 0x80000000 + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx + const ( + WS_CAPTION = 0x00C00000 + WS_MAXIMIZEBOX = 0x00010000 + WS_MINIMIZEBOX = 0x00020000 + WS_OVERLAPPED = 0x00000000 + WS_SYSMENU = 0x00080000 + WS_THICKFRAME = 0x00040000 + + WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX + ) + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff729176 + const ( + CS_HREDRAW = 0x0002 + CS_VREDRAW = 0x0001 + ) + const NIF_MESSAGE = 0x00000001 + + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644931(v=vs.85).aspx + const WM_USER = 0x0400 + + const ( + className = "SystrayClass" + windowName = "" + ) + + t.wmSystrayMessage = WM_USER + 1 + + taskbarEventNamePtr, _ := windows.UTF16PtrFromString("TaskbarCreated") + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644947 + res, _, err := pRegisterWindowMessage.Call( + uintptr(unsafe.Pointer(taskbarEventNamePtr)), + ) + t.wmTaskbarCreated = uint32(res) + + t.loadedImages = make(map[string]windows.Handle) + + instanceHandle, _, err := pGetModuleHandle.Call(0) + if instanceHandle == 0 { + return err } + t.instance = windows.Handle(instanceHandle) - err = os.MkdirAll(dllDir, 0755) + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms648072(v=vs.85).aspx + iconHandle, _, err := pLoadIcon.Call(0, uintptr(IDI_APPLICATION)) + if iconHandle == 0 { + return err + } + t.icon = windows.Handle(iconHandle) + + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms648391(v=vs.85).aspx + cursorHandle, _, err := pLoadCursor.Call(0, uintptr(IDC_ARROW)) + if cursorHandle == 0 { + return err + } + t.cursor = windows.Handle(cursorHandle) + + classNamePtr, err := windows.UTF16PtrFromString(className) if err != nil { - panic(fmt.Errorf("Unable to create directory %v to hold " + dllFileName + ": %v", dllDir, err)) + return err } - err = filepersist.Save(dllFile, b, 0644) + windowNamePtr, err := windows.UTF16PtrFromString(windowName) if err != nil { - panic(fmt.Errorf("Unable to save " + dllFileName + " to %v: %v", dllFile, err)) + return err + } + + t.wcex = &wndClassEx{ + Style: CS_HREDRAW | CS_VREDRAW, + WndProc: windows.NewCallback(t.wndProc), + Instance: t.instance, + Icon: t.icon, + Cursor: t.cursor, + Background: windows.Handle(6), // (COLOR_WINDOW + 1) + ClassName: classNamePtr, + IconSm: t.icon, } + if err := t.wcex.register(); err != nil { + return err + } + + windowHandle, _, err := pCreateWindowEx.Call( + uintptr(0), + uintptr(unsafe.Pointer(classNamePtr)), + uintptr(unsafe.Pointer(windowNamePtr)), + uintptr(WS_OVERLAPPEDWINDOW), + uintptr(CW_USEDEFAULT), + uintptr(CW_USEDEFAULT), + uintptr(CW_USEDEFAULT), + uintptr(CW_USEDEFAULT), + uintptr(0), + uintptr(0), + uintptr(t.instance), + uintptr(0), + ) + if windowHandle == 0 { + return err + } + t.window = windows.Handle(windowHandle) + + pShowWindow.Call( + uintptr(t.window), + uintptr(SW_HIDE), + ) + + pUpdateWindow.Call( + uintptr(t.window), + ) + + t.nid = ¬ifyIconData{ + Wnd: windows.Handle(t.window), + ID: 100, + Flags: NIF_MESSAGE, + CallbackMessage: t.wmSystrayMessage, + } + t.nid.Size = uint32(unsafe.Sizeof(*t.nid)) + + return t.nid.add() } -func nativeLoop() { - _nativeLoop.Call( - syscall.NewCallbackCDecl(systray_ready), - syscall.NewCallbackCDecl(systray_menu_item_selected)) +func (t *winTray) createMenu() error { + const MIM_APPLYTOSUBMENUS = 0x80000000 // Settings apply to the menu and all of its submenus + + menuHandle, _, err := pCreatePopupMenu.Call() + if menuHandle == 0 { + return err + } + t.menu = windows.Handle(menuHandle) + + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647575(v=vs.85).aspx + mi := struct { + Size, Mask, Style, Max uint32 + Background windows.Handle + ContextHelpID uint32 + MenuData uintptr + }{ + Mask: MIM_APPLYTOSUBMENUS, + } + mi.Size = uint32(unsafe.Sizeof(mi)) + + res, _, err := pSetMenuInfo.Call( + uintptr(t.menu), + uintptr(unsafe.Pointer(&mi)), + ) + if res == 0 { + return err + } + return nil } -func quit() { - _quit.Call() - for _, f := range iconFiles { - err := os.Remove(f.Name()) - if err != nil { - log.Debugf("Unable to delete temporary icon file %v: %v", f.Name(), err) +func (t *winTray) addOrUpdateMenuItem(menuId int32, title string, disabled, checked bool) error { + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647578(v=vs.85).aspx + const ( + MIIM_FTYPE = 0x00000100 + MIIM_STRING = 0x00000040 + MIIM_ID = 0x00000002 + MIIM_STATE = 0x00000001 + ) + const MFT_STRING = 0x00000000 + const ( + MFS_CHECKED = 0x00000008 + MFS_DISABLED = 0x00000003 + ) + titlePtr, err := windows.UTF16PtrFromString(title) + if err != nil { + return err + } + + mi := menuItemInfo{ + Mask: MIIM_FTYPE | MIIM_STRING | MIIM_ID | MIIM_STATE, + Type: MFT_STRING, + ID: uint32(menuId), + TypeData: titlePtr, + Cch: uint32(len(title)), + } + if disabled { + mi.State |= MFS_DISABLED + } + if checked { + mi.State |= MFS_CHECKED + } + mi.Size = uint32(unsafe.Sizeof(mi)) + + // The return value is the identifier of the specified menu item. + // If the menu item identifier is NULL or if the specified item opens a submenu, the return value is -1. + // If the given menu identifier is not found (becase we deleted the menu item when hiding it), + // the call will return the next integer that is available as an existing menu item. + res, _, err := pGetMenuItemID.Call(uintptr(t.menu), uintptr(menuId)) + if int32(res) == -1 || int32(res) != menuId { + res, _, err = pInsertMenuItem.Call( + uintptr(t.menu), + uintptr(menuId), + 1, + uintptr(unsafe.Pointer(&mi)), + ) + if res == 0 { + return err + } + } else { + res, _, err = pSetMenuItemInfo.Call( + uintptr(t.menu), + uintptr(menuId), + 0, + uintptr(unsafe.Pointer(&mi)), + ) + if res == 0 { + return err + } + } + + return nil +} + +func (t *winTray) addSeparatorMenuItem(menuId int32) error { + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647578(v=vs.85).aspx + const ( + MIIM_FTYPE = 0x00000100 + MIIM_ID = 0x00000002 + MIIM_STATE = 0x00000001 + ) + const MFT_SEPARATOR = 0x00000800 + + mi := menuItemInfo{ + Mask: MIIM_FTYPE | MIIM_ID | MIIM_STATE, + Type: MFT_SEPARATOR, + ID: uint32(menuId), + } + + mi.Size = uint32(unsafe.Sizeof(mi)) + + res, _, err := pInsertMenuItem.Call( + uintptr(t.menu), + uintptr(menuId), + 1, + uintptr(unsafe.Pointer(&mi)), + ) + if res == 0 { + return err + } + + return nil +} + +func (t *winTray) hideMenuItem(menuId int32) error { + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647629(v=vs.85).aspx + const MF_BYCOMMAND = 0x00000000 + const ERROR_SUCCESS syscall.Errno = 0 + + res, _, err := pDeleteMenu.Call( + uintptr(t.menu), + uintptr(uint32(menuId)), + MF_BYCOMMAND, + ) + if res == 0 && err.(syscall.Errno) != ERROR_SUCCESS { + return err + } + + return nil +} + +func (t *winTray) showMenu() error { + const ( + TPM_BOTTOMALIGN = 0x0020 + TPM_LEFTALIGN = 0x0000 + ) + p := point{} + res, _, err := pGetCursorPos.Call(uintptr(unsafe.Pointer(&p))) + if res == 0 { + return err + } + pSetForegroundWindow.Call(uintptr(t.window)) + + res, _, err = pTrackPopupMenu.Call( + uintptr(t.menu), + TPM_BOTTOMALIGN|TPM_LEFTALIGN, + uintptr(p.X), + uintptr(p.Y), + 0, + uintptr(t.window), + 0, + ) + if res == 0 { + return err + } + + return nil +} + +func nativeLoop() { + if err := wt.initInstance(); err != nil { + log.Errorf("Unable to init instance: %v", err) + return + } + + if err := wt.createMenu(); err != nil { + log.Errorf("Unable to create menu: %v", err) + return + } + + defer func() { + pDestroyWindow.Call(uintptr(wt.window)) + wt.wcex.unregister() + }() + + go systrayReady() + + // Main message pump. + m := &struct { + WindowHandle windows.Handle + Message uint32 + Wparam uintptr + Lparam uintptr + Time uint32 + Pt point + }{} + for { + ret, _, err := pGetMessage.Call(uintptr(unsafe.Pointer(m)), 0, 0, 0) + + // If the function retrieves a message other than WM_QUIT, the return value is nonzero. + // If the function retrieves the WM_QUIT message, the return value is zero. + // If there is an error, the return value is -1 + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx + switch int32(ret) { + case -1: + log.Errorf("Error at message loop: %v", err) + return + case 0: + return + default: + pTranslateMessage.Call(uintptr(unsafe.Pointer(m))) + pDispatchMessage.Call(uintptr(unsafe.Pointer(m))) } } } +func quit() { + const WM_CLOSE = 0x0010 + + pPostMessage.Call( + uintptr(wt.window), + WM_CLOSE, + 0, + 0, + ) +} + // SetIcon sets the systray icon. // iconBytes should be the content of .ico for windows and .ico/.jpg/.png // for other platforms. func SetIcon(iconBytes []byte) { - f, err := ioutil.TempFile("", "systray_temp_icon") - if err != nil { - log.Errorf("Unable to create temp icon: %v", err) - return - } - defer f.Close() - _, err = f.Write(iconBytes) - if err != nil { - log.Errorf("Unable to write icon to temp file %v: %v", f.Name(), f) - return + bh := md5.Sum(iconBytes) + dataHash := hex.EncodeToString(bh[:]) + iconFilePath := filepath.Join(os.TempDir(), "systray_temp_icon_"+dataHash) + + if _, err := os.Stat(iconFilePath); os.IsNotExist(err) { + if err := ioutil.WriteFile(iconFilePath, iconBytes, 0644); err != nil { + log.Errorf("Unable to write icon data to temp file: %v", err) + return + } } - // Need to close file before we load it to make sure contents is flushed. - f.Close() - name, err := strUTF16(f.Name()) - if err != nil { - log.Errorf("Unable to convert name to string pointer: %v", err) + + if err := wt.setIcon(iconFilePath); err != nil { + log.Errorf("Unable to set icon: %v", err) return } - _setIcon.Call(name.Raw()) } // SetTitle sets the systray title, only available on Mac. @@ -92,66 +651,44 @@ func SetTitle(title string) { // do nothing } +// SetIcon sets the icon of a menu item. Only available on Mac. +func (item *MenuItem) SetIcon(iconBytes []byte) { + // do nothing +} + // SetTooltip sets the systray tooltip to display on mouse hover of the tray icon, // only available on Mac and Windows. func SetTooltip(tooltip string) { - t, err := strUTF16(tooltip) - if err != nil { - log.Errorf("Unable to convert tooltip to string pointer: %v", err) + if err := wt.setTooltip(tooltip); err != nil { + log.Errorf("Unable to set tooltip: %v", err) return } - _setTooltip.Call(t.Raw()) } func addOrUpdateMenuItem(item *MenuItem) { - var disabled = 0 - if item.disabled { - disabled = 1 - } - var checked = 0 - if item.checked { - checked = 1 - } - title, err := strUTF16(item.title) + err := wt.addOrUpdateMenuItem(item.id, item.title, item.disabled, item.checked) if err != nil { - log.Errorf("Unable to convert title to string pointer: %v", err) + log.Errorf("Unable to addOrUpdateMenuItem: %v", err) return } - tooltip, err := strUTF16(item.tooltip) +} + +func addSeparator(id int32) { + err := wt.addSeparatorMenuItem(id) if err != nil { - log.Errorf("Unable to convert tooltip to string pointer: %v", err) + log.Errorf("Unable to addSeparator: %v", err) return } - _add_or_update_menu_item.Call( - uintptr(item.id), - title.Raw(), - tooltip.Raw(), - uintptr(disabled), - uintptr(checked), - ) -} - -type utf16 []uint16 - -// Raw returns the underlying *wchar_t of an utf16 so we can pass to DLL -func (u utf16) Raw() uintptr { - return uintptr(unsafe.Pointer(&u[0])) } -// strUTF16 converts a Go string into a utf16 byte sequence -func strUTF16(s string) (utf16, error) { - return syscall.UTF16FromString(s) -} - -// systray_ready takes an ignored parameter just so we can compile a callback -// (for some reason in Go 1.4.x, syscall.NewCallback panics if there's no -// parameter to the function). -func systray_ready(ignore uintptr) uintptr { - systrayReady() - return 0 +func hideMenuItem(item *MenuItem) { + err := wt.hideMenuItem(item.id) + if err != nil { + log.Errorf("Unable to hideMenuItem: %v", err) + return + } } -func systray_menu_item_selected(id uintptr) uintptr { - systrayMenuItemSelected(int32(id)) - return 0 +func showMenuItem(item *MenuItem) { + addOrUpdateMenuItem(item) } diff --git a/vendor/github.com/getlantern/systray/systraydll_windows.go b/vendor/github.com/getlantern/systray/systraydll_windows.go deleted file mode 100644 index 2bf4b4e95..000000000 --- a/vendor/github.com/getlantern/systray/systraydll_windows.go +++ /dev/null @@ -1,248 +0,0 @@ -// Code generated by go-bindata. -// sources: -// dll/systray386.dll -// dll/systrayamd64.dll -// DO NOT EDIT! - -package systray - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "reflect" - "strings" - "time" - "unsafe" -) - -func bindataRead(data, name string) ([]byte, error) { - var empty [0]byte - sx := (*reflect.StringHeader)(unsafe.Pointer(&data)) - b := empty[:] - bx := (*reflect.SliceHeader)(unsafe.Pointer(&b)) - bx.Data = sx.Data - bx.Len = len(data) - bx.Cap = bx.Len - return b, nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -func (fi bindataFileInfo) Name() string { - return fi.name -} -func (fi bindataFileInfo) Size() int64 { - return fi.size -} -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} -func (fi bindataFileInfo) IsDir() bool { - return false -} -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var _systray386Dll = "\x4d\x5a\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01\x00\x00\x0e\x1f\xba\x0e\x00\xb4\x09\xcd\x21\xb8\x01\x4c\xcd\x21\x54\x68\x69\x73\x20\x70\x72\x6f\x67\x72\x61\x6d\x20\x63\x61\x6e\x6e\x6f\x74\x20\x62\x65\x20\x72\x75\x6e\x20\x69\x6e\x20\x44\x4f\x53\x20\x6d\x6f\x64\x65\x2e\x0d\x0d\x0a\x24\x00\x00\x00\x00\x00\x00\x00\xa2\xdc\x46\xa6\xe6\xbd\x28\xf5\xe6\xbd\x28\xf5\xe6\xbd\x28\xf5\x52\x21\xd9\xf5\xee\xbd\x28\xf5\x52\x21\xdb\xf5\x89\xbd\x28\xf5\x52\x21\xda\xf5\xfe\xbd\x28\xf5\x88\xe6\x2b\xf4\xf7\xbd\x28\xf5\x88\xe6\x2d\xf4\xf3\xbd\x28\xf5\x88\xe6\x2c\xf4\xe9\xbd\x28\xf5\x3b\x42\xe3\xf5\xef\xbd\x28\xf5\xe6\xbd\x29\xf5\x80\xbd\x28\xf5\x34\xe6\x21\xf4\xe5\xbd\x28\xf5\x34\xe6\x28\xf4\xe7\xbd\x28\xf5\x34\xe6\xd7\xf5\xe7\xbd\x28\xf5\x34\xe6\x2a\xf4\xe7\xbd\x28\xf5\x52\x69\x63\x68\xe6\xbd\x28\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x45\x00\x00\x4c\x01\x06\x00\x06\x7e\xb7\x57\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x02\x21\x0b\x01\x0e\x00\x00\xe8\x00\x00\x00\x92\x00\x00\x00\x00\x00\x00\x3a\x1b\x00\x00\x00\x10\x00\x00\x00\x00\x01\x00\x00\x00\x00\x10\x00\x10\x00\x00\x00\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x01\x00\x00\x04\x00\x00\x00\x00\x00\x00\x02\x00\x40\x01\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x70\x5e\x01\x00\xa1\x00\x00\x00\x14\x5f\x01\x00\x64\x00\x00\x00\x00\xa0\x01\x00\xe0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x01\x00\x20\x0f\x00\x00\x80\x55\x01\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x55\x01\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x64\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x74\x65\x78\x74\x00\x00\x00\xeb\xe7\x00\x00\x00\x10\x00\x00\x00\xe8\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x60\x2e\x72\x64\x61\x74\x61\x00\x00\x26\x67\x00\x00\x00\x00\x01\x00\x00\x68\x00\x00\x00\xec\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x40\x2e\x64\x61\x74\x61\x00\x00\x00\xac\x14\x00\x00\x00\x70\x01\x00\x00\x08\x00\x00\x00\x54\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\xc0\x2e\x67\x66\x69\x64\x73\x00\x00\xa4\x00\x00\x00\x00\x90\x01\x00\x00\x02\x00\x00\x00\x5c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x40\x2e\x72\x73\x72\x63\x00\x00\x00\xe0\x01\x00\x00\x00\xa0\x01\x00\x00\x02\x00\x00\x00\x5e\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x40\x2e\x72\x65\x6c\x6f\x63\x00\x00\x20\x0f\x00\x00\x00\xb0\x01\x00\x00\x10\x00\x00\x00\x60\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x8b\xec\x8b\x4d\x0c\x56\x57\x8b\x7d\x08\x85\xc9\x75\x03\x8d\x4f\x20\x8b\x45\x10\x89\x47\x30\x8b\x45\x14\x89\x47\x34\x8d\x47\x18\x50\x57\x68\x23\x11\x00\x10\x51\xe8\x3a\x1a\x00\x00\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x0d\x7e\x1e\x0f\xb7\xf6\x81\xce\x00\x00\x07\x80\xeb\x13\x8b\x4f\x04\x0f\xb7\x01\x50\x51\x6a\x02\x57\xe8\x09\x00\x00\x00\x83\xc4\x10\x5f\x8b\xc6\x5e\x5d\xc3\x55\x8b\xec\xff\x75\x14\x8b\x45\x08\xff\x75\x10\xff\x75\x0c\xff\x70\x1c\xff\x70\x18\xe8\x31\x1a\x00\x00\x83\xc4\x14\x85\xc0\x7e\x08\x0f\xb7\xc0\x0d\x00\x00\x07\x80\x5d\xc3\x55\x8b\xec\x56\x8b\x75\x08\xff\x76\x1c\xff\x76\x18\xe8\x51\x1a\x00\x00\x83\x66\x18\x00\x83\x66\x1c\x00\x59\x59\x5e\x5d\xc3\x55\x8b\xec\x8b\x45\x0c\x33\xd2\x56\xbe\xb0\x01\x01\x10\x85\xc0\x74\x10\x8b\xd0\x8b\xf0\x8d\x4a\x01\x8a\x02\x42\x84\xc0\x75\xf9\x2b\xd1\x8b\x4d\x08\x8d\x42\x01\x83\x61\x04\x00\x83\x61\x0c\x00\x89\x31\x89\x41\x08\x5e\x5d\xc3\x55\x8b\xec\x8b\x45\x0c\x56\x57\x33\xff\xbe\x50\x55\x01\x10\x8b\xd7\x85\xc0\x74\x16\x8b\xd0\x8b\xf0\x8d\x4a\x02\x66\x8b\x02\x83\xc2\x02\x66\x3b\xc7\x75\xf5\x2b\xd1\xd1\xfa\x8b\x4d\x08\x8d\x04\x55\x02\x00\x00\x00\x89\x79\x04\x89\x79\x0c\x5f\x89\x31\x89\x41\x08\x5e\x5d\xc3\x55\x8b\xec\x8b\x45\x28\x85\xc0\x74\x6a\x8b\x4d\x0c\x8b\x55\x10\x53\x8b\x5d\x1c\x57\x8b\x7d\x20\x83\xe9\x00\x74\x2a\x83\xe9\x01\x75\x28\x84\xd2\x74\x06\x0f\xb6\xca\x41\xeb\x05\xb9\x00\x01\x00\x00\x89\x08\x8b\x4d\x14\x89\x48\x08\x8b\x4d\x18\x89\x48\x0c\x89\x58\x10\x89\x78\x14\xeb\x06\x83\x20\x00\x8b\x4d\x18\x56\x8b\x70\x30\x85\xf6\x74\x1c\xff\x70\x34\xff\x75\x24\x57\x53\x51\xff\x75\x14\x8b\xce\x52\xff\x75\x0c\xff\x75\x08\xe8\x64\x10\x00\x00\xff\xd6\x5e\x5f\x5b\x5d\xc2\x24\x00\x55\x8b\xec\x8b\x45\x0c\x0b\x45\x10\x74\x2d\x8b\x55\x08\x8b\x4a\x08\x8b\x42\x0c\x23\x4d\x0c\x23\x45\x10\x0b\xc8\x74\x16\x8b\x42\x10\x8b\x4a\x14\x23\x45\x0c\x23\x4d\x10\x3b\x42\x10\x75\x05\x3b\x4a\x14\x74\x04\x32\xc0\x5d\xc3\xb0\x01\x5d\xc3\x55\x8b\xec\x83\xec\x10\xa0\x13\x57\x01\x10\x8b\x55\x0c\x8b\xca\x56\x8b\x75\x08\x81\xe9\x60\x56\x01\x10\x81\xc9\x00\x00\x00\x0b\x8b\x02\x89\x45\xf4\x8b\x42\x04\x89\x45\xf8\x8b\x42\x08\x83\xc2\x0c\x89\x4d\xf0\x8b\x4d\x1c\x89\x45\xfc\x8b\x46\x04\x51\x83\x61\x04\x00\xff\x75\x18\x89\x01\x8b\x46\x04\xff\x75\x14\xff\x75\x10\x0f\xb7\x00\x83\x61\x14\x00\x89\x41\x08\xc7\x41\x0c\x02\x00\x00\x00\x89\x51\x10\x0f\xb7\x02\x89\x41\x18\x8d\x45\xf0\x50\xc7\x41\x1c\x01\x00\x00\x00\xff\x76\x1c\xff\x76\x18\xe8\xce\x18\x00\x00\x83\xc4\x1c\x5e\x8b\xe5\x5d\xc3\xcc\xb8\x01\x00\x00\x00\xc2\x0c\x00\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x83\xec\x0c\x8d\x45\xf8\x56\x50\x8b\xf1\xff\x15\x58\x01\x01\x10\x85\xc0\x75\x38\xff\x15\xfc\x00\x01\x10\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x8b\xf0\x56\x6a\x00\x68\x00\x31\x00\x00\xff\x15\x0c\x00\x01\x10\x6a\x00\x56\x68\x24\x55\x01\x10\x68\x08\x55\x01\x10\xe8\x29\x05\x00\x00\x83\xc4\x10\x5e\x8b\xe5\x5d\xc3\x56\xff\x15\x54\x01\x01\x10\x6a\x00\x56\x6a\x00\xff\x75\xfc\xff\x75\xf8\x6a\x20\xff\x35\x8c\x84\x01\x10\xff\x15\x50\x01\x01\x10\x5e\x8b\xe5\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x83\xec\x34\x56\x8d\x45\xd0\xc7\x45\xd0\x30\x00\x00\x00\x50\x6a\x01\x51\xff\x35\x8c\x84\x01\x10\xc7\x45\xd4\x20\x00\x00\x00\xff\x15\x4c\x01\x01\x10\x85\xc0\x75\x3b\xff\x15\xfc\x00\x01\x10\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x8b\xf0\x56\x6a\x00\x68\x00\x31\x00\x00\xff\x15\x0c\x00\x01\x10\x6a\x00\x56\x68\x3c\x55\x01\x10\x68\x08\x55\x01\x10\xe8\x94\x04\x00\x00\x83\xc4\x10\x83\xc8\xff\x5e\x8b\xe5\x5d\xc3\x8b\x45\xf0\x5e\x8b\xe5\x5d\xc3\xcc\x55\x8b\xec\x83\xe4\xf8\x8b\x4d\x0c\x8b\xc1\x83\xe8\x02\x74\x7c\x2d\x24\x01\x00\x00\x74\x56\x2d\xdb\x02\x00\x00\x74\x16\xff\x75\x14\xff\x75\x10\x51\xff\x75\x08\xff\x15\x44\x01\x01\x10\x8b\xe5\x5d\xc2\x10\x00\x8b\x4d\x14\x8b\xc1\x2d\x02\x02\x00\x00\x74\x1d\x83\xe8\x03\x74\x18\x51\xff\x75\x10\x68\x01\x04\x00\x00\xff\x75\x08\xff\x15\x44\x01\x01\x10\x8b\xe5\x5d\xc2\x10\x00\x8b\x4d\x08\xe8\xab\xfe\xff\xff\x33\xc0\x8b\xe5\x5d\xc2\x10\x00\x8b\x4d\x10\xe8\x1b\xff\xff\xff\x83\xf8\xff\x74\x1a\x50\xff\x15\xc8\x80\x01\x10\x83\xc4\x04\x33\xc0\x8b\xe5\x5d\xc2\x10\x00\x6a\x00\xff\x15\x48\x01\x01\x10\x33\xc0\x8b\xe5\x5d\xc2\x10\x00\xcc\xcc\xcc\xcc\x55\x8b\xec\x83\xec\x30\x68\x00\x7f\x00\x00\x6a\x00\xc7\x45\xd0\x30\x00\x00\x00\xc7\x45\xd4\x03\x00\x00\x00\xc7\x45\xd8\x60\x13\x00\x10\xc7\x45\xdc\x00\x00\x00\x00\xc7\x45\xe0\x00\x00\x00\x00\x89\x4d\xe4\xff\x15\x40\x01\x01\x10\x68\x00\x7f\x00\x00\x6a\x00\x89\x45\xe8\xff\x15\x3c\x01\x01\x10\x68\x00\x7f\x00\x00\x6a\x00\x89\x45\xec\xc7\x45\xf0\x06\x00\x00\x00\xc7\x45\xf4\x00\x00\x00\x00\xc7\x45\xf8\x54\x55\x01\x10\xff\x15\x40\x01\x01\x10\x89\x45\xfc\x8d\x45\xd0\x50\xff\x15\x38\x01\x01\x10\x8b\xe5\x5d\xc3\xcc\x55\x8b\xec\x8b\x45\x0c\x83\xec\x38\xa3\xc8\x80\x01\x10\x56\x6a\x00\xff\x15\x08\x00\x01\x10\x8b\xf0\x8b\xce\xe8\x60\xff\xff\xff\x6a\x00\x56\x6a\x00\x6a\x00\x6a\x00\x68\x00\x00\x00\x80\x6a\x00\x68\x00\x00\x00\x80\x68\x00\x00\xcf\x00\x68\x50\x55\x01\x10\x68\x54\x55\x01\x10\x6a\x00\xff\x15\x34\x01\x01\x10\x8b\xf0\x85\xf6\x75\x0f\xa3\xcc\x80\x01\x10\xb8\x01\x00\x00\x00\x5e\x8b\xe5\x5d\xc3\x6a\x00\x56\xff\x15\x30\x01\x01\x10\x56\xff\x15\x5c\x01\x01\x10\x89\x35\xcc\x80\x01\x10\xff\x15\x2c\x01\x01\x10\x8d\x4d\xe4\xa3\x8c\x84\x01\x10\x51\x50\xc7\x45\xe4\x1c\x00\x00\x00\xc7\x45\xe8\x10\x00\x00\x80\xc7\x45\xec\x00\x00\x00\x08\xff\x15\x28\x01\x01\x10\x85\xc0\x74\xb1\xa1\xcc\x80\x01\x10\x68\xd0\x80\x01\x10\x6a\x00\xc7\x05\xd0\x80\x01\x10\xbc\x03\x00\x00\xa3\xd4\x80\x01\x10\xc7\x05\xd8\x80\x01\x10\x64\x00\x00\x00\xc7\x05\xe0\x80\x01\x10\x01\x04\x00\x00\xc7\x05\xdc\x80\x01\x10\x01\x00\x00\x00\xff\x15\x04\x01\x01\x10\x85\xc0\x0f\x84\x6a\xff\xff\xff\x6a\x00\xff\x55\x08\x8b\x35\x24\x01\x01\x10\x8d\x45\xc8\x83\xc4\x04\x6a\x00\x6a\x00\x6a\x00\x50\xff\xd6\x85\xc0\x74\x33\x53\x8b\x1d\x1c\x01\x01\x10\x57\x8b\x3d\x20\x01\x01\x10\x0f\x1f\x80\x00\x00\x00\x00\x8d\x45\xc8\x50\xff\xd7\x8d\x45\xc8\x50\xff\xd3\x6a\x00\x6a\x00\x6a\x00\x8d\x45\xc8\x50\xff\xd6\x85\xc0\x75\xe4\x5f\x5b\x33\xc0\x5e\x8b\xe5\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x6a\x10\x6a\x40\x6a\x40\x6a\x01\xff\x75\x08\x6a\x00\xff\x15\x18\x01\x01\x10\x85\xc0\x75\x37\x56\xff\x15\xfc\x00\x01\x10\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x8b\xf0\x56\x6a\x00\x68\x00\x31\x00\x00\xff\x15\x0c\x00\x01\x10\x6a\x00\x56\x68\x70\x55\x01\x10\x68\x08\x55\x01\x10\xe8\xc5\x01\x00\x00\x83\xc4\x10\x5e\x5d\xc3\x68\xd0\x80\x01\x10\x6a\x01\xa3\xe4\x80\x01\x10\xc7\x05\xdc\x80\x01\x10\x02\x00\x00\x00\xff\x15\x04\x01\x01\x10\x5d\xc3\xcc\x55\x8b\xec\x68\x80\x00\x00\x00\xff\x75\x08\x68\x80\x00\x00\x00\x68\xe8\x80\x01\x10\xe8\x92\x30\x00\x00\x83\xc4\x10\xc7\x05\xdc\x80\x01\x10\x04\x00\x00\x00\x68\xd0\x80\x01\x10\x6a\x01\xff\x15\x04\x01\x01\x10\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x83\xe4\xf8\x83\xec\x64\x8b\x4d\x0c\x53\x56\x57\xc7\x44\x24\x10\x30\x00\x00\x00\x8d\x51\x02\xc7\x44\x24\x14\x61\x01\x00\x00\xc7\x44\x24\x18\x00\x00\x00\x00\x89\x4c\x24\x34\x66\x90\x66\x8b\x01\x83\xc1\x02\x66\x85\xc0\x75\xf5\x8b\x75\x08\x2b\xca\xd1\xf9\x89\x74\x24\x30\x8d\x41\x01\xb9\x03\x00\x00\x00\x89\x44\x24\x38\x33\xc0\x66\x83\x7d\x14\x01\x0f\x44\xc1\x66\x83\x7d\x18\x01\x89\x44\x24\x1c\x75\x07\x83\xc8\x08\x89\x44\x24\x1c\xff\x35\x8c\x84\x01\x10\xff\x15\x14\x01\x01\x10\x8b\xd8\x33\xff\x85\xdb\x0f\x8e\x92\x00\x00\x00\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x8d\x44\x24\x40\xc7\x44\x24\x40\x30\x00\x00\x00\x50\x6a\x01\x57\xff\x35\x8c\x84\x01\x10\xc7\x44\x24\x54\x20\x00\x00\x00\xff\x15\x4c\x01\x01\x10\x85\xc0\x75\x38\xff\x15\xfc\x00\x01\x10\x6a\x00\x6a\x00\x6a\x00\x6a\x00\x8b\xf0\x56\x6a\x00\x68\x00\x31\x00\x00\xff\x15\x0c\x00\x01\x10\x6a\x00\x56\x68\x3c\x55\x01\x10\x68\x08\x55\x01\x10\xe8\x78\x00\x00\x00\x8b\x75\x08\x83\xc4\x10\xeb\x0d\x8b\x44\x24\x60\x83\xf8\xff\x74\x04\x3b\xf0\x74\x07\x47\x3b\xfb\x7c\x8e\xeb\x14\x8d\x44\x24\x10\x50\x6a\x01\x57\xff\x35\x8c\x84\x01\x10\xff\x15\x10\x01\x01\x10\x3b\xfb\x75\x15\x8d\x44\x24\x10\x50\x6a\x01\x6a\xff\xff\x35\x8c\x84\x01\x10\xff\x15\x0c\x01\x01\x10\x5f\x5e\x5b\x8b\xe5\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x68\xd0\x80\x01\x10\x6a\x02\xff\x15\x04\x01\x01\x10\xc3\xcc\xcc\xb8\x90\x84\x01\x10\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x83\xe4\xf8\x51\x56\x8b\x75\x08\x6a\x01\xe8\x0d\x1a\x00\x00\x83\xc4\x04\x8d\x4d\x0c\x51\x6a\x00\x56\x50\xe8\xce\xff\xff\xff\xff\x70\x04\xff\x30\xe8\x9c\x2d\x00\x00\x83\xc4\x18\x5e\x8b\xe5\x5d\xc3\x3b\x0d\x04\x70\x01\x10\xf2\x75\x02\xf2\xc3\xf2\xe9\x60\x03\x00\x00\x55\x8b\xec\x8b\x45\x0c\x83\xe8\x00\x74\x33\x83\xe8\x01\x74\x20\x83\xe8\x01\x74\x11\x83\xe8\x01\x74\x05\x33\xc0\x40\xeb\x30\xe8\xf5\x04\x00\x00\xeb\x05\xe8\xcf\x04\x00\x00\x0f\xb6\xc0\xeb\x1f\xff\x75\x10\xff\x75\x08\xe8\x18\x00\x00\x00\x59\xeb\x10\x83\x7d\x10\x00\x0f\x95\xc0\x0f\xb6\xc0\x50\xe8\x17\x01\x00\x00\x59\x5d\xc2\x0c\x00\x6a\x10\x68\x98\x5a\x01\x10\xe8\x7c\x09\x00\x00\x6a\x00\xe8\x23\x05\x00\x00\x59\x84\xc0\x75\x07\x33\xc0\xe9\xe0\x00\x00\x00\xe8\x28\x04\x00\x00\x88\x45\xe3\xb3\x01\x88\x5d\xe7\x83\x65\xfc\x00\x83\x3d\xf4\x7a\x01\x10\x00\x74\x07\x6a\x07\xe8\xc5\x07\x00\x00\xc7\x05\xf4\x7a\x01\x10\x01\x00\x00\x00\xe8\x4a\x04\x00\x00\x84\xc0\x74\x65\xe8\xd0\x08\x00\x00\x68\xcb\x21\x00\x10\xe8\xb1\x06\x00\x00\xe8\x5d\x07\x00\x00\xc7\x04\x24\x48\x20\x00\x10\xe8\xa0\x06\x00\x00\xe8\x6a\x07\x00\x00\xc7\x04\x24\x80\x01\x01\x10\x68\x70\x01\x01\x10\xe8\x52\x2e\x00\x00\x59\x59\x85\xc0\x75\x29\xe8\xed\x03\x00\x00\x84\xc0\x74\x20\x68\x6c\x01\x01\x10\x68\x68\x01\x01\x10\xe8\xd8\x2d\x00\x00\x59\x59\xc7\x05\xf4\x7a\x01\x10\x02\x00\x00\x00\x32\xdb\x88\x5d\xe7\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x44\x00\x00\x00\x84\xdb\x0f\x85\x4c\xff\xff\xff\xe8\x2e\x07\x00\x00\x8b\xf0\x83\x3e\x00\x74\x1e\x56\xe8\x28\x05\x00\x00\x59\x84\xc0\x74\x13\xff\x75\x0c\x6a\x02\xff\x75\x08\x8b\x36\x8b\xce\xe8\x8a\x08\x00\x00\xff\xd6\xff\x05\xd0\x77\x01\x10\x33\xc0\x40\xe8\xca\x08\x00\x00\xc3\x8a\x5d\xe7\xff\x75\xe3\xe8\x83\x05\x00\x00\x59\xc3\x6a\x0c\x68\xb8\x5a\x01\x10\xe8\x6a\x08\x00\x00\xa1\xd0\x77\x01\x10\x85\xc0\x7f\x04\x33\xc0\xeb\x4f\x48\xa3\xd0\x77\x01\x10\xe8\x16\x03\x00\x00\x88\x45\xe4\x83\x65\xfc\x00\x83\x3d\xf4\x7a\x01\x10\x02\x74\x07\x6a\x07\xe8\xb8\x06\x00\x00\xe8\xb4\x03\x00\x00\x83\x25\xf4\x7a\x01\x10\x00\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x1b\x00\x00\x00\x6a\x00\xff\x75\x08\xe8\x41\x05\x00\x00\x59\x59\x33\xc9\x84\xc0\x0f\x95\xc1\x8b\xc1\xe8\x4f\x08\x00\x00\xc3\xe8\xa4\x03\x00\x00\xff\x75\xe4\xe8\x06\x05\x00\x00\x59\xc3\x6a\x0c\x68\xd8\x5a\x01\x10\xe8\xed\x07\x00\x00\x83\x65\xfc\x00\x8b\x7d\x0c\x83\xff\x01\x74\x0a\x83\xff\x02\x74\x05\x8b\x5d\x08\xeb\x31\xff\x75\x10\x57\x8b\x5d\x08\x53\xe8\xda\x00\x00\x00\x8b\xf0\x89\x75\xe4\x85\xf6\x0f\x84\xbe\x00\x00\x00\xff\x75\x10\x57\x53\xe8\xd8\xfd\xff\xff\x8b\xf0\x89\x75\xe4\x85\xf6\x0f\x84\xa7\x00\x00\x00\x83\xff\x01\x75\x07\x53\xe8\xde\x09\x00\x00\x59\xff\x75\x10\x57\x53\xe8\xf0\xf7\xff\xff\x8b\xf0\x89\x75\xe4\x83\xff\x01\x75\x2b\x85\xf6\x75\x1e\xff\x75\x10\x50\x53\xe8\xd8\xf7\xff\xff\xff\x75\x10\x56\x53\xe8\x93\xfd\xff\xff\xff\x75\x10\x56\x53\xe8\x74\x00\x00\x00\x83\xff\x01\x75\x04\x85\xf6\x74\x04\x85\xff\x75\x0b\x53\xe8\x30\x0a\x00\x00\x59\x85\xff\x74\x05\x83\xff\x03\x75\x48\xff\x75\x10\x57\x53\xe8\x62\xfd\xff\xff\x8b\xf0\x89\x75\xe4\x85\xf6\x74\x35\xff\x75\x10\x57\x53\xe8\x3a\x00\x00\x00\x8b\xf0\xeb\x24\x8b\x4d\xec\x8b\x01\x51\xff\x30\x68\x25\x18\x00\x10\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\x56\x02\x00\x00\x83\xc4\x18\xc3\x8b\x65\xe8\x33\xf6\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\x8b\xc6\xe8\x37\x07\x00\x00\xc3\x55\x8b\xec\x56\x8b\x35\xa0\x01\x01\x10\x85\xf6\x75\x05\x33\xc0\x40\xeb\x12\xff\x75\x10\x8b\xce\xff\x75\x0c\xff\x75\x08\xe8\xc3\x06\x00\x00\xff\xd6\x5e\x5d\xc2\x0c\x00\x55\x8b\xec\x83\x7d\x0c\x01\x75\x05\xe8\x58\x04\x00\x00\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\xb1\xfe\xff\xff\x83\xc4\x0c\x5d\xc2\x0c\x00\x55\x8b\xec\x6a\x00\xff\x15\x58\x00\x01\x10\xff\x75\x08\xff\x15\x54\x00\x01\x10\x68\x09\x04\x00\xc0\xff\x15\x5c\x00\x01\x10\x50\xff\x15\x60\x00\x01\x10\x5d\xc3\x55\x8b\xec\x81\xec\x24\x03\x00\x00\x6a\x17\xe8\xfb\xc9\x00\x00\x85\xc0\x74\x05\x6a\x02\x59\xcd\x29\xa3\xd8\x78\x01\x10\x89\x0d\xd4\x78\x01\x10\x89\x15\xd0\x78\x01\x10\x89\x1d\xcc\x78\x01\x10\x89\x35\xc8\x78\x01\x10\x89\x3d\xc4\x78\x01\x10\x66\x8c\x15\xf0\x78\x01\x10\x66\x8c\x0d\xe4\x78\x01\x10\x66\x8c\x1d\xc0\x78\x01\x10\x66\x8c\x05\xbc\x78\x01\x10\x66\x8c\x25\xb8\x78\x01\x10\x66\x8c\x2d\xb4\x78\x01\x10\x9c\x8f\x05\xe8\x78\x01\x10\x8b\x45\x00\xa3\xdc\x78\x01\x10\x8b\x45\x04\xa3\xe0\x78\x01\x10\x8d\x45\x08\xa3\xec\x78\x01\x10\x8b\x85\xdc\xfc\xff\xff\xc7\x05\x28\x78\x01\x10\x01\x00\x01\x00\xa1\xe0\x78\x01\x10\xa3\xe4\x77\x01\x10\xc7\x05\xd8\x77\x01\x10\x09\x04\x00\xc0\xc7\x05\xdc\x77\x01\x10\x01\x00\x00\x00\xc7\x05\xe8\x77\x01\x10\x01\x00\x00\x00\x6a\x04\x58\x6b\xc0\x00\xc7\x80\xec\x77\x01\x10\x02\x00\x00\x00\x6a\x04\x58\x6b\xc0\x00\x8b\x0d\x04\x70\x01\x10\x89\x4c\x05\xf8\x6a\x04\x58\xc1\xe0\x00\x8b\x0d\x00\x70\x01\x10\x89\x4c\x05\xf8\x68\xa4\x01\x01\x10\xe8\xe1\xfe\xff\xff\x8b\xe5\x5d\xc3\x55\x8b\xec\x8b\x45\x08\x56\x8b\x48\x3c\x03\xc8\x0f\xb7\x41\x14\x8d\x51\x18\x03\xd0\x0f\xb7\x41\x06\x6b\xf0\x28\x03\xf2\x3b\xd6\x74\x19\x8b\x4d\x0c\x3b\x4a\x0c\x72\x0a\x8b\x42\x08\x03\x42\x0c\x3b\xc8\x72\x0c\x83\xc2\x28\x3b\xd6\x75\xea\x33\xc0\x5e\x5d\xc3\x8b\xc2\xeb\xf9\xe8\x33\x07\x00\x00\x85\xc0\x75\x03\x32\xc0\xc3\x64\xa1\x18\x00\x00\x00\x56\xbe\xf8\x7a\x01\x10\x8b\x50\x04\xeb\x04\x3b\xd0\x74\x10\x33\xc0\x8b\xca\xf0\x0f\xb1\x0e\x85\xc0\x75\xf0\x32\xc0\x5e\xc3\xb0\x01\x5e\xc3\xe8\xfe\x06\x00\x00\x85\xc0\x74\x07\xe8\x54\x05\x00\x00\xeb\x05\xe8\x78\x30\x00\x00\xb0\x01\xc3\x6a\x00\xe8\xcf\x00\x00\x00\x84\xc0\x59\x0f\x95\xc0\xc3\xe8\x44\x0a\x00\x00\x84\xc0\x75\x03\x32\xc0\xc3\xe8\x64\x35\x00\x00\x84\xc0\x75\x07\xe8\x3a\x0a\x00\x00\xeb\xed\xb0\x01\xc3\xe8\x5c\x35\x00\x00\xe8\x2b\x0a\x00\x00\xb0\x01\xc3\x55\x8b\xec\xe8\xa9\x06\x00\x00\x85\xc0\x75\x18\x83\x7d\x0c\x01\x75\x12\xff\x75\x10\x8b\x4d\x14\x50\xff\x75\x08\xe8\x8a\x04\x00\x00\xff\x55\x14\xff\x75\x1c\xff\x75\x18\xe8\x1e\x2a\x00\x00\x59\x59\x5d\xc3\xe8\x79\x06\x00\x00\x85\xc0\x74\x0c\x68\xfc\x7a\x01\x10\xe8\x82\x33\x00\x00\x59\xc3\xe8\xe2\x2d\x00\x00\x85\xc0\x0f\x84\xb5\x2d\x00\x00\xc3\x6a\x00\xe8\x11\x35\x00\x00\x59\xe9\xf4\x09\x00\x00\x55\x8b\xec\x83\x7d\x08\x00\x75\x07\xc6\x05\x14\x7b\x01\x10\x01\xe8\x98\x04\x00\x00\xe8\x72\x09\x00\x00\x84\xc0\x75\x04\x32\xc0\x5d\xc3\xe8\xad\x34\x00\x00\x84\xc0\x75\x0a\x6a\x00\xe8\x9e\x09\x00\x00\x59\xeb\xe9\xb0\x01\x5d\xc3\x55\x8b\xec\x83\xec\x0c\x56\x8b\x75\x08\x85\xf6\x74\x05\x83\xfe\x01\x75\x7c\xe8\xfd\x05\x00\x00\x85\xc0\x74\x2a\x85\xf6\x75\x26\x68\xfc\x7a\x01\x10\xe8\x1f\x33\x00\x00\x59\x85\xc0\x74\x04\x32\xc0\xeb\x57\x68\x08\x7b\x01\x10\xe8\x0c\x33\x00\x00\xf7\xd8\x59\x1a\xc0\xfe\xc0\xeb\x44\xa1\x04\x70\x01\x10\x8d\x75\xf4\x57\x83\xe0\x1f\xbf\xfc\x7a\x01\x10\x6a\x20\x59\x2b\xc8\x83\xc8\xff\xd3\xc8\x33\x05\x04\x70\x01\x10\x89\x45\xf4\x89\x45\xf8\x89\x45\xfc\xa5\xa5\xa5\xbf\x08\x7b\x01\x10\x89\x45\xf4\x89\x45\xf8\x8d\x75\xf4\x89\x45\xfc\xb0\x01\xa5\xa5\xa5\x5f\x5e\x8b\xe5\x5d\xc3\x6a\x05\xe8\x00\x02\x00\x00\xcc\x6a\x08\x68\xf8\x5a\x01\x10\xe8\x76\x03\x00\x00\x83\x65\xfc\x00\xb8\x4d\x5a\x00\x00\x66\x39\x05\x00\x00\x00\x10\x75\x60\xa1\x3c\x00\x00\x10\x81\xb8\x00\x00\x00\x10\x50\x45\x00\x00\x75\x4f\xb9\x0b\x01\x00\x00\x66\x39\x88\x18\x00\x00\x10\x75\x41\x8b\x45\x08\xb9\x00\x00\x00\x10\x2b\xc1\x50\x51\xe8\xb4\xfd\xff\xff\x59\x59\x85\xc0\x74\x2a\xf7\x40\x24\x00\x00\x00\x80\x75\x21\xc7\x45\xfc\xfe\xff\xff\xff\xb0\x01\xeb\x1f\x8b\x45\xec\x8b\x00\x33\xc9\x81\x38\x05\x00\x00\xc0\x0f\x94\xc1\x8b\xc1\xc3\x8b\x65\xe8\xc7\x45\xfc\xfe\xff\xff\xff\x32\xc0\xe8\x3c\x03\x00\x00\xc3\x55\x8b\xec\xe8\xe9\x04\x00\x00\x85\xc0\x74\x0f\x80\x7d\x08\x00\x75\x09\x33\xc0\xb9\xf8\x7a\x01\x10\x87\x01\x5d\xc3\x55\x8b\xec\x80\x3d\x14\x7b\x01\x10\x00\x74\x06\x80\x7d\x0c\x00\x75\x12\xff\x75\x08\xe8\x65\x33\x00\x00\xff\x75\x08\xe8\x34\x08\x00\x00\x59\x59\xb0\x01\x5d\xc3\x55\x8b\xec\xa1\x04\x70\x01\x10\x8b\xc8\x33\x05\xfc\x7a\x01\x10\x83\xe1\x1f\xff\x75\x08\xd3\xc8\x83\xf8\xff\x75\x07\xe8\x8b\x31\x00\x00\xeb\x0b\x68\xfc\x7a\x01\x10\xe8\xef\x31\x00\x00\x59\xf7\xd8\x59\x1b\xc0\xf7\xd0\x23\x45\x08\x5d\xc3\x55\x8b\xec\xff\x75\x08\xe8\xba\xff\xff\xff\xf7\xd8\x59\x1b\xc0\xf7\xd8\x48\x5d\xc3\x55\x8b\xec\x83\xec\x14\x83\x65\xf4\x00\x83\x65\xf8\x00\xa1\x04\x70\x01\x10\x56\x57\xbf\x4e\xe6\x40\xbb\xbe\x00\x00\xff\xff\x3b\xc7\x74\x0d\x85\xc6\x74\x09\xf7\xd0\xa3\x00\x70\x01\x10\xeb\x66\x8d\x45\xf4\x50\xff\x15\x74\x00\x01\x10\x8b\x45\xf8\x33\x45\xf4\x89\x45\xfc\xff\x15\x70\x00\x01\x10\x31\x45\xfc\xff\x15\x6c\x00\x01\x10\x31\x45\xfc\x8d\x45\xec\x50\xff\x15\x68\x00\x01\x10\x8b\x4d\xf0\x8d\x45\xfc\x33\x4d\xec\x33\x4d\xfc\x33\xc8\x3b\xcf\x75\x07\xb9\x4f\xe6\x40\xbb\xeb\x10\x85\xce\x75\x0c\x8b\xc1\x0d\x11\x47\x00\x00\xc1\xe0\x10\x0b\xc8\x89\x0d\x04\x70\x01\x10\xf7\xd1\x89\x0d\x00\x70\x01\x10\x5f\x5e\x8b\xe5\x5d\xc3\x68\x18\x7b\x01\x10\xff\x15\x78\x00\x01\x10\xc3\x68\x18\x7b\x01\x10\xe8\x58\x07\x00\x00\x59\xc3\xb8\x20\x7b\x01\x10\xc3\xe8\x71\xf7\xff\xff\x8b\x48\x04\x83\x08\x04\x89\x48\x04\xe8\xe7\xff\xff\xff\x8b\x48\x04\x83\x08\x02\x89\x48\x04\xc3\xb8\x9c\x84\x01\x10\xc3\x55\x8b\xec\x81\xec\x24\x03\x00\x00\x53\x56\x6a\x17\xe8\x01\xc5\x00\x00\x85\xc0\x74\x05\x8b\x4d\x08\xcd\x29\x33\xf6\x8d\x85\xdc\xfc\xff\xff\x68\xcc\x02\x00\x00\x56\x50\x89\x35\x28\x7b\x01\x10\xe8\x1e\x07\x00\x00\x83\xc4\x0c\x89\x85\x8c\xfd\xff\xff\x89\x8d\x88\xfd\xff\xff\x89\x95\x84\xfd\xff\xff\x89\x9d\x80\xfd\xff\xff\x89\xb5\x7c\xfd\xff\xff\x89\xbd\x78\xfd\xff\xff\x66\x8c\x95\xa4\xfd\xff\xff\x66\x8c\x8d\x98\xfd\xff\xff\x66\x8c\x9d\x74\xfd\xff\xff\x66\x8c\x85\x70\xfd\xff\xff\x66\x8c\xa5\x6c\xfd\xff\xff\x66\x8c\xad\x68\xfd\xff\xff\x9c\x8f\x85\x9c\xfd\xff\xff\x8b\x45\x04\x89\x85\x94\xfd\xff\xff\x8d\x45\x04\x89\x85\xa0\xfd\xff\xff\xc7\x85\xdc\xfc\xff\xff\x01\x00\x01\x00\x8b\x40\xfc\x6a\x50\x89\x85\x90\xfd\xff\xff\x8d\x45\xa8\x56\x50\xe8\x95\x06\x00\x00\x8b\x45\x04\x83\xc4\x0c\xc7\x45\xa8\x15\x00\x00\x40\xc7\x45\xac\x01\x00\x00\x00\x89\x45\xb4\xff\x15\x7c\x00\x01\x10\x56\x8d\x58\xff\xf7\xdb\x8d\x45\xa8\x89\x45\xf8\x8d\x85\xdc\xfc\xff\xff\x1a\xdb\x89\x45\xfc\xfe\xc3\xff\x15\x58\x00\x01\x10\x8d\x45\xf8\x50\xff\x15\x54\x00\x01\x10\x85\xc0\x75\x0d\x0f\xb6\xc3\xf7\xd8\x1b\xc0\x21\x05\x28\x7b\x01\x10\x5e\x5b\x8b\xe5\x5d\xc3\x83\x25\x28\x7b\x01\x10\x00\xc3\x53\x56\xbe\x8c\x5a\x01\x10\xbb\x8c\x5a\x01\x10\x3b\xf3\x73\x18\x57\x8b\x3e\x85\xff\x74\x09\x8b\xcf\xe8\x38\x00\x00\x00\xff\xd7\x83\xc6\x04\x3b\xf3\x72\xea\x5f\x5e\x5b\xc3\x53\x56\xbe\x94\x5a\x01\x10\xbb\x94\x5a\x01\x10\x3b\xf3\x73\x18\x57\x8b\x3e\x85\xff\x74\x09\x8b\xcf\xe8\x0d\x00\x00\x00\xff\xd7\x83\xc6\x04\x3b\xf3\x72\xea\x5f\x5e\x5b\xc3\xff\x25\x64\x01\x01\x10\xcc\xcc\xcc\xcc\x68\xe0\x25\x00\x10\x64\xff\x35\x00\x00\x00\x00\x8b\x44\x24\x10\x89\x6c\x24\x10\x8d\x6c\x24\x10\x2b\xe0\x53\x56\x57\xa1\x04\x70\x01\x10\x31\x45\xfc\x33\xc5\x50\x89\x65\xe8\xff\x75\xf8\x8b\x45\xfc\xc7\x45\xfc\xfe\xff\xff\xff\x89\x45\xf8\x8d\x45\xf0\x64\xa3\x00\x00\x00\x00\xf2\xc3\x8b\x4d\xf0\x64\x89\x0d\x00\x00\x00\x00\x59\x5f\x5f\x5e\x5b\x8b\xe5\x5d\x51\xf2\xc3\x55\x8b\xec\x83\x25\x2c\x7b\x01\x10\x00\x83\xec\x2c\x53\x33\xdb\x43\x09\x1d\x10\x70\x01\x10\x6a\x0a\xe8\x17\xc3\x00\x00\x85\xc0\x0f\x84\x74\x01\x00\x00\x83\x65\xec\x00\x33\xc0\x83\x0d\x10\x70\x01\x10\x02\x33\xc9\x56\x57\x89\x1d\x2c\x7b\x01\x10\x8d\x7d\xd4\x53\x0f\xa2\x8b\xf3\x5b\x89\x07\x89\x77\x04\x89\x4f\x08\x89\x57\x0c\x8b\x45\xd4\x8b\x4d\xe0\x89\x45\xf4\x81\xf1\x69\x6e\x65\x49\x8b\x45\xdc\x35\x6e\x74\x65\x6c\x0b\xc8\x8b\x45\xd8\x35\x47\x65\x6e\x75\x0b\xc8\xf7\xd9\x6a\x01\x58\x1a\xc9\x6a\x00\x80\xc1\x01\x59\x53\x0f\xa2\x8b\xf3\x5b\x89\x07\x89\x77\x04\x89\x4f\x08\x89\x57\x0c\x74\x43\x8b\x45\xd4\x25\xf0\x3f\xff\x0f\x3d\xc0\x06\x01\x00\x74\x23\x3d\x60\x06\x02\x00\x74\x1c\x3d\x70\x06\x02\x00\x74\x15\x3d\x50\x06\x03\x00\x74\x0e\x3d\x60\x06\x03\x00\x74\x07\x3d\x70\x06\x03\x00\x75\x11\x8b\x3d\x30\x7b\x01\x10\x83\xcf\x01\x89\x3d\x30\x7b\x01\x10\xeb\x06\x8b\x3d\x30\x7b\x01\x10\x83\x7d\xf4\x07\x8b\x45\xe0\x89\x45\xe4\x8b\x45\xdc\x89\x45\xf8\x89\x45\xe8\x7c\x32\x6a\x07\x58\x33\xc9\x53\x0f\xa2\x8b\xf3\x5b\x8d\x5d\xd4\x89\x03\x89\x73\x04\x89\x4b\x08\x89\x53\x0c\x8b\x45\xd8\xa9\x00\x02\x00\x00\x89\x45\xec\x8b\x45\xf8\x74\x09\x83\xcf\x02\x89\x3d\x30\x7b\x01\x10\x5f\x5e\xa9\x00\x00\x10\x00\x74\x6d\x83\x0d\x10\x70\x01\x10\x04\xc7\x05\x2c\x7b\x01\x10\x02\x00\x00\x00\xa9\x00\x00\x00\x08\x74\x55\xa9\x00\x00\x00\x10\x74\x4e\x33\xc9\x0f\x01\xd0\x89\x45\xf0\x89\x55\xf4\x8b\x45\xf0\x8b\x4d\xf4\x83\xe0\x06\x33\xc9\x83\xf8\x06\x75\x33\x85\xc9\x75\x2f\xa1\x10\x70\x01\x10\x83\xc8\x08\xc7\x05\x2c\x7b\x01\x10\x03\x00\x00\x00\xf6\x45\xec\x20\xa3\x10\x70\x01\x10\x74\x12\x83\xc8\x20\xc7\x05\x2c\x7b\x01\x10\x05\x00\x00\x00\xa3\x10\x70\x01\x10\x33\xc0\x5b\x8b\xe5\x5d\xc3\x33\xc0\x39\x05\x98\x84\x01\x10\x0f\x95\xc0\xc3\xc3\x55\x8b\xec\x56\x8b\x75\x10\x57\x8b\x7d\x0c\x56\x57\xff\x75\x08\xff\x15\x84\x00\x01\x10\x85\xf6\x74\x1c\x85\xc0\x75\x05\x33\xc9\x66\x89\x0f\x3b\xc6\x75\x0f\xff\x15\xfc\x00\x01\x10\x85\xc0\x75\x05\x66\x89\x44\x77\xfe\x5f\x5e\x5d\xc3\x55\x8b\xec\x81\xec\x4c\x02\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x45\x08\x8d\x8d\xf4\xfd\xff\xff\x68\x04\x01\x00\x00\x51\x50\xe8\x9e\xff\xff\xff\x83\xc4\x0c\x83\x3d\x18\x70\x01\x10\x05\x76\x5a\x57\x68\x00\x20\x00\x00\x6a\x00\xbf\x18\x70\x01\x10\x57\xe8\x11\xed\xff\xff\x83\xc4\x0c\x84\xc0\x74\x3f\x8d\x85\xd4\xfd\xff\xff\x68\xb4\x01\x01\x10\x50\xe8\x05\xec\xff\xff\x8d\x85\xf4\xfd\xff\xff\x50\x8d\x85\xe4\xfd\xff\xff\x50\xe8\x2a\xec\xff\xff\x8d\x85\xb4\xfd\xff\xff\x50\x6a\x04\x6a\x00\x6a\x00\x68\x71\x56\x01\x10\x57\xe8\x0a\xed\xff\xff\x83\xc4\x28\x5f\x8b\x4d\xfc\x33\xcd\xe8\x39\xf3\xff\xff\x8b\xe5\x5d\xc3\x55\x8b\xec\x81\xec\x4c\x02\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x45\x08\x8d\x8d\xf4\xfd\xff\xff\x68\x04\x01\x00\x00\x51\x50\xe8\x02\xff\xff\xff\x83\xc4\x0c\x83\x3d\x18\x70\x01\x10\x05\x76\x5a\x57\x68\x00\x20\x00\x00\x6a\x00\xbf\x18\x70\x01\x10\x57\xe8\x75\xec\xff\xff\x83\xc4\x0c\x84\xc0\x74\x3f\x8d\x85\xd4\xfd\xff\xff\x68\xc4\x01\x01\x10\x50\xe8\x69\xeb\xff\xff\x8d\x85\xf4\xfd\xff\xff\x50\x8d\x85\xe4\xfd\xff\xff\x50\xe8\x8e\xeb\xff\xff\x8d\x85\xb4\xfd\xff\xff\x50\x6a\x04\x6a\x00\x6a\x00\x68\xad\x56\x01\x10\x57\xe8\x6e\xec\xff\xff\x83\xc4\x28\x5f\x8b\x4d\xfc\x33\xcd\xe8\x9d\xf2\xff\xff\x8b\xe5\x5d\xc3\x33\xc0\x50\x50\x50\x68\x18\x70\x01\x10\xe8\x76\xea\xff\xff\x83\xc4\x10\xc3\x68\x18\x70\x01\x10\xe8\xf0\xea\xff\xff\x59\xc3\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x56\x8b\x75\x08\x57\x8b\x7d\x0c\x8b\x06\x83\xf8\xfe\x74\x0d\x8b\x4e\x04\x03\xcf\x33\x0c\x38\xe8\x55\xf2\xff\xff\x8b\x46\x08\x8b\x4e\x0c\x03\xcf\x33\x0c\x38\x5f\x5e\x5d\xe9\x42\xf2\xff\xff\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x83\xec\x1c\x53\x8b\x5d\x0c\x56\x57\xc6\x45\xff\x00\x8b\x43\x08\x8d\x73\x10\x33\x05\x04\x70\x01\x10\x56\x50\xc7\x45\xf4\x01\x00\x00\x00\x89\x75\xf0\x89\x45\xf8\xe8\x90\xff\xff\xff\x8b\x7d\x10\x57\xe8\xef\xfd\xff\xff\x8b\x45\x08\x83\xc4\x0c\xf6\x40\x04\x66\x0f\x85\xb4\x00\x00\x00\x89\x45\xe4\x8d\x45\xe4\x89\x7d\xe8\x8b\x7b\x0c\x89\x43\xfc\x83\xff\xfe\x0f\x84\xc0\x00\x00\x00\x8b\x4d\xf8\x8d\x47\x02\x8d\x04\x47\x8b\x1c\x81\x8d\x04\x81\x8b\x48\x04\x89\x45\xec\x85\xc9\x74\x66\x8b\xd6\xe8\x9d\x07\x00\x00\xb1\x01\x88\x4d\xff\x85\xc0\x78\x6a\x7e\x57\x8b\x45\x08\x81\x38\x63\x73\x6d\xe0\x75\x34\x83\x3d\xa0\x84\x01\x10\x00\x74\x2b\x68\xa0\x84\x01\x10\xe8\x76\xbf\x00\x00\x83\xc4\x04\x85\xc0\x74\x1a\x8b\x35\xa0\x84\x01\x10\x8b\xce\x6a\x01\xff\x75\x08\xe8\x53\xfb\xff\xff\xff\xd6\x8b\x75\xf0\x83\xc4\x08\x8b\x55\x08\x8b\x4d\x0c\xe8\x78\x07\x00\x00\x8b\x45\x0c\x39\x78\x0c\x74\x5f\xeb\x4b\x8a\x4d\xff\x8b\xfb\x83\xfb\xfe\x0f\x85\x73\xff\xff\xff\x84\xc9\x74\x2f\xeb\x21\xc7\x45\xf4\x00\x00\x00\x00\xeb\x18\x83\x7b\x0c\xfe\x74\x1e\x68\x04\x70\x01\x10\x56\x8b\xcb\xba\xfe\xff\xff\xff\xe8\x52\x07\x00\x00\x56\xff\x75\xf8\xe8\xa2\xfe\xff\xff\x83\xc4\x08\x8b\x45\xf4\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x68\x04\x70\x01\x10\x56\x8b\xd7\x8b\xc8\xe8\x2d\x07\x00\x00\x8b\x45\x0c\x56\xff\x75\xf8\x89\x58\x0c\xe8\x77\xfe\xff\xff\x8b\x4d\xec\x83\xc4\x08\x8b\xd6\x8b\x49\x08\xe8\xdc\x06\x00\x00\xcc\xe8\xa2\x08\x00\x00\xe8\x5b\x05\x00\x00\xe8\x2d\x08\x00\x00\x84\xc0\x75\x03\x32\xc0\xc3\xe8\xd3\x07\x00\x00\x84\xc0\x75\x07\xe8\x54\x08\x00\x00\xeb\xed\xe8\x16\xfe\xff\xff\xb0\x01\xc3\xe8\x43\x07\x00\x00\x85\xc0\x0f\x95\xc0\xc3\x6a\x00\xe8\x00\x07\x00\x00\x59\xb0\x01\xc3\x55\x8b\xec\xe8\x08\xfe\xff\xff\x80\x7d\x08\x00\x75\x12\xe8\xca\x07\x00\x00\xe8\x1c\x08\x00\x00\x6a\x00\xe8\x26\x05\x00\x00\x59\xb0\x01\x5d\xc3\xe8\xb4\x07\x00\x00\xb0\x01\xc3\x55\x8b\xec\xff\x75\x08\xff\x15\x88\x00\x01\x10\x85\xc0\x74\x11\x56\x8b\x30\x50\xe8\x44\x2b\x00\x00\x8b\xc6\x59\x85\xf6\x75\xf1\x5e\x5d\xc3\xcc\xcc\xcc\x8b\x4c\x24\x0c\x0f\xb6\x44\x24\x08\x8b\xd7\x8b\x7c\x24\x04\x85\xc9\x0f\x84\x3c\x01\x00\x00\x69\xc0\x01\x01\x01\x01\x83\xf9\x20\x0f\x8e\xdf\x00\x00\x00\x81\xf9\x80\x00\x00\x00\x0f\x8c\x8b\x00\x00\x00\x0f\xba\x25\x30\x7b\x01\x10\x01\x73\x09\xf3\xaa\x8b\x44\x24\x04\x8b\xfa\xc3\x0f\xba\x25\x10\x70\x01\x10\x01\x0f\x83\xb2\x00\x00\x00\x66\x0f\x6e\xc0\x66\x0f\x70\xc0\x00\x03\xcf\x0f\x11\x07\x83\xc7\x10\x83\xe7\xf0\x2b\xcf\x81\xf9\x80\x00\x00\x00\x7e\x4c\x8d\xa4\x24\x00\x00\x00\x00\x8d\xa4\x24\x00\x00\x00\x00\x90\x66\x0f\x7f\x07\x66\x0f\x7f\x47\x10\x66\x0f\x7f\x47\x20\x66\x0f\x7f\x47\x30\x66\x0f\x7f\x47\x40\x66\x0f\x7f\x47\x50\x66\x0f\x7f\x47\x60\x66\x0f\x7f\x47\x70\x8d\xbf\x80\x00\x00\x00\x81\xe9\x80\x00\x00\x00\xf7\xc1\x00\xff\xff\xff\x75\xc5\xeb\x13\x0f\xba\x25\x10\x70\x01\x10\x01\x73\x3e\x66\x0f\x6e\xc0\x66\x0f\x70\xc0\x00\x83\xf9\x20\x72\x1c\xf3\x0f\x7f\x07\xf3\x0f\x7f\x47\x10\x83\xc7\x20\x83\xe9\x20\x83\xf9\x20\x73\xec\xf7\xc1\x1f\x00\x00\x00\x74\x62\x8d\x7c\x39\xe0\xf3\x0f\x7f\x07\xf3\x0f\x7f\x47\x10\x8b\x44\x24\x04\x8b\xfa\xc3\xf7\xc1\x03\x00\x00\x00\x74\x0e\x88\x07\x47\x83\xe9\x01\xf7\xc1\x03\x00\x00\x00\x75\xf2\xf7\xc1\x04\x00\x00\x00\x74\x08\x89\x07\x83\xc7\x04\x83\xe9\x04\xf7\xc1\xf8\xff\xff\xff\x74\x20\x8d\xa4\x24\x00\x00\x00\x00\x8d\x9b\x00\x00\x00\x00\x89\x07\x89\x47\x04\x83\xc7\x08\x83\xe9\x08\xf7\xc1\xf8\xff\xff\xff\x75\xed\x8b\x44\x24\x04\x8b\xfa\xc3\x55\x8b\xec\xa1\x04\x70\x01\x10\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\x8b\x45\x08\xd3\xc8\x33\x05\x04\x70\x01\x10\x5d\xc3\x55\x8b\xec\x8b\x45\x08\x33\xc9\x53\x56\x57\x8d\x1c\x85\x44\x7b\x01\x10\x33\xc0\xf0\x0f\xb1\x0b\x8b\x15\x04\x70\x01\x10\x83\xcf\xff\x8b\xca\x8b\xf2\x83\xe1\x1f\x33\xf0\xd3\xce\x3b\xf7\x74\x69\x85\xf6\x74\x04\x8b\xc6\xeb\x63\x8b\x75\x10\x3b\x75\x14\x74\x1a\xff\x36\xe8\x59\x00\x00\x00\x59\x85\xc0\x75\x2f\x83\xc6\x04\x3b\x75\x14\x75\xec\x8b\x15\x04\x70\x01\x10\x33\xc0\x85\xc0\x74\x29\xff\x75\x0c\x50\xff\x15\xa4\x00\x01\x10\x8b\xf0\x85\xf6\x74\x13\x56\xe8\x6d\xff\xff\xff\x59\x87\x03\xeb\xb9\x8b\x15\x04\x70\x01\x10\xeb\xd9\x8b\x15\x04\x70\x01\x10\x8b\xc2\x6a\x20\x83\xe0\x1f\x59\x2b\xc8\xd3\xcf\x33\xfa\x87\x3b\x33\xc0\x5f\x5e\x5b\x5d\xc3\x55\x8b\xec\x53\x8b\x5d\x08\x33\xc9\x57\x33\xc0\x8d\x3c\x9d\x34\x7b\x01\x10\xf0\x0f\xb1\x0f\x8b\xc8\x85\xc9\x74\x0b\x8d\x41\x01\xf7\xd8\x1b\xc0\x23\xc1\xeb\x55\x8b\x1c\x9d\xd4\x01\x01\x10\x56\x68\x00\x08\x00\x00\x6a\x00\x53\xff\x15\xa8\x00\x01\x10\x8b\xf0\x85\xf6\x75\x27\xff\x15\xfc\x00\x01\x10\x83\xf8\x57\x75\x0d\x56\x56\x53\xff\x15\xa8\x00\x01\x10\x8b\xf0\xeb\x02\x33\xf6\x85\xf6\x75\x09\x83\xc8\xff\x87\x07\x33\xc0\xeb\x11\x8b\xc6\x87\x07\x85\xc0\x74\x07\x56\xff\x15\xa0\x00\x01\x10\x8b\xc6\x5e\x5f\x5b\x5d\xc3\x55\x8b\xec\x56\x68\x88\x02\x01\x10\x68\x84\x02\x01\x10\x68\x88\x02\x01\x10\x6a\x00\xe8\xc5\xfe\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x17\xff\x75\x14\x8b\xce\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\x58\xf7\xff\xff\xff\xd6\xeb\x03\x6a\x32\x58\x5e\x5d\xc3\x55\x8b\xec\x56\x68\x9c\x02\x01\x10\x68\x98\x02\x01\x10\x68\x9c\x02\x01\x10\x6a\x01\xe8\x85\xfe\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x1a\xff\x75\x18\x8b\xce\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\x15\xf7\xff\xff\xff\xd6\xeb\x03\x6a\x32\x58\x5e\x5d\xc3\x55\x8b\xec\x56\x68\xb4\x02\x01\x10\x68\xb0\x02\x01\x10\x68\xb4\x02\x01\x10\x6a\x02\xe8\x42\xfe\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x11\xff\x75\x0c\x8b\xce\xff\x75\x08\xe8\xdb\xf6\xff\xff\xff\xd6\xeb\x03\x6a\x32\x58\x5e\x5d\xc3\x55\x8b\xec\x56\x68\xc8\x02\x01\x10\x68\xc4\x02\x01\x10\x68\xc8\x02\x01\x10\x6a\x03\xe8\x08\xfe\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x20\xff\x75\x20\x8b\xce\xff\x75\x1c\xff\x75\x18\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\x92\xf6\xff\xff\xff\xd6\xeb\x03\x6a\x32\x58\x5e\x5d\xc3\x55\x8b\xec\x56\x68\xe4\x02\x01\x10\x68\xdc\x02\x01\x10\x68\xe4\x02\x01\x10\x6a\x04\xe8\xbf\xfd\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x0f\xff\x75\x08\x8b\xce\xe8\x5b\xf6\xff\xff\xff\xd6\x5e\x5d\xc3\x5e\x5d\xff\x25\x90\x00\x01\x10\x55\x8b\xec\x56\x68\xf8\x02\x01\x10\x68\xf0\x02\x01\x10\x68\xf8\x02\x01\x10\x6a\x05\xe8\x85\xfd\xff\xff\x83\xc4\x10\x8b\xf0\xff\x75\x08\x85\xf6\x74\x0b\x8b\xce\xe8\x21\xf6\xff\xff\xff\xd6\xeb\x06\xff\x15\x9c\x00\x01\x10\x5e\x5d\xc3\x55\x8b\xec\x56\x68\x08\x03\x01\x10\x68\x00\x03\x01\x10\x68\x08\x03\x01\x10\x6a\x06\xe8\x4b\xfd\xff\xff\x83\xc4\x10\x8b\xf0\xff\x75\x08\x85\xf6\x74\x0b\x8b\xce\xe8\xe7\xf5\xff\xff\xff\xd6\xeb\x06\xff\x15\x94\x00\x01\x10\x5e\x5d\xc3\x55\x8b\xec\x56\x68\x1c\x03\x01\x10\x68\x14\x03\x01\x10\x68\x1c\x03\x01\x10\x6a\x07\xe8\x11\xfd\xff\xff\x83\xc4\x10\x8b\xf0\xff\x75\x0c\xff\x75\x08\x85\xf6\x74\x0b\x8b\xce\xe8\xaa\xf5\xff\xff\xff\xd6\xeb\x06\xff\x15\x98\x00\x01\x10\x5e\x5d\xc3\x55\x8b\xec\x56\x68\x30\x03\x01\x10\x68\x28\x03\x01\x10\x68\x30\x03\x01\x10\x6a\x08\xe8\xd4\xfc\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x14\xff\x75\x10\x8b\xce\xff\x75\x0c\xff\x75\x08\xe8\x6a\xf5\xff\xff\xff\xd6\xeb\x0c\xff\x75\x0c\xff\x75\x08\xff\x15\x8c\x00\x01\x10\x5e\x5d\xc3\xa1\x04\x70\x01\x10\x57\x6a\x20\x83\xe0\x1f\xbf\x44\x7b\x01\x10\x59\x2b\xc8\x33\xc0\xd3\xc8\x33\x05\x04\x70\x01\x10\x6a\x09\x59\xf3\xab\x5f\xc3\x55\x8b\xec\x80\x7d\x08\x00\x75\x27\x56\xbe\x34\x7b\x01\x10\x83\x3e\x00\x74\x10\x83\x3e\xff\x74\x08\xff\x36\xff\x15\xa0\x00\x01\x10\x83\x26\x00\x83\xc6\x04\x81\xfe\x44\x7b\x01\x10\x75\xe0\x5e\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x53\x56\x57\x8b\x54\x24\x10\x8b\x44\x24\x14\x8b\x4c\x24\x18\x55\x52\x50\x51\x51\x68\x90\x2d\x00\x10\x64\xff\x35\x00\x00\x00\x00\xa1\x04\x70\x01\x10\x33\xc4\x89\x44\x24\x08\x64\x89\x25\x00\x00\x00\x00\x8b\x44\x24\x30\x8b\x58\x08\x8b\x4c\x24\x2c\x33\x19\x8b\x70\x0c\x83\xfe\xfe\x74\x3b\x8b\x54\x24\x34\x83\xfa\xfe\x74\x04\x3b\xf2\x76\x2e\x8d\x34\x76\x8d\x5c\xb3\x10\x8b\x0b\x89\x48\x0c\x83\x7b\x04\x00\x75\xcc\x68\x01\x01\x00\x00\x8b\x43\x08\xe8\xa2\x03\x00\x00\xb9\x01\x00\x00\x00\x8b\x43\x08\xe8\xb4\x03\x00\x00\xeb\xb0\x64\x8f\x05\x00\x00\x00\x00\x83\xc4\x18\x5f\x5e\x5b\xc3\x8b\x4c\x24\x04\xf7\x41\x04\x06\x00\x00\x00\xb8\x01\x00\x00\x00\x74\x33\x8b\x44\x24\x08\x8b\x48\x08\x33\xc8\xe8\x64\xea\xff\xff\x55\x8b\x68\x18\xff\x70\x0c\xff\x70\x10\xff\x70\x14\xe8\x3e\xff\xff\xff\x83\xc4\x0c\x5d\x8b\x44\x24\x08\x8b\x54\x24\x10\x89\x02\xb8\x03\x00\x00\x00\xc3\x55\xff\x74\x24\x08\xe8\x28\xf6\xff\xff\x83\xc4\x04\x8b\x4c\x24\x08\x8b\x29\xff\x71\x1c\xff\x71\x18\xff\x71\x28\xe8\x09\xff\xff\xff\x83\xc4\x0c\x5d\xc2\x04\x00\x55\x56\x57\x53\x8b\xea\x33\xc0\x33\xdb\x33\xd2\x33\xf6\x33\xff\xff\xd1\x5b\x5f\x5e\x5d\xc3\x8b\xea\x8b\xf1\x8b\xc1\x6a\x01\xe8\xf3\x02\x00\x00\x33\xc0\x33\xdb\x33\xc9\x33\xd2\x33\xff\xff\xe6\x55\x8b\xec\x53\x56\x57\x6a\x00\x52\x68\x42\x2e\x00\x10\x51\xe8\x54\xb7\x00\x00\x5f\x5e\x5b\x5d\xc3\x55\x8b\x6c\x24\x08\x52\x51\xff\x74\x24\x14\xe8\xa9\xfe\xff\xff\x83\xc4\x0c\x5d\xc2\x08\x00\x55\x8b\xec\x8b\x45\x08\x85\xc0\x74\x0e\x3d\x68\x7b\x01\x10\x74\x07\x50\xe8\x92\x24\x00\x00\x59\x5d\xc2\x04\x00\x55\x8b\xec\xa1\x60\x70\x01\x10\x83\xf8\xff\x74\x27\x56\x8b\x75\x08\x85\xf6\x75\x0e\x50\xe8\x4d\xfd\xff\xff\x8b\xf0\xa1\x60\x70\x01\x10\x59\x6a\x00\x50\xe8\x77\xfd\xff\xff\x59\x59\x56\xe8\xb1\xff\xff\xff\x5e\x5d\xc3\x83\x3d\x60\x70\x01\x10\xff\x75\x03\x33\xc0\xc3\x56\x57\xff\x15\xfc\x00\x01\x10\xff\x35\x60\x70\x01\x10\x8b\xf8\xe8\x11\xfd\xff\xff\x8b\xf0\x59\x85\xf6\x74\x0b\x57\xff\x15\xb0\x00\x01\x10\x8b\xc6\xeb\x42\x6a\x28\x6a\x01\xe8\x40\x25\x00\x00\x8b\xf0\x59\x59\x85\xf6\x74\x12\x56\xff\x35\x60\x70\x01\x10\xe8\x1c\xfd\xff\xff\x59\x59\x85\xc0\x75\x0b\x57\xff\x15\xb0\x00\x01\x10\x33\xff\xeb\x0b\x57\xff\x15\xb0\x00\x01\x10\x8b\xfe\x33\xf6\x56\xe8\xe5\x23\x00\x00\x59\x8b\xc7\x5f\x5e\xc3\x68\x5e\x2e\x00\x10\xe8\x3c\xfc\xff\xff\xa3\x60\x70\x01\x10\x59\x83\xf8\xff\x75\x03\x32\xc0\xc3\x68\x68\x7b\x01\x10\x50\xe8\xd1\xfc\xff\xff\x59\x59\x85\xc0\x75\x07\xe8\x05\x00\x00\x00\xeb\xe5\xb0\x01\xc3\xa1\x60\x70\x01\x10\x83\xf8\xff\x74\x0e\x50\xe8\x3d\xfc\xff\xff\x83\x0d\x60\x70\x01\x10\xff\x59\xb0\x01\xc3\x56\x57\xbf\x90\x7b\x01\x10\x33\xf6\x6a\x00\x68\xa0\x0f\x00\x00\x57\xe8\xcd\xfc\xff\xff\x83\xc4\x0c\x85\xc0\x74\x15\xff\x05\xa8\x7b\x01\x10\x83\xc6\x18\x83\xc7\x18\x83\xfe\x18\x72\xdb\xb0\x01\xeb\x07\xe8\x05\x00\x00\x00\x32\xc0\x5f\x5e\xc3\x56\x8b\x35\xa8\x7b\x01\x10\x85\xf6\x74\x20\x6b\xc6\x18\x57\x8d\xb8\x78\x7b\x01\x10\x57\xff\x15\xbc\x00\x01\x10\xff\x0d\xa8\x7b\x01\x10\x83\xef\x18\x83\xee\x01\x75\xeb\x5f\xb0\x01\x5e\xc3\xa1\x04\x70\x01\x10\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\x33\xc0\xd3\xc8\x33\x05\x04\x70\x01\x10\xa3\xac\x7b\x01\x10\xc3\xcc\xcc\x55\x8b\xec\x53\x56\x57\x55\x6a\x00\x6a\x00\x68\x18\x30\x00\x10\xff\x75\x08\xe8\x7e\xb5\x00\x00\x5d\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4c\x24\x04\xf7\x41\x04\x06\x00\x00\x00\xb8\x01\x00\x00\x00\x74\x32\x8b\x44\x24\x14\x8b\x48\xfc\x33\xc8\xe8\xd4\xe7\xff\xff\x55\x8b\x68\x10\x8b\x50\x28\x52\x8b\x50\x24\x52\xe8\x14\x00\x00\x00\x83\xc4\x08\x5d\x8b\x44\x24\x08\x8b\x54\x24\x10\x89\x02\xb8\x03\x00\x00\x00\xc3\x53\x56\x57\x8b\x44\x24\x10\x55\x50\x6a\xfe\x68\x20\x30\x00\x10\x64\xff\x35\x00\x00\x00\x00\xa1\x04\x70\x01\x10\x33\xc4\x50\x8d\x44\x24\x04\x64\xa3\x00\x00\x00\x00\x8b\x44\x24\x28\x8b\x58\x08\x8b\x70\x0c\x83\xfe\xff\x74\x3a\x83\x7c\x24\x2c\xff\x74\x06\x3b\x74\x24\x2c\x76\x2d\x8d\x34\x76\x8b\x0c\xb3\x89\x4c\x24\x0c\x89\x48\x0c\x83\x7c\xb3\x04\x00\x75\x17\x68\x01\x01\x00\x00\x8b\x44\xb3\x08\xe8\x49\x00\x00\x00\x8b\x44\xb3\x08\xe8\x5f\x00\x00\x00\xeb\xb7\x8b\x4c\x24\x04\x64\x89\x0d\x00\x00\x00\x00\x83\xc4\x18\x5f\x5e\x5b\xc3\x33\xc0\x64\x8b\x0d\x00\x00\x00\x00\x81\x79\x04\x20\x30\x00\x10\x75\x10\x8b\x51\x0c\x8b\x52\x0c\x39\x51\x08\x75\x05\xb8\x01\x00\x00\x00\xc3\x53\x51\xbb\x70\x70\x01\x10\xeb\x0b\x53\x51\xbb\x70\x70\x01\x10\x8b\x4c\x24\x0c\x89\x4b\x08\x89\x43\x04\x89\x6b\x0c\x55\x51\x50\x58\x59\x5d\x59\x5b\xc2\x04\x00\xff\xd0\xc3\xa1\xec\x7b\x01\x10\x56\x6a\x03\x5e\x85\xc0\x75\x07\xb8\x00\x02\x00\x00\xeb\x06\x3b\xc6\x7d\x07\x8b\xc6\xa3\xec\x7b\x01\x10\x6a\x04\x50\xe8\xce\x22\x00\x00\x6a\x00\xa3\xf0\x7b\x01\x10\xe8\x9d\x21\x00\x00\x83\xc4\x0c\x83\x3d\xf0\x7b\x01\x10\x00\x75\x2b\x6a\x04\x56\x89\x35\xec\x7b\x01\x10\xe8\xa8\x22\x00\x00\x6a\x00\xa3\xf0\x7b\x01\x10\xe8\x77\x21\x00\x00\x83\xc4\x0c\x83\x3d\xf0\x7b\x01\x10\x00\x75\x05\x83\xc8\xff\x5e\xc3\x57\x33\xff\xbe\x80\x70\x01\x10\x6a\x00\x68\xa0\x0f\x00\x00\x8d\x46\x20\x50\xe8\x07\x2b\x00\x00\xa1\xf0\x7b\x01\x10\x8b\xd7\xc1\xfa\x06\x89\x34\xb8\x8b\xc7\x83\xe0\x3f\x6b\xc8\x30\x8b\x04\x95\x08\x7d\x01\x10\x8b\x44\x08\x18\x83\xf8\xff\x74\x09\x83\xf8\xfe\x74\x04\x85\xc0\x75\x07\xc7\x46\x10\xfe\xff\xff\xff\x83\xc6\x38\x47\x81\xfe\x28\x71\x01\x10\x75\xaf\x5f\x33\xc0\x5e\xc3\x8b\xff\x55\x8b\xec\x6b\x45\x08\x38\x05\x80\x70\x01\x10\x5d\xc3\x8b\xff\x56\xe8\x1f\x2e\x00\x00\xe8\xcd\x2c\x00\x00\x33\xf6\xa1\xf0\x7b\x01\x10\xff\x34\x06\xe8\xec\x2e\x00\x00\xa1\xf0\x7b\x01\x10\x59\x8b\x04\x06\x83\xc0\x20\x50\xff\x15\xbc\x00\x01\x10\x83\xc6\x04\x83\xfe\x0c\x75\xd8\xff\x35\xf0\x7b\x01\x10\xe8\xb6\x20\x00\x00\x83\x25\xf0\x7b\x01\x10\x00\x59\x5e\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x83\xc0\x20\x50\xff\x15\xb4\x00\x01\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x83\xc0\x20\x50\xff\x15\xb8\x00\x01\x10\x5d\xc3\x6a\x0c\x68\x18\x5b\x01\x10\xe8\x71\xef\xff\xff\x83\x65\xe4\x00\x8b\x45\x08\xff\x30\xe8\xbe\xff\xff\xff\x59\x83\x65\xfc\x00\x8b\x4d\x0c\xe8\xf0\x03\x00\x00\x8b\xf0\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0d\x00\x00\x00\x8b\xc6\xe8\x84\xef\xff\xff\xc2\x0c\x00\x8b\x75\xe4\x8b\x45\x10\xff\x30\xe8\x9d\xff\xff\xff\x59\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x8b\xff\xff\xff\x8b\xe5\x5d\xc3\x83\xb9\x04\x04\x00\x00\x00\x75\x06\xb8\x00\x02\x00\x00\xc3\x8b\x81\x00\x04\x00\x00\xd1\xe8\xc3\x8b\xff\x55\x8b\xec\x51\x83\xc8\xff\x33\xd2\x56\x8b\x75\x08\xf7\xf6\x57\x83\xe0\xfe\x8b\xf9\x83\xf8\x02\x73\x0f\xe8\x06\x27\x00\x00\xc7\x00\x0c\x00\x00\x00\x32\xc0\xeb\x53\x53\x33\xdb\x03\xf6\x39\x9f\x04\x04\x00\x00\x75\x08\x81\xfe\x00\x04\x00\x00\x76\x08\x3b\xb7\x00\x04\x00\x00\x77\x04\xb0\x01\xeb\x31\x56\xe8\xdb\x1f\x00\x00\x89\x45\xfc\x59\x85\xc0\x74\x1a\x8d\x45\xfc\x50\x8d\x8f\x04\x04\x00\x00\xe8\xf9\x02\x00\x00\x8b\x45\xfc\xb3\x01\x89\xb7\x00\x04\x00\x00\x50\xe8\x79\x1f\x00\x00\x59\x8a\xc3\x5b\x5f\x5e\x8b\xe5\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x8b\x45\x14\x48\x83\xe8\x01\x74\x2e\x83\xe8\x01\x74\x25\x83\xe8\x09\x74\x20\x83\x7d\x14\x0d\x74\x1e\x8a\x45\x10\x3c\x63\x74\x08\x3c\x73\x74\x04\x32\xc9\xeb\x02\xb1\x01\x33\xc0\x84\xc9\x0f\x94\xc0\x5d\xc3\xb0\x01\x5d\xc3\x32\xc0\x5d\xc3\x8b\xff\x56\x8b\xf1\x57\x8b\xbe\x04\x04\x00\x00\xe8\x11\xff\xff\xff\x85\xff\x75\x04\x03\xc6\xeb\x02\x03\xc7\x5f\x5e\xc3\x8b\xff\x55\x8b\xec\x53\x56\x8b\xf1\x57\x8d\x4e\x40\x8b\xb9\x04\x04\x00\x00\x85\xff\x75\x02\x8b\xf9\xe8\xe6\xfe\xff\xff\x8b\x5d\x08\x48\x03\xf8\x89\x7e\x34\x8b\x4e\x28\x85\xc9\x7f\x04\x85\xdb\x74\x30\x33\xd2\x8b\xc3\xf7\x75\x0c\x49\x80\xc2\x30\x89\x4e\x28\x8b\xd8\x80\xfa\x39\x7e\x11\x80\x7d\x10\x00\x0f\x94\xc0\xfe\xc8\x24\xe0\x04\x61\x2c\x3a\x02\xd0\x8b\x46\x34\x88\x10\xff\x4e\x34\xeb\xc5\x8b\x46\x34\x2b\xf8\x89\x7e\x38\x40\x5f\x89\x46\x34\x5e\x5b\x5d\xc2\x0c\x00\x8b\xff\x55\x8b\xec\x51\x51\x53\x56\x8b\xf1\x57\x8d\x4e\x40\x8b\xb9\x04\x04\x00\x00\x85\xff\x75\x02\x8b\xf9\xe8\x6f\xfe\xff\xff\x8b\x55\x0c\x48\x8b\x5d\x08\x03\xf8\x89\x7e\x34\x8b\x4e\x28\x85\xc9\x7f\x06\x8b\xc3\x0b\xc2\x74\x3a\x6a\x00\xff\x75\x10\x8d\x41\xff\x52\x53\x89\x46\x28\xe8\x48\xb2\x00\x00\x80\xc1\x30\x89\x5d\xfc\x8b\xd8\x80\xf9\x39\x7e\x11\x80\x7d\x14\x00\x0f\x94\xc0\xfe\xc8\x24\xe0\x04\x61\x2c\x3a\x02\xc8\x8b\x46\x34\x88\x08\xff\x4e\x34\xeb\xb9\x8b\x46\x34\x2b\xf8\x89\x7e\x38\x40\x5f\x89\x46\x34\x5e\x5b\x8b\xe5\x5d\xc2\x10\x00\x8b\xff\x55\x8b\xec\x56\x33\xf6\x39\x75\x10\x7e\x1c\x57\x8b\x7d\x14\x8b\x4d\x08\x57\xff\x75\x0c\xe8\x28\x0f\x00\x00\x83\x3f\xff\x74\x06\x46\x3b\x75\x10\x7c\xe9\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x33\xc0\x89\x4d\xfc\x89\x01\x89\x41\x04\x89\x41\x08\x89\x41\x0c\x89\x41\x10\x89\x41\x14\x89\x41\x18\x89\x41\x1c\x89\x41\x20\x89\x41\x24\x89\x41\x28\x66\x89\x41\x30\x89\x41\x38\x88\x41\x3c\x89\x81\x40\x04\x00\x00\x89\x81\x44\x04\x00\x00\x8b\xc1\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\xf1\xe8\xac\xff\xff\xff\x8b\x45\x08\x8b\x00\x89\x86\x48\x04\x00\x00\x8b\x45\x0c\x89\x06\x8b\x45\x10\x89\x46\x04\x8b\x45\x18\x89\x46\x08\x8b\x45\x14\x89\x46\x10\x8b\x45\x1c\x89\x46\x14\x8b\xc6\x5e\x5d\xc2\x18\x00\x8b\xff\x55\x8b\xec\x56\xff\x75\x1c\x8b\xf1\xff\x75\x18\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\xa5\xff\xff\xff\x83\xa6\x50\x04\x00\x00\x00\xe8\x6c\x24\x00\x00\x89\x46\x0c\x8b\xc6\x5e\x5d\xc2\x18\x00\x8b\xff\x55\x8b\xec\x57\x8b\xf9\x8b\x4d\x08\xc6\x47\x0c\x00\x85\xc9\x74\x0a\x8b\x01\x89\x47\x04\x8b\x41\x04\xeb\x16\xa1\x18\x7f\x01\x10\x85\xc0\x75\x12\xa1\x28\x72\x01\x10\x89\x47\x04\xa1\x2c\x72\x01\x10\x89\x47\x08\xeb\x44\x56\xe8\x57\x38\x00\x00\x8d\x57\x04\x89\x07\x52\x8d\x77\x08\x8b\x48\x4c\x89\x0a\x8b\x48\x48\x50\x89\x0e\xe8\x8d\x39\x00\x00\x56\xff\x37\xe8\xb2\x39\x00\x00\x8b\x0f\x83\xc4\x10\x8b\x81\x50\x03\x00\x00\x5e\xa8\x02\x75\x0d\x83\xc8\x02\x89\x81\x50\x03\x00\x00\xc6\x47\x0c\x01\x8b\xc7\x5f\x5d\xc2\x04\x00\x8b\xff\x56\x8b\xf1\xff\xb6\x04\x04\x00\x00\xe8\x9b\x1c\x00\x00\x83\xa6\x04\x04\x00\x00\x00\x59\x5e\xc3\x8b\xff\x55\x8b\xec\x56\x8b\xf1\xff\x36\xe8\x82\x1c\x00\x00\x8b\x55\x08\x83\x26\x00\x59\x8b\x02\x89\x06\x8b\xc6\x83\x22\x00\x5e\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x81\xec\x78\x04\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x8b\xf1\x57\x8b\x06\x8b\x38\x57\xe8\xd3\x43\x00\x00\x88\x85\x9c\xfb\xff\xff\x8b\x46\x04\x59\x8d\x8d\x88\xfb\xff\xff\xff\x30\xe8\x05\xff\xff\xff\x8b\x06\x8d\x8d\xa4\xfb\xff\xff\x8b\x00\x89\x85\xa0\xfb\xff\xff\x8b\x46\x10\xff\x30\x8d\x85\x8c\xfb\xff\xff\x50\x8b\x46\x0c\xff\x30\x8b\x46\x08\xff\x70\x04\xff\x30\x8d\x85\xa0\xfb\xff\xff\x50\xe8\x9b\xfe\xff\xff\x8d\x8d\xa4\xfb\xff\xff\xe8\x84\x01\x00\x00\x8d\x8d\xe4\xfb\xff\xff\x8b\xf0\xe8\x3b\xff\xff\xff\x80\xbd\x94\xfb\xff\xff\x00\x74\x0d\x8b\x8d\x88\xfb\xff\xff\x83\xa1\x50\x03\x00\x00\xfd\x57\xff\xb5\x9c\xfb\xff\xff\xe8\x02\x44\x00\x00\x59\x59\x8b\x4d\xfc\x8b\xc6\x5f\x33\xcd\x5e\xe8\xc1\xe0\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x0c\x8b\x4d\x08\x53\x8b\x00\x8b\x80\x88\x00\x00\x00\x8b\x00\x8a\x18\xeb\x05\x3a\xc3\x74\x07\x41\x8a\x01\x84\xc0\x75\xf5\x8a\x01\x41\x84\xc0\x74\x28\xeb\x09\x3c\x65\x74\x0b\x3c\x45\x74\x07\x41\x8a\x01\x84\xc0\x75\xf1\x8b\xd1\x49\x80\x39\x30\x74\xfa\x38\x19\x75\x01\x49\x8a\x02\x41\x42\x88\x01\x84\xc0\x75\xf6\x5b\x5d\xc3\x8b\xff\x55\x8b\xec\x8a\x4d\x08\x8d\x41\xe0\x3c\x5a\x77\x0f\x0f\xbe\xc1\x0f\xb6\x88\x90\x0a\x01\x10\x83\xe1\x0f\xeb\x02\x33\xc9\x8b\x45\x0c\x0f\xb6\x84\xc8\xb0\x0a\x01\x10\xc1\xe8\x04\x5d\xc2\x08\x00\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x0f\xbe\x06\x50\xe8\x37\x2d\x00\x00\x83\xf8\x65\xeb\x0c\x46\x0f\xb6\x06\x50\xe8\x7a\x2b\x00\x00\x85\xc0\x59\x75\xf1\x0f\xbe\x06\x50\xe8\x1a\x2d\x00\x00\x59\x83\xf8\x78\x75\x03\x83\xc6\x02\x8b\x45\x0c\x8a\x0e\x8b\x00\x8b\x80\x88\x00\x00\x00\x8b\x00\x8a\x00\x88\x06\x46\x8a\x06\x88\x0e\x8a\xc8\x8a\x06\x46\x84\xc0\x75\xf3\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x53\x56\x8b\xf1\x8d\x4d\xfc\x57\x6a\x0a\x51\x8b\x7e\x0c\x8b\x1f\x83\x27\x00\x8b\x46\x10\x83\x65\xfc\x00\x48\x50\xe8\x11\x2d\x00\x00\x8b\x4d\x08\x83\xc4\x0c\x89\x01\x8b\x46\x0c\x83\x38\x22\x74\x0f\x8b\x45\xfc\x3b\x46\x10\x72\x07\x89\x46\x10\xb0\x01\xeb\x02\x32\xc0\x83\x3f\x00\x75\x06\x85\xdb\x74\x02\x89\x1f\x5f\x5e\x5b\x8b\xe5\x5d\xc2\x04\x00\x8b\xff\x56\x8b\xf1\x8d\x8e\x48\x04\x00\x00\xe8\xef\x0a\x00\x00\x84\xc0\x75\x05\x83\xc8\xff\x5e\xc3\x53\x33\xdb\x39\x5e\x10\x0f\x85\xbb\x00\x00\x00\xe8\x79\x21\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\xb2\x20\x00\x00\x83\xc8\xff\xe9\xb9\x00\x00\x00\x89\x5e\x38\x89\x5e\x1c\xe9\x85\x00\x00\x00\xff\x46\x10\x39\x5e\x18\x0f\x8c\x8c\x00\x00\x00\xff\x76\x1c\x0f\xb6\x46\x31\x8b\xce\x50\xe8\xb3\xfe\xff\xff\x89\x46\x1c\x83\xf8\x08\x74\xba\x83\xf8\x07\x77\xc5\xff\x24\x85\x94\x39\x00\x10\x8b\xce\xe8\xdb\x00\x00\x00\xeb\x45\x83\x4e\x28\xff\x89\x5e\x24\x88\x5e\x30\x89\x5e\x20\x89\x5e\x2c\x88\x5e\x3c\xeb\x38\x8b\xce\xe8\x80\x00\x00\x00\xeb\x27\x8b\xce\xe8\x1e\x05\x00\x00\xeb\x1e\x89\x5e\x28\xeb\x21\x8b\xce\xe8\x50\x01\x00\x00\xeb\x10\x8b\xce\xe8\x6f\x01\x00\x00\xeb\x07\x8b\xce\xe8\xcf\x02\x00\x00\x84\xc0\x0f\x84\x68\xff\xff\xff\x8b\x46\x10\x8a\x00\x88\x46\x31\x84\xc0\x0f\x85\x6b\xff\xff\xff\xff\x46\x10\xff\x86\x50\x04\x00\x00\x83\xbe\x50\x04\x00\x00\x02\x0f\x85\x4a\xff\xff\xff\x8b\x46\x18\x5b\x5e\xc3\x8d\x49\x00\x0f\x39\x00\x10\x18\x39\x00\x10\x2d\x39\x00\x10\x36\x39\x00\x10\x3f\x39\x00\x10\x44\x39\x00\x10\x4d\x39\x00\x10\x56\x39\x00\x10\x0f\xbe\x41\x31\x83\xe8\x20\x74\x2d\x83\xe8\x03\x74\x22\x83\xe8\x08\x74\x17\x48\x83\xe8\x01\x74\x0b\x83\xe8\x03\x75\x1c\x83\x49\x20\x08\xeb\x16\x83\x49\x20\x04\xeb\x10\x83\x49\x20\x01\xeb\x0a\x83\x49\x20\x20\xeb\x04\x83\x49\x20\x02\xb0\x01\xc3\xe8\x1a\x00\x00\x00\x84\xc0\x75\x13\xe8\x3c\x20\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x75\x1f\x00\x00\x32\xc0\xc3\xb0\x01\xc3\x8b\xff\x56\x6a\x00\x8b\xf1\xe8\x1e\x00\x00\x00\x84\xc0\x75\x02\x5e\xc3\x8d\x46\x18\x50\x0f\xb6\x46\x31\x8d\x8e\x48\x04\x00\x00\x50\xe8\x04\x0a\x00\x00\xb0\x01\x5e\xc3\x8b\xff\x56\x8b\xf1\x57\xbf\x00\x80\x00\x00\x8b\x46\x08\x8a\x4e\x31\xc6\x46\x3c\x00\x0f\xb6\xd1\x8b\x00\x8b\x00\x66\x85\x3c\x50\x74\x38\x8d\x46\x18\x50\x51\x8d\x8e\x48\x04\x00\x00\xe8\xce\x09\x00\x00\x8b\x4e\x10\x8a\x01\x88\x46\x31\x8d\x41\x01\x80\x7e\x31\x00\x89\x46\x10\x75\x14\xe8\xb6\x1f\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\xef\x1e\x00\x00\x32\xc0\xeb\x02\xb0\x01\x5f\x5e\xc2\x04\x00\x80\x79\x31\x2a\x74\x0a\x8d\x41\x28\x50\xe8\x92\xfd\xff\xff\xc3\x83\x41\x14\x04\x8b\x41\x14\x8b\x40\xfc\x89\x41\x28\x85\xc0\x79\x04\x83\x49\x28\xff\xb0\x01\xc3\x8a\x41\x31\x3c\x46\x75\x1a\x8b\x01\x83\xe0\x08\x83\xc8\x00\x0f\x85\x51\x01\x00\x00\xc7\x41\x1c\x07\x00\x00\x00\xe9\x48\x01\x00\x00\x3c\x4e\x75\x26\x8b\x01\x6a\x08\x5a\x23\xc2\x83\xc8\x00\x0f\x85\x31\x01\x00\x00\x89\x51\x1c\xe8\x3b\x1f\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x74\x1e\x00\x00\x32\xc0\xc3\x83\x79\x2c\x00\x75\xe7\x0f\xbe\xc0\x83\xf8\x6a\x0f\x8f\xbe\x00\x00\x00\x0f\x84\xaf\x00\x00\x00\x83\xf8\x49\x74\x4f\x83\xf8\x4c\x74\x3e\x83\xf8\x54\x74\x2d\x83\xf8\x68\x0f\x85\xeb\x00\x00\x00\x8b\x41\x10\x80\x38\x68\x75\x10\x40\xc7\x41\x2c\x01\x00\x00\x00\x89\x41\x10\xe9\xd3\x00\x00\x00\xc7\x41\x2c\x02\x00\x00\x00\xe9\xc7\x00\x00\x00\xc7\x41\x2c\x0d\x00\x00\x00\xe9\xbb\x00\x00\x00\xc7\x41\x2c\x08\x00\x00\x00\xe9\xaf\x00\x00\x00\x8b\x51\x10\x8a\x02\x3c\x33\x75\x18\x80\x7a\x01\x32\x75\x12\x8d\x42\x02\xc7\x41\x2c\x0a\x00\x00\x00\x89\x41\x10\xe9\x8e\x00\x00\x00\x3c\x36\x75\x15\x80\x7a\x01\x34\x75\x0f\x8d\x42\x02\xc7\x41\x2c\x0b\x00\x00\x00\x89\x41\x10\xeb\x75\x3c\x64\x74\x14\x3c\x69\x74\x10\x3c\x6f\x74\x0c\x3c\x75\x74\x08\x3c\x78\x74\x04\x3c\x58\x75\x5d\xc7\x41\x2c\x09\x00\x00\x00\xeb\x54\xc7\x41\x2c\x05\x00\x00\x00\xeb\x4b\x83\xf8\x6c\x74\x2a\x83\xf8\x74\x74\x1c\x83\xf8\x77\x74\x0e\x83\xf8\x7a\x75\x37\xc7\x41\x2c\x06\x00\x00\x00\xeb\x2e\xc7\x41\x2c\x0c\x00\x00\x00\xeb\x25\xc7\x41\x2c\x07\x00\x00\x00\xeb\x1c\x8b\x41\x10\x80\x38\x6c\x75\x0d\x40\xc7\x41\x2c\x04\x00\x00\x00\x89\x41\x10\xeb\x07\xc7\x41\x2c\x03\x00\x00\x00\xb0\x01\xc3\x8b\xff\x55\x8b\xec\x51\x53\x56\x8b\xf1\x33\xdb\x43\x33\xc9\x0f\xbe\x46\x31\x83\xf8\x64\x7f\x6c\x0f\x84\x93\x00\x00\x00\x83\xf8\x58\x7f\x3e\x74\x37\x83\xf8\x41\x0f\x84\x93\x00\x00\x00\x83\xf8\x43\x74\x3e\x83\xf8\x44\x7e\x1d\x83\xf8\x47\x0f\x8e\x80\x00\x00\x00\x83\xf8\x53\x75\x0f\x8b\xce\xe8\xab\x06\x00\x00\x84\xc0\x0f\x85\x9f\x00\x00\x00\x32\xc0\xe9\xcd\x01\x00\x00\x53\x6a\x10\xeb\x57\x83\xe8\x5a\x74\x15\x83\xe8\x07\x74\x56\x48\x83\xe8\x01\x75\xe4\x51\x8b\xce\xe8\xfa\x03\x00\x00\xeb\xd2\x8b\xce\xe8\x34\x02\x00\x00\xeb\xc9\x83\xf8\x70\x7f\x4d\x74\x3f\x83\xf8\x67\x7e\x31\x83\xf8\x69\x74\x1c\x83\xf8\x6e\x74\x0e\x83\xf8\x6f\x75\xb6\x8b\xce\xe8\x1b\x06\x00\x00\xeb\xa5\x8b\xce\xe8\x9e\x05\x00\x00\xeb\x9c\x83\x4e\x20\x10\x51\x6a\x0a\x8b\xce\xe8\x44\x04\x00\x00\xeb\x8c\x8b\xce\xe8\x51\x02\x00\x00\xeb\x83\x8b\xce\xe8\x0f\x06\x00\x00\xe9\x77\xff\xff\xff\x83\xe8\x73\x0f\x84\x67\xff\xff\xff\x48\x83\xe8\x01\x74\xd0\x83\xe8\x03\x0f\x85\x67\xff\xff\xff\x51\xe9\x69\xff\xff\xff\x80\x7e\x30\x00\x74\x07\x8a\xc3\xe9\x28\x01\x00\x00\x8b\x56\x20\x33\xc0\x57\x66\x89\x45\xfc\x8b\xf8\x88\x45\xfe\x8b\xc2\xc1\xe8\x04\x84\xc3\x74\x27\x8b\xc2\xc1\xe8\x06\x84\xc3\x74\x06\xc6\x45\xfc\x2d\xeb\x16\x84\xd3\x74\x06\xc6\x45\xfc\x2b\xeb\x0c\x8b\xc2\xd1\xe8\x84\xc3\x74\x06\xc6\x45\xfc\x20\x8b\xfb\x8a\x4e\x31\x80\xf9\x78\x74\x05\x80\xf9\x58\x75\x09\x8b\xc2\xc1\xe8\x05\x84\xc3\x75\x02\x32\xdb\x80\xf9\x61\x74\x09\x80\xf9\x41\x74\x04\x32\xc0\xeb\x02\xb0\x01\x84\xdb\x75\x04\x84\xc0\x74\x27\xc6\x44\x3d\xfc\x30\x80\xf9\x58\x74\x09\x80\xf9\x41\x74\x04\x32\xc0\xeb\x02\xb0\x01\x84\xc0\x0f\x94\xc0\xfe\xc8\x24\xe0\x04\x78\x88\x44\x3d\xfd\x83\xc7\x02\x8b\x5e\x24\x2b\x5e\x38\x2b\xdf\xf6\xc2\x0c\x75\x16\x8d\x46\x18\x50\x53\x8d\x86\x48\x04\x00\x00\x6a\x20\x50\xe8\x12\xf7\xff\xff\x83\xc4\x10\xff\x76\x0c\x8d\x46\x18\x50\x57\x8d\x45\xfc\x8d\x8e\x48\x04\x00\x00\x50\xe8\x21\x07\x00\x00\x8b\x4e\x20\x8d\x7e\x18\x8b\xc1\xc1\xe8\x03\xa8\x01\x74\x1b\xc1\xe9\x02\xf6\xc1\x01\x75\x13\x57\x53\x8d\x86\x48\x04\x00\x00\x6a\x30\x50\xe8\xd1\xf6\xff\xff\x83\xc4\x10\x6a\x00\x8b\xce\xe8\x47\x06\x00\x00\x83\x3f\x00\x7c\x1d\x8b\x46\x20\xc1\xe8\x02\xa8\x01\x74\x13\x57\x53\x8d\x86\x48\x04\x00\x00\x6a\x20\x50\xe8\xa6\xf6\xff\xff\x83\xc4\x10\xb0\x01\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x80\x79\x31\x2a\x74\x0a\x8d\x41\x24\x50\xe8\xd2\xf9\xff\xff\xc3\x83\x41\x14\x04\x8b\x41\x14\x8b\x40\xfc\x89\x41\x24\x85\xc0\x79\x07\x83\x49\x20\x04\xf7\x59\x24\xb0\x01\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x83\xf8\x0b\x77\x19\xff\x24\x85\xb2\x3e\x00\x10\x6a\x04\x58\x5d\xc3\x33\xc0\x40\x5d\xc3\x6a\x02\xeb\xf4\x6a\x08\xeb\xf0\x33\xc0\x5d\xc3\x8b\xff\x9a\x3e\x00\x10\x9f\x3e\x00\x10\xa4\x3e\x00\x10\x9a\x3e\x00\x10\xa8\x3e\x00\x10\xa8\x3e\x00\x10\x9a\x3e\x00\x10\x9a\x3e\x00\x10\xac\x3e\x00\x10\x9a\x3e\x00\x10\x9a\x3e\x00\x10\xa8\x3e\x00\x10\x8b\xff\x53\x56\x8b\xf1\x57\x83\x46\x14\x04\x8b\x46\x14\x8b\x78\xfc\x85\xff\x74\x36\x8b\x5f\x04\x85\xdb\x74\x2f\xff\x76\x2c\x0f\xb6\x46\x31\x50\xff\x76\x04\xff\x36\xe8\x8a\xf4\xff\xff\x83\xc4\x10\x89\x5e\x34\x84\xc0\x0f\xb7\x07\x74\x0b\xd1\xe8\x89\x46\x38\xc6\x46\x3c\x01\xeb\x17\x89\x46\x38\xeb\x0e\xc7\x46\x34\x0c\x0b\x01\x10\xc7\x46\x38\x06\x00\x00\x00\xc6\x46\x3c\x00\x5f\x5e\xb0\x01\x5b\xc3\x8b\xff\x55\x8b\xec\x51\x51\x56\x8b\xf1\x57\x83\x4e\x20\x10\x8b\x46\x28\x85\xc0\x79\x1d\x8a\x46\x31\x3c\x61\x74\x0d\x3c\x41\x74\x09\xc7\x46\x28\x06\x00\x00\x00\xeb\x1d\xc7\x46\x28\x0d\x00\x00\x00\xeb\x14\x75\x12\x8a\x46\x31\x3c\x67\x74\x04\x3c\x47\x75\x07\xc7\x46\x28\x01\x00\x00\x00\x8b\x46\x28\x8d\x7e\x40\x53\xbb\x5d\x01\x00\x00\x8b\xcf\x03\xc3\x50\xe8\x72\xf3\xff\xff\x84\xc0\x75\x0c\x8b\xcf\xe8\x4f\xf3\xff\xff\x2b\xc3\x89\x46\x28\x8b\x87\x04\x04\x00\x00\x85\xc0\x75\x02\x8b\xc7\x83\x65\xf8\x00\x83\x65\xfc\x00\x89\x46\x34\x83\x46\x14\x08\x8b\x4e\x14\x8b\x41\xf8\x89\x45\xf8\x8b\x41\xfc\x8b\xcf\x89\x45\xfc\xe8\x19\xf3\xff\xff\x8b\x9f\x04\x04\x00\x00\x8b\xc8\x85\xdb\x75\x02\x8b\xdf\xff\x76\x08\x0f\xbe\x46\x31\xff\x76\x04\xff\x36\xff\x76\x28\x50\x51\x8b\xcf\xe8\xd1\xf3\xff\xff\x50\x8b\xcf\xe8\xeb\xf2\xff\xff\x50\x8d\x45\xf8\x53\x50\xe8\xc6\x38\x00\x00\x8b\x46\x20\x83\xc4\x28\xc1\xe8\x05\x5b\xa8\x01\x74\x13\x83\x7e\x28\x00\x75\x0d\xff\x76\x08\xff\x76\x34\xe8\xa5\xf7\xff\xff\x59\x59\x8a\x46\x31\x3c\x67\x74\x04\x3c\x47\x75\x17\x8b\x46\x20\xc1\xe8\x05\xa8\x01\x75\x0d\xff\x76\x08\xff\x76\x34\xe8\xfa\xf6\xff\xff\x59\x59\x8b\x46\x34\x80\x38\x2d\x75\x08\x83\x4e\x20\x40\x40\x89\x46\x34\x8b\x56\x34\x8a\x02\x3c\x69\x74\x0c\x3c\x49\x74\x08\x3c\x6e\x74\x04\x3c\x4e\x75\x04\xc6\x46\x31\x73\x8d\x7a\x01\x8a\x0a\x42\x84\xc9\x75\xf9\x2b\xd7\xb0\x01\x5f\x89\x56\x38\x5e\x8b\xe5\x5d\xc3\x8b\xff\x56\x8b\xf1\x57\xff\x76\x2c\x0f\xb6\x46\x31\x50\xff\x76\x04\xff\x36\xe8\xe3\xf2\xff\xff\x83\xc4\x10\x8d\x7e\x40\x84\xc0\x74\x39\x83\x46\x14\x04\x8b\x46\x14\x53\x8b\x9f\x04\x04\x00\x00\x0f\xb7\x40\xfc\x85\xdb\x75\x02\x8b\xdf\x50\x8b\xcf\xe8\x1b\xf2\xff\xff\x50\x8d\x46\x38\x53\x50\xe8\xe9\x26\x00\x00\x83\xc4\x10\x5b\x85\xc0\x74\x25\xc6\x46\x30\x01\xeb\x1f\x8b\x8f\x04\x04\x00\x00\x85\xc9\x75\x02\x8b\xcf\x83\x46\x14\x04\x8b\x46\x14\x8a\x40\xfc\x88\x01\xc7\x46\x38\x01\x00\x00\x00\x8b\x87\x04\x04\x00\x00\x85\xc0\x74\x02\x8b\xf8\x89\x7e\x34\xb0\x01\x5f\x5e\xc2\x04\x00\x8b\xff\x55\x8b\xec\x53\x56\x8b\xf1\xff\x76\x2c\xe8\x46\xfd\xff\xff\x59\x8b\xd8\x8b\xcb\x83\xe9\x01\x74\x78\x83\xe9\x01\x74\x56\x49\x83\xe9\x01\x74\x33\x83\xe9\x04\x74\x17\xe8\xdc\x18\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x15\x18\x00\x00\x32\xc0\xe9\x02\x01\x00\x00\x8b\x46\x20\x83\x46\x14\x08\xc1\xe8\x04\xa8\x01\x8b\x46\x14\x8b\x48\xf8\x8b\x50\xfc\xeb\x58\x8b\x46\x20\x83\x46\x14\x04\xc1\xe8\x04\xa8\x01\x8b\x46\x14\x74\x05\x8b\x40\xfc\xeb\x3f\x8b\x48\xfc\x33\xd2\xeb\x3b\x8b\x46\x20\x83\x46\x14\x04\xc1\xe8\x04\xa8\x01\x8b\x46\x14\x74\x06\x0f\xbf\x40\xfc\xeb\x21\x0f\xb7\x40\xfc\xeb\x1b\x8b\x46\x20\x83\x46\x14\x04\xc1\xe8\x04\xa8\x01\x8b\x46\x14\x74\x06\x0f\xbe\x40\xfc\xeb\x04\x0f\xb6\x40\xfc\x99\x8b\xc8\x57\x8b\x7e\x20\x8b\xc7\xc1\xe8\x04\xa8\x01\x74\x17\x85\xd2\x7f\x13\x7c\x04\x85\xc9\x73\x0d\xf7\xd9\x83\xd2\x00\xf7\xda\x83\xcf\x40\x89\x7e\x20\x83\x7e\x28\x00\x5f\x7d\x09\xc7\x46\x28\x01\x00\x00\x00\xeb\x11\x83\x66\x20\xf7\xb8\x00\x02\x00\x00\x39\x46\x28\x7e\x03\x89\x46\x28\x8b\xc1\x0b\xc2\x75\x04\x83\x66\x20\xdf\xff\x75\x0c\xff\x75\x08\x83\xfb\x08\x75\x0b\x52\x51\x8b\xce\xe8\x2a\xf2\xff\xff\xeb\x08\x51\x8b\xce\xe8\xab\xf1\xff\xff\x8b\x46\x20\xc1\xe8\x07\xa8\x01\x74\x1a\x83\x7e\x38\x00\x74\x08\x8b\x46\x34\x80\x38\x30\x74\x0c\xff\x4e\x34\x8b\x4e\x34\xc6\x01\x30\xff\x46\x38\xb0\x01\x5e\x5b\x5d\xc2\x08\x00\x8b\xff\x56\x8b\xf1\x57\x83\x46\x14\x04\x8b\x46\x14\x8b\x78\xfc\xe8\xed\x37\x00\x00\x85\xc0\x75\x14\xe8\xa4\x17\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\xdd\x16\x00\x00\x32\xc0\xeb\x44\xff\x76\x2c\xe8\xd8\xfb\xff\xff\x59\x83\xe8\x01\x74\x2b\x83\xe8\x01\x74\x1d\x48\x83\xe8\x01\x74\x10\x83\xe8\x04\x75\xce\x8b\x46\x18\x99\x89\x07\x89\x57\x04\xeb\x15\x8b\x46\x18\x89\x07\xeb\x0e\x66\x8b\x46\x18\x66\x89\x07\xeb\x05\x8a\x46\x18\x88\x07\xc6\x46\x30\x01\xb0\x01\x5f\x5e\xc3\x8b\x51\x20\x8b\xc2\xc1\xe8\x05\xa8\x01\x74\x09\x81\xca\x80\x00\x00\x00\x89\x51\x20\x6a\x00\x6a\x08\xe8\x24\xfe\xff\xff\xc3\x6a\x01\x6a\x10\xc7\x41\x28\x08\x00\x00\x00\xc7\x41\x2c\x0a\x00\x00\x00\xe8\x0c\xfe\xff\xff\xc3\x8b\xff\x53\x56\x8b\xf1\x57\x83\x46\x14\x04\x8b\x46\x14\x8b\x7e\x28\x8b\x58\xfc\x89\x5e\x34\x83\xff\xff\x75\x05\xbf\xff\xff\xff\x7f\xff\x76\x2c\x0f\xb6\x46\x31\x50\xff\x76\x04\xff\x36\xe8\x43\xf0\xff\xff\x83\xc4\x10\x84\xc0\x74\x1a\x85\xdb\x75\x07\xc7\x46\x34\x14\x0b\x01\x10\x57\xff\x76\x34\xc6\x46\x3c\x01\xe8\xa3\x25\x00\x00\xeb\x14\x85\xdb\x75\x07\xc7\x46\x34\x0c\x0b\x01\x10\x57\xff\x76\x34\xe8\x66\x24\x00\x00\x59\x59\x5f\x89\x46\x38\xb0\x01\x5e\x5b\xc3\x8b\x01\x85\xc0\x75\x13\xe8\x99\x16\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\xd2\x15\x00\x00\x32\xc0\xc3\x50\xe8\x02\x00\x00\x00\x59\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x56\x8b\x41\x0c\xc1\xe8\x0c\xa8\x01\x75\x6a\x51\xe8\x5b\x36\x00\x00\x8b\xd0\xbe\x38\x71\x01\x10\x59\x83\xfa\xff\x74\x19\x83\xfa\xfe\x74\x14\x83\xe0\x3f\x8b\xca\x6b\xc0\x30\xc1\xf9\x06\x03\x04\x8d\x08\x7d\x01\x10\xeb\x02\x8b\xc6\x80\x78\x29\x00\x75\x22\x83\xfa\xff\x74\x17\x83\xfa\xfe\x74\x12\x8b\xc2\x83\xe2\x3f\x6b\xf2\x30\xc1\xf8\x06\x03\x34\x85\x08\x7d\x01\x10\xf6\x46\x2d\x01\x74\x14\xe8\x15\x16\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x4e\x15\x00\x00\x32\xc0\xeb\x02\xb0\x01\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x01\x8b\x40\x0c\xc1\xe8\x0c\xa8\x01\x74\x08\x8b\x01\x83\x78\x04\x00\x74\x1b\xff\x31\x0f\xbe\x45\x08\x50\xe8\xf3\x35\x00\x00\x59\x59\x83\xf8\xff\x75\x08\x8b\x45\x0c\x83\x08\xff\xeb\x05\x8b\x45\x0c\xff\x00\x5d\xc2\x08\x00\x8b\xff\x55\x8b\xec\x83\xec\x10\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x53\x56\x8b\xf1\x57\x80\x7e\x3c\x00\x74\x5d\x8b\x46\x38\x85\xc0\x7e\x56\x8b\x7e\x34\x33\xdb\x85\xc0\x74\x65\x0f\xb7\x07\x8d\x7f\x02\x83\x65\xf0\x00\x50\x6a\x06\x8d\x45\xf4\x50\x8d\x45\xf0\x50\xe8\x17\x23\x00\x00\x83\xc4\x10\x85\xc0\x75\x26\x39\x45\xf0\x74\x21\xff\x76\x0c\x8d\x46\x18\x50\xff\x75\xf0\x8d\x45\xf4\x50\x8d\x8e\x48\x04\x00\x00\xe8\x3b\x00\x00\x00\x43\x3b\x5e\x38\x75\xbb\xeb\x1e\x83\x4e\x18\xff\xeb\x18\xff\x76\x0c\x8d\x46\x18\x50\xff\x76\x38\x8d\x8e\x48\x04\x00\x00\xff\x76\x34\xe8\x15\x00\x00\x00\x8b\x4d\xfc\xb0\x01\x5f\x5e\x33\xcd\x5b\xe8\xfc\xd2\xff\xff\x8b\xe5\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x51\x51\x53\x8b\xd9\x8b\x03\x8b\x40\x0c\xc1\xe8\x0c\xa8\x01\x74\x12\x8b\x03\x83\x78\x04\x00\x75\x0a\x8b\x4d\x10\x8b\x45\x0c\x01\x01\xeb\x5b\x8b\x45\x0c\x56\x8b\x75\x14\x57\x8b\x7d\x08\x03\xc7\x89\x45\xfc\x8b\x0e\x83\x26\x00\x89\x4d\xf8\x3b\xf8\x74\x32\x8b\x45\x10\x50\x0f\xb6\x07\x8b\xcb\x50\xe8\xc9\xfe\xff\xff\x8b\x45\x10\x83\x38\xff\x75\x12\x83\x3e\x2a\x75\x13\x50\x6a\x3f\x8b\xcb\xe8\xb2\xfe\xff\xff\x8b\x45\x10\x47\x3b\x7d\xfc\x75\xd4\x8b\x4d\xf8\x83\x3e\x00\x75\x06\x85\xc9\x74\x02\x89\x0e\x5f\x5e\x5b\x8b\xe5\x5d\xc2\x10\x00\x8b\xff\x55\x8b\xec\x83\xec\x2c\x8b\x45\x1c\x8b\x55\x10\x8b\x4d\x14\x89\x45\xf0\x8b\x45\x18\x89\x45\xf8\x8b\x45\x08\x89\x45\xe8\x8b\x45\x0c\x89\x4d\xf4\x89\x55\xfc\x89\x45\xec\x85\xd2\x75\x15\xe8\x5e\x14\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x97\x13\x00\x00\x83\xc8\xff\xeb\x2e\x85\xc9\x74\xe7\x8d\x45\xfc\x89\x45\xd4\x8d\x45\xf8\x89\x45\xd8\x8d\x45\xe8\x89\x45\xdc\x8d\x45\xf4\x89\x45\xe0\x8d\x45\xf0\x89\x45\xe4\x8d\x45\xd4\x50\x52\xe8\xbb\xec\xff\xff\x59\x59\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x8b\x55\x14\x8b\x4d\x08\x56\x85\xd2\x75\x0d\x85\xc9\x75\x0d\x39\x4d\x0c\x75\x26\x33\xc0\xeb\x33\x85\xc9\x74\x1e\x8b\x45\x0c\x85\xc0\x74\x17\x85\xd2\x75\x07\x33\xc0\x66\x89\x01\xeb\xe6\x8b\x75\x10\x85\xf6\x75\x1b\x33\xc0\x66\x89\x01\xe8\xd7\x13\x00\x00\x6a\x16\x5e\x89\x30\xe8\x11\x13\x00\x00\x8b\xc6\x5e\x8b\xe5\x5d\xc3\x53\x2b\xf1\x8b\xd8\x57\x8b\xf9\x83\xfa\xff\x75\x16\x0f\xb7\x04\x3e\x66\x89\x07\x8d\x7f\x02\x66\x85\xc0\x74\x2c\x83\xeb\x01\x75\xec\xeb\x25\x0f\xb7\x04\x3e\x66\x89\x07\x8d\x7f\x02\x66\x85\xc0\x74\x0a\x83\xeb\x01\x74\x05\x83\xea\x01\x75\xe7\x85\xd2\x8b\x55\x14\x75\x05\x33\xc0\x66\x89\x07\x5f\x85\xdb\x5b\x0f\x85\x72\xff\xff\xff\x83\xfa\xff\x75\x0f\x8b\x45\x0c\x33\xd2\x6a\x50\x66\x89\x54\x41\xfe\x58\xeb\x95\x33\xc0\x66\x89\x01\xe8\x56\x13\x00\x00\x6a\x22\xe9\x7a\xff\xff\xff\x8b\xff\x55\x8b\xec\x5d\xe9\x28\xff\xff\xff\x8b\xff\x55\x8b\xec\x51\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x45\x0c\x53\x56\x8b\x75\x08\x2b\xc6\x83\xc0\x03\x57\x33\xff\xc1\xe8\x02\x39\x75\x0c\x1b\xdb\xf7\xd3\x23\xd8\x74\x1c\x8b\x06\x89\x45\xf8\x85\xc0\x74\x0b\x8b\xc8\xff\x15\x64\x01\x01\x10\xff\x55\xf8\x83\xc6\x04\x47\x3b\xfb\x75\xe4\x8b\x4d\xfc\x5f\x5e\x33\xcd\x5b\xe8\xc5\xd0\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x8b\x75\x08\x57\xeb\x17\x8b\x3e\x85\xff\x74\x0e\x8b\xcf\xff\x15\x64\x01\x01\x10\xff\xd7\x85\xc0\x75\x0a\x83\xc6\x04\x3b\x75\x0c\x75\xe4\x33\xc0\x8b\x4d\xfc\x5f\x33\xcd\x5e\xe8\x80\xd0\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xb8\x63\x73\x6d\xe0\x39\x45\x08\x74\x04\x33\xc0\x5d\xc3\xff\x75\x0c\x50\xe8\x04\x00\x00\x00\x59\x59\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\xe8\x23\x27\x00\x00\x8b\xf0\x85\xf6\x0f\x84\x43\x01\x00\x00\x8b\x16\x8b\xca\x53\x33\xdb\x57\x8d\x82\x90\x00\x00\x00\x3b\xd0\x74\x0e\x8b\x7d\x08\x39\x39\x74\x09\x83\xc1\x0c\x3b\xc8\x75\xf5\x8b\xcb\x85\xc9\x74\x07\x8b\x79\x08\x85\xff\x75\x07\x33\xc0\xe9\x0d\x01\x00\x00\x83\xff\x05\x75\x0b\x33\xc0\x89\x59\x08\x40\xe9\xfd\x00\x00\x00\x83\xff\x01\x0f\x84\xf1\x00\x00\x00\x8b\x46\x04\x89\x45\xf8\x8b\x45\x0c\x89\x46\x04\x83\x79\x04\x08\x0f\x85\xc4\x00\x00\x00\x8d\x42\x24\x8d\x50\x6c\xeb\x06\x89\x58\x08\x83\xc0\x0c\x3b\xc2\x75\xf6\x8b\x5e\x08\xb8\x91\x00\x00\xc0\x39\x01\x77\x4f\x74\x44\x81\x39\x8d\x00\x00\xc0\x74\x33\x81\x39\x8e\x00\x00\xc0\x74\x22\x81\x39\x8f\x00\x00\xc0\x74\x11\x81\x39\x90\x00\x00\xc0\x75\x6f\xc7\x46\x08\x81\x00\x00\x00\xeb\x66\xc7\x46\x08\x86\x00\x00\x00\xeb\x5d\xc7\x46\x08\x83\x00\x00\x00\xeb\x54\xc7\x46\x08\x82\x00\x00\x00\xeb\x4b\xc7\x46\x08\x84\x00\x00\x00\xeb\x42\x81\x39\x92\x00\x00\xc0\x74\x33\x81\x39\x93\x00\x00\xc0\x74\x22\x81\x39\xb4\x02\x00\xc0\x74\x11\x81\x39\xb5\x02\x00\xc0\x75\x22\xc7\x46\x08\x8d\x00\x00\x00\xeb\x19\xc7\x46\x08\x8e\x00\x00\x00\xeb\x10\xc7\x46\x08\x85\x00\x00\x00\xeb\x07\xc7\x46\x08\x8a\x00\x00\x00\xff\x76\x08\x8b\xcf\x6a\x08\xff\x15\x64\x01\x01\x10\xff\xd7\x59\x89\x5e\x08\xeb\x10\xff\x71\x04\x89\x59\x08\x8b\xcf\xff\x15\x64\x01\x01\x10\xff\xd7\x8b\x45\xf8\x59\x89\x46\x04\x83\xc8\xff\x5f\x5b\x8b\x4d\xfc\x33\xcd\x5e\xe8\xed\xce\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x33\xc0\x81\x7d\x08\x63\x73\x6d\xe0\x0f\x94\xc0\x5d\xc3\x6a\x0c\x68\x38\x5b\x01\x10\xe8\x56\x9e\x00\x00\x8b\x75\x10\x85\xf6\x75\x12\xe8\x42\x01\x00\x00\x84\xc0\x74\x09\xff\x75\x08\xe8\x7a\x01\x00\x00\x59\x6a\x02\xe8\xb2\x32\x00\x00\x59\x83\x65\xfc\x00\x80\x3d\x00\x7c\x01\x10\x00\x0f\x85\x99\x00\x00\x00\x33\xc0\x40\xb9\xf8\x7b\x01\x10\x87\x01\xc7\x45\xfc\x01\x00\x00\x00\x8b\x7d\x0c\x85\xff\x75\x3c\x8b\x1d\x04\x70\x01\x10\x8b\xd3\x83\xe2\x1f\x6a\x20\x59\x2b\xca\x33\xc0\xd3\xc8\x33\xc3\x8b\x0d\xfc\x7b\x01\x10\x3b\xc8\x74\x15\x33\xd9\x33\xc0\x50\x50\x50\x8b\xca\xd3\xcb\x8b\xcb\xff\x15\x64\x01\x01\x10\xff\xd3\x68\x14\x7c\x01\x10\xeb\x0a\x83\xff\x01\x75\x0b\x68\x20\x7c\x01\x10\xe8\x34\x07\x00\x00\x59\x83\x65\xfc\x00\x85\xff\x75\x11\x68\x94\x01\x01\x10\x68\x84\x01\x01\x10\xe8\x00\xfd\xff\xff\x59\x59\x68\x9c\x01\x01\x10\x68\x98\x01\x01\x10\xe8\xef\xfc\xff\xff\x59\x59\x85\xf6\x75\x07\xc6\x05\x00\x7c\x01\x10\x01\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x27\x00\x00\x00\x85\xf6\x75\x2c\xff\x75\x08\xe8\x2a\x00\x00\x00\x8b\x45\xec\x8b\x00\xff\x30\xe8\xf2\xfe\xff\xff\x83\xc4\x04\xc3\x8b\x65\xe8\xe8\x86\x08\x00\x00\x8b\x75\x10\x6a\x02\xe8\x15\x32\x00\x00\x59\xc3\xe8\x93\x9d\x00\x00\xc3\x8b\xff\x55\x8b\xec\xe8\xcb\x13\x00\x00\x84\xc0\x74\x20\x64\xa1\x30\x00\x00\x00\x8b\x40\x68\xc1\xe8\x08\xa8\x01\x75\x10\xff\x75\x08\xff\x15\x5c\x00\x01\x10\x50\xff\x15\x60\x00\x01\x10\xff\x75\x08\xe8\x4f\x00\x00\x00\x59\xff\x75\x08\xff\x15\xc0\x00\x01\x10\xcc\x6a\x00\xff\x15\x08\x00\x01\x10\x8b\xc8\x85\xc9\x75\x03\x32\xc0\xc3\xb8\x4d\x5a\x00\x00\x66\x39\x01\x75\xf3\x8b\x41\x3c\x03\xc1\x81\x38\x50\x45\x00\x00\x75\xe6\xb9\x0b\x01\x00\x00\x66\x39\x48\x18\x75\xdb\x83\x78\x74\x0e\x76\xd5\x83\xb8\xe8\x00\x00\x00\x00\x0f\x95\xc0\xc3\x8b\xff\x55\x8b\xec\x51\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x83\x65\xf8\x00\x8d\x45\xf8\x50\x68\xc4\x0b\x01\x10\x6a\x00\xff\x15\xc4\x00\x01\x10\x85\xc0\x74\x23\x56\x68\xdc\x0b\x01\x10\xff\x75\xf8\xff\x15\xa4\x00\x01\x10\x8b\xf0\x85\xf6\x74\x0d\xff\x75\x08\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\x5e\x83\x7d\xf8\x00\x74\x09\xff\x75\xf8\xff\x15\xa0\x00\x01\x10\x8b\x4d\xfc\x33\xcd\xe8\xd2\xcc\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\xa3\xfc\x7b\x01\x10\x5d\xc3\x6a\x01\x6a\x00\x6a\x00\xe8\xde\xfd\xff\xff\x83\xc4\x0c\xc3\x8b\xff\x55\x8b\xec\x6a\x00\x6a\x02\xff\x75\x08\xe8\xc9\xfd\xff\xff\x83\xc4\x0c\x5d\xc3\xa1\xf8\x7b\x01\x10\xc3\x83\x3d\x04\x7c\x01\x10\x00\x74\x03\x33\xc0\xc3\x56\x57\xe8\xc2\x35\x00\x00\xe8\xa5\x38\x00\x00\x8b\xf0\x85\xf6\x75\x05\x83\xcf\xff\xeb\x2a\x56\xe8\x30\x00\x00\x00\x59\x85\xc0\x75\x05\x83\xcf\xff\xeb\x12\x50\xb9\x04\x7c\x01\x10\xa3\x10\x7c\x01\x10\xe8\xc1\x0b\x00\x00\x33\xff\x6a\x00\xe8\x3b\x07\x00\x00\x59\x56\xe8\x34\x07\x00\x00\x59\x8b\xc7\x5f\x5e\xc3\x8b\xff\x55\x8b\xec\x51\x51\x53\x56\x57\x8b\x7d\x08\x33\xd2\x8b\xf7\x8a\x07\xeb\x18\x3c\x3d\x74\x01\x42\x8b\xce\x8d\x59\x01\x8a\x01\x41\x84\xc0\x75\xf9\x2b\xcb\x46\x03\xf1\x8a\x06\x84\xc0\x75\xe4\x8d\x42\x01\x6a\x04\x50\xe8\x17\x08\x00\x00\x8b\xd8\x59\x59\x85\xdb\x74\x6d\x89\x5d\xfc\xeb\x52\x8b\xcf\x8d\x51\x01\x8a\x01\x41\x84\xc0\x75\xf9\x2b\xca\x80\x3f\x3d\x8d\x41\x01\x89\x45\xf8\x74\x37\x6a\x01\x50\xe8\xe9\x07\x00\x00\x8b\xf0\x59\x59\x85\xf6\x74\x30\x57\xff\x75\xf8\x56\xe8\x3a\x07\x00\x00\x83\xc4\x0c\x85\xc0\x75\x41\x8b\x45\xfc\x6a\x00\x89\x30\x83\xc0\x04\x89\x45\xfc\xe8\x99\x06\x00\x00\x8b\x45\xf8\x59\x03\xf8\x80\x3f\x00\x75\xa9\xeb\x11\x53\xe8\x29\x00\x00\x00\x6a\x00\xe8\x7f\x06\x00\x00\x59\x59\x33\xdb\x6a\x00\xe8\x74\x06\x00\x00\x59\x5f\x5e\x8b\xc3\x5b\x8b\xe5\x5d\xc3\x33\xc0\x50\x50\x50\x50\x50\xe8\xe6\x0c\x00\x00\xcc\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x74\x1f\x8b\x06\x57\x8b\xfe\xeb\x0c\x50\xe8\x43\x06\x00\x00\x8d\x7f\x04\x8b\x07\x59\x85\xc0\x75\xf0\x56\xe8\x33\x06\x00\x00\x59\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x8b\xf1\x57\x8d\x7e\x04\xeb\x11\x8b\x4d\x08\x56\xff\x15\x64\x01\x01\x10\xff\x55\x08\x59\x83\xc6\x04\x3b\xf7\x75\xeb\x8b\x4d\xfc\x5f\x33\xcd\x5e\xe8\x01\xcb\xff\xff\x8b\xe5\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x8b\x45\x08\x8b\x00\x3b\x05\x10\x7c\x01\x10\x74\x07\x50\xe8\x79\xff\xff\xff\x59\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x8b\x00\x3b\x05\x0c\x7c\x01\x10\x74\x07\x50\xe8\x5e\xff\xff\xff\x59\x5d\xc3\x68\x19\x4d\x00\x10\xb9\x04\x7c\x01\x10\xe8\x7b\xff\xff\xff\x68\x34\x4d\x00\x10\xb9\x08\x7c\x01\x10\xe8\x6c\xff\xff\xff\xff\x35\x10\x7c\x01\x10\xe8\x32\xff\xff\xff\xff\x35\x0c\x7c\x01\x10\xe8\x27\xff\xff\xff\x59\x59\xc3\xe9\xf5\xfd\xff\xff\x6a\x0c\x68\x60\x5b\x01\x10\xe8\x69\xd4\xff\xff\x83\x65\xe4\x00\x8b\x45\x08\xff\x30\xe8\x77\x2e\x00\x00\x59\x83\x65\xfc\x00\x8b\x4d\x0c\xe8\x0a\x02\x00\x00\x8b\xf0\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0d\x00\x00\x00\x8b\xc6\xe8\x7c\xd4\xff\xff\xc2\x0c\x00\x8b\x75\xe4\x8b\x45\x10\xff\x30\xe8\x8a\x2e\x00\x00\x59\xc3\x6a\x0c\x68\x80\x5b\x01\x10\xe8\x18\xd4\xff\xff\x83\x65\xe4\x00\x8b\x45\x08\xff\x30\xe8\x26\x2e\x00\x00\x59\x83\x65\xfc\x00\x8b\x4d\x0c\xe8\x99\x00\x00\x00\x8b\xf0\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0d\x00\x00\x00\x8b\xc6\xe8\x2b\xd4\xff\xff\xc2\x0c\x00\x8b\x75\xe4\x8b\x45\x10\xff\x30\xe8\x39\x2e\x00\x00\x59\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x8b\xff\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x12\xff\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xa1\x04\x70\x01\x10\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\x8b\x45\x08\xd3\xc8\x33\x05\x04\x70\x01\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x18\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\xc1\x89\x45\xe8\x53\x8b\x00\x8b\x18\x85\xdb\x75\x08\x83\xc8\xff\xe9\xe9\x00\x00\x00\x8b\x15\x04\x70\x01\x10\x56\x57\x8b\x3b\x8b\xf2\x8b\x5b\x04\x83\xe6\x1f\x33\xfa\x89\x75\xec\x8b\xce\x33\xda\xd3\xcf\xd3\xcb\x85\xff\x0f\x84\xbe\x00\x00\x00\x83\xff\xff\x0f\x84\xb5\x00\x00\x00\x89\x7d\xf4\x89\x5d\xf0\x6a\x20\x59\x2b\xce\x33\xc0\xd3\xc8\x33\xc2\x83\xeb\x04\x3b\xdf\x72\x60\x39\x03\x74\xf5\x8b\x33\x8b\x4d\xec\x33\xf2\xd3\xce\x8b\xce\x89\x03\xff\x15\x64\x01\x01\x10\xff\xd6\x8b\x45\xe8\x8b\x15\x04\x70\x01\x10\x8b\xf2\x83\xe6\x1f\x89\x75\xec\x8b\x00\x8b\x00\x8b\x08\x8b\x40\x04\x33\xca\x89\x4d\xf8\x33\xc2\x8b\xce\xd3\x4d\xf8\xd3\xc8\x8b\x4d\xf8\x3b\x4d\xf4\x75\x0b\x6a\x20\x59\x3b\x45\xf0\x74\xa0\x8b\x4d\xf8\x89\x4d\xf4\x8b\xf9\x89\x45\xf0\x8b\xd8\xeb\x8e\x83\xff\xff\x74\x0d\x57\xe8\x90\x03\x00\x00\x8b\x15\x04\x70\x01\x10\x59\x8b\xc2\x33\xd2\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\xd3\xca\x8b\x4d\xe8\x33\x15\x04\x70\x01\x10\x8b\x01\x8b\x00\x89\x10\x8b\x01\x8b\x00\x89\x50\x04\x8b\x01\x8b\x00\x89\x50\x08\x5f\x33\xc0\x5e\x8b\x4d\xfc\x33\xcd\x5b\xe8\x5c\xc8\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\xc1\x89\x45\xf8\x56\x8b\x00\x8b\x30\x85\xf6\x75\x08\x83\xc8\xff\xe9\x1e\x01\x00\x00\xa1\x04\x70\x01\x10\x8b\xc8\x53\x8b\x1e\x83\xe1\x1f\x57\x8b\x7e\x04\x33\xd8\x8b\x76\x08\x33\xf8\x33\xf0\xd3\xcf\xd3\xce\xd3\xcb\x3b\xfe\x0f\x85\xb4\x00\x00\x00\x2b\xf3\xb8\x00\x02\x00\x00\xc1\xfe\x02\x3b\xf0\x77\x02\x8b\xc6\x8d\x3c\x30\x85\xff\x75\x03\x6a\x20\x5f\x3b\xfe\x72\x1d\x6a\x04\x57\x53\xe8\x97\x34\x00\x00\x6a\x00\x89\x45\xfc\xe8\xd4\x02\x00\x00\x8b\x4d\xfc\x83\xc4\x10\x85\xc9\x75\x28\x6a\x04\x8d\x7e\x04\x57\x53\xe8\x77\x34\x00\x00\x6a\x00\x89\x45\xfc\xe8\xb4\x02\x00\x00\x8b\x4d\xfc\x83\xc4\x10\x85\xc9\x75\x08\x83\xc8\xff\xe9\x91\x00\x00\x00\x8d\x04\xb1\x8b\xd9\x89\x45\xfc\x8d\x34\xb9\xa1\x04\x70\x01\x10\x8b\x7d\xfc\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\x33\xc0\xd3\xc8\x8b\xcf\x33\x05\x04\x70\x01\x10\x89\x45\xf4\x8b\xc6\x2b\xc7\x83\xc0\x03\xc1\xe8\x02\x3b\xf7\x1b\xd2\xf7\xd2\x23\xd0\x89\x55\xfc\x74\x10\x8b\x55\xf4\x33\xc0\x40\x89\x11\x8d\x49\x04\x3b\x45\xfc\x75\xf5\x8b\x45\xf8\x8b\x40\x04\xff\x30\xe8\xba\xfd\xff\xff\x53\x89\x07\xe8\x5f\xd8\xff\xff\x8b\x5d\xf8\x8b\x0b\x8b\x09\x89\x01\x8d\x47\x04\x50\xe8\x4d\xd8\xff\xff\x8b\x0b\x56\x8b\x09\x89\x41\x04\xe8\x40\xd8\xff\xff\x8b\x0b\x83\xc4\x10\x8b\x09\x89\x41\x08\x33\xc0\x5f\x5b\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xff\x75\x08\x68\x14\x7c\x01\x10\xe8\x5e\x00\x00\x00\x59\x59\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x8d\x45\x08\x89\x45\xfc\x8d\x45\xfc\x50\x6a\x02\xe8\x03\xfd\xff\xff\x59\x59\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x75\x05\x83\xc8\xff\xeb\x28\x8b\x06\x3b\x46\x08\x75\x1f\xa1\x04\x70\x01\x10\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\x33\xc0\xd3\xc8\x33\x05\x04\x70\x01\x10\x89\x06\x89\x46\x04\x89\x46\x08\x33\xc0\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x8d\x45\x08\x89\x45\xf8\x8d\x45\x0c\x89\x45\xfc\x8d\x45\xf8\x50\x6a\x02\xe8\xca\xfc\xff\xff\x59\x59\x8b\xe5\x5d\xc3\x68\x70\x71\x01\x10\xb9\x1c\x7f\x01\x10\xe8\xe4\x05\x00\x00\xb0\x01\xc3\x68\x14\x7c\x01\x10\xe8\x83\xff\xff\xff\xc7\x04\x24\x20\x7c\x01\x10\xe8\x77\xff\xff\xff\x59\xb0\x01\xc3\xe8\x8d\xfb\xff\xff\xb0\x01\xc3\xa1\x04\x70\x01\x10\x56\x6a\x20\x83\xe0\x1f\x33\xf6\x59\x2b\xc8\xd3\xce\x33\x35\x04\x70\x01\x10\x56\xe8\x0d\x07\x00\x00\x56\xe8\x56\x34\x00\x00\x56\xe8\xfd\x35\x00\x00\x56\xe8\x5c\x38\x00\x00\x56\xe8\x4b\xf9\xff\xff\x83\xc4\x14\xb0\x01\x5e\xc3\x6a\x00\xe8\x75\xd5\xff\xff\x59\xc3\xa1\x50\x77\x01\x10\x83\xc9\xff\x56\xf0\x0f\xc1\x08\x75\x1b\xa1\x50\x77\x01\x10\xbe\x30\x75\x01\x10\x3b\xc6\x74\x0d\x50\xe8\xd9\x00\x00\x00\x59\x89\x35\x50\x77\x01\x10\xff\x35\x10\x7f\x01\x10\xe8\xc7\x00\x00\x00\xff\x35\x14\x7f\x01\x10\x33\xf6\x89\x35\x10\x7f\x01\x10\xe8\xb4\x00\x00\x00\xff\x35\x80\x80\x01\x10\x89\x35\x14\x7f\x01\x10\xe8\xa3\x00\x00\x00\xff\x35\x84\x80\x01\x10\x89\x35\x80\x80\x01\x10\xe8\x92\x00\x00\x00\x83\xc4\x10\x89\x35\x84\x80\x01\x10\xb0\x01\x5e\xc3\x68\x68\x0c\x01\x10\x68\xf0\x0b\x01\x10\xe8\xde\x32\x00\x00\x59\x59\xc3\xe8\x59\x1c\x00\x00\x85\xc0\x0f\x95\xc0\xc3\xe8\x9e\x1b\x00\x00\xb0\x01\xc3\x68\x68\x0c\x01\x10\x68\xf0\x0b\x01\x10\xe8\x3c\x33\x00\x00\x59\x59\xc3\x8b\xff\x55\x8b\xec\xff\x75\x08\xe8\xdd\x1c\x00\x00\x59\xb0\x01\x5d\xc3\x6a\x0c\x68\xa0\x5b\x01\x10\xe8\xc9\x94\x00\x00\xe8\x92\x1b\x00\x00\x8b\x70\x0c\x85\xf6\x74\x1e\x83\x65\xfc\x00\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\xeb\x07\x33\xc0\x40\xc3\x8b\x65\xe8\xc7\x45\xfc\xfe\xff\xff\xff\xe8\xe3\x00\x00\x00\xcc\x8b\xff\x55\x8b\xec\x83\x7d\x08\x00\x74\x2d\xff\x75\x08\x6a\x00\xff\x35\x7c\x80\x01\x10\xff\x15\xd0\x00\x01\x10\x85\xc0\x75\x18\x56\xe8\x0e\x07\x00\x00\x8b\xf0\xff\x15\xfc\x00\x01\x10\x50\xe8\x87\x06\x00\x00\x59\x89\x06\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x83\xfe\xe0\x77\x30\x85\xf6\x75\x17\x46\xeb\x14\xe8\x53\x37\x00\x00\x85\xc0\x74\x20\x56\xe8\xee\x32\x00\x00\x59\x85\xc0\x74\x15\x56\x6a\x00\xff\x35\x7c\x80\x01\x10\xff\x15\xd4\x00\x01\x10\x85\xc0\x74\xd9\xeb\x0d\xe8\xb7\x06\x00\x00\xc7\x00\x0c\x00\x00\x00\x33\xc0\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x56\x85\xd2\x74\x11\x8b\x4d\x0c\x85\xc9\x74\x0a\x8b\x75\x10\x85\xf6\x75\x17\xc6\x02\x00\xe8\x89\x06\x00\x00\x6a\x16\x5e\x89\x30\xe8\xc3\x05\x00\x00\x8b\xc6\x5e\x5d\xc3\x57\x8b\xfa\x2b\xf2\x8a\x04\x3e\x88\x07\x47\x84\xc0\x74\x05\x83\xe9\x01\x75\xf1\x5f\x85\xc9\x75\x0b\x88\x0a\xe8\x5a\x06\x00\x00\x6a\x22\xeb\xcf\x33\xf6\xeb\xd3\xe8\xe7\x33\x00\x00\x85\xc0\x74\x08\x6a\x16\xe8\x37\x34\x00\x00\x59\xf6\x05\x28\x71\x01\x10\x02\x74\x21\x6a\x17\xe8\x86\x91\x00\x00\x85\xc0\x74\x05\x6a\x07\x59\xcd\x29\x6a\x01\x68\x15\x00\x00\x40\x6a\x03\xe8\x94\x03\x00\x00\x83\xc4\x0c\x6a\x03\xe8\x39\xf7\xff\xff\xcc\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x74\x0c\x6a\xe0\x33\xd2\x58\xf7\xf6\x3b\x45\x0c\x72\x34\x0f\xaf\x75\x0c\x85\xf6\x75\x17\x46\xeb\x14\xe8\x59\x36\x00\x00\x85\xc0\x74\x20\x56\xe8\xf4\x31\x00\x00\x59\x85\xc0\x74\x15\x56\x6a\x08\xff\x35\x7c\x80\x01\x10\xff\x15\xd4\x00\x01\x10\x85\xc0\x74\xd9\xeb\x0d\xe8\xbd\x05\x00\x00\xc7\x00\x0c\x00\x00\x00\x33\xc0\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\xa8\x04\x74\x04\xb0\x01\x5d\xc3\xa8\x01\x74\x1b\x83\xe0\x02\x74\x09\x81\x7d\x0c\x00\x00\x00\x80\x77\xea\x85\xc0\x75\x09\x81\x7d\x0c\xff\xff\xff\x7f\x77\xdd\x32\xc0\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x28\x8d\x4d\x0c\x53\x57\xe8\x3e\x02\x00\x00\x84\xc0\x74\x21\x8b\x7d\x14\x85\xff\x74\x30\x83\xff\x02\x7c\x05\x83\xff\x24\x7e\x26\xe8\x53\x05\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x8c\x04\x00\x00\x33\xdb\x8b\x55\x10\x85\xd2\x74\x05\x8b\x4d\x0c\x89\x0a\x5f\x8b\xc3\x5b\x8b\xe5\x5d\xc3\x56\xff\x75\x08\x8d\x4d\xd8\xe8\xc4\xe0\xff\xff\x8b\x45\x0c\x33\xf6\x89\x75\xf4\x89\x45\xe8\xeb\x03\x8b\x45\x0c\x8a\x18\x40\x89\x45\x0c\x8d\x45\xdc\x50\x0f\xb6\xc3\x6a\x08\x50\x88\x5d\xfc\xe8\x14\x02\x00\x00\x83\xc4\x0c\x85\xc0\x75\xde\x38\x45\x18\x0f\x95\xc0\x89\x45\xf8\x80\xfb\x2d\x75\x08\x83\xc8\x02\x89\x45\xf8\xeb\x05\x80\xfb\x2b\x75\x0e\x8b\x75\x0c\x8a\x1e\x46\x88\x5d\xfc\x89\x75\x0c\xeb\x03\x8b\x75\x0c\x85\xff\x74\x05\x83\xff\x10\x75\x78\x8a\xc3\x2c\x30\x3c\x09\x77\x08\x0f\xbe\xc3\x83\xc0\xd0\xeb\x23\x8a\xc3\x2c\x61\x3c\x19\x77\x08\x0f\xbe\xc3\x83\xc0\xa9\xeb\x13\x8a\xc3\x2c\x41\x3c\x19\x77\x08\x0f\xbe\xc3\x83\xc0\xc9\xeb\x03\x83\xc8\xff\x85\xc0\x74\x09\x85\xff\x75\x3d\x6a\x0a\x5f\xeb\x38\x8a\x06\x46\x88\x45\xf0\x89\x75\x0c\x3c\x78\x74\x1b\x3c\x58\x74\x17\x85\xff\x75\x03\x6a\x08\x5f\xff\x75\xf0\x8d\x4d\x0c\xe8\x08\x01\x00\x00\x8b\x75\x0c\xeb\x10\x85\xff\x75\x03\x6a\x10\x5f\x8a\x1e\x46\x88\x5d\xfc\x89\x75\x0c\x33\xd2\x83\xc8\xff\xf7\xf7\x89\x55\xec\x8b\x55\xf8\x89\x45\xf0\x8d\x4b\xd0\x80\xf9\x09\x77\x08\x0f\xbe\xcb\x83\xc1\xd0\xeb\x23\x8a\xc3\x2c\x61\x3c\x19\x77\x08\x0f\xbe\xcb\x83\xc1\xa9\xeb\x13\x8a\xc3\x2c\x41\x3c\x19\x77\x08\x0f\xbe\xcb\x83\xc1\xc9\xeb\x03\x83\xc9\xff\x83\xf9\xff\x74\x30\x3b\xcf\x73\x2c\x8b\x45\xf4\x83\xca\x08\x8b\x5d\xf0\x3b\xc3\x72\x0c\x75\x05\x3b\x4d\xec\x76\x05\x83\xca\x04\xeb\x08\x0f\xaf\xc7\x03\xc1\x89\x45\xf4\x8a\x1e\x46\x88\x5d\xfc\x89\x75\x0c\xeb\x98\xff\x75\xfc\x8d\x4d\x0c\x89\x55\xf8\xe8\x6d\x00\x00\x00\x8b\x5d\xf8\xf6\xc3\x08\x75\x0a\x8b\x45\xe8\x33\xdb\x89\x45\x0c\xeb\x41\x8b\x75\xf4\x56\x53\xe8\xf6\xfd\xff\xff\x59\x59\x84\xc0\x74\x28\xe8\x9d\x03\x00\x00\xc7\x00\x22\x00\x00\x00\xf6\xc3\x01\x75\x05\x83\xce\xff\xeb\x1a\xf6\xc3\x02\x74\x07\xbb\x00\x00\x00\x80\xeb\x10\xbb\xff\xff\xff\x7f\xeb\x09\xf6\xc3\x02\x74\x02\xf7\xde\x8b\xde\x80\x7d\xe4\x00\x5e\x0f\x84\x20\xfe\xff\xff\x8b\x45\xd8\x83\xa0\x50\x03\x00\x00\xfd\xe9\x11\xfe\xff\xff\x8b\xff\x55\x8b\xec\xff\x09\x8a\x45\x08\x8b\x09\x84\xc0\x74\x14\x38\x01\x74\x10\xe8\x3e\x03\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x77\x02\x00\x00\x5d\xc2\x04\x00\x83\x39\x00\x75\x13\xe8\x25\x03\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x5e\x02\x00\x00\x32\xc0\xc3\xb0\x01\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x10\x85\xc0\x74\x0d\x8b\x00\x8b\x08\x8b\x45\x08\x0f\xb7\x04\x41\xeb\x0c\xe8\x6f\x33\x00\x00\x8b\x4d\x08\x0f\xb7\x04\x48\x23\x45\x0c\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x10\x85\xc9\x74\x16\x8b\x01\x83\x78\x04\x01\x7e\x0e\x51\xff\x75\x0c\xff\x75\x08\xe8\x69\x33\x00\x00\xeb\x0c\x51\xff\x75\x0c\xff\x75\x08\xe8\xa8\xff\xff\xff\x83\xc4\x0c\x5d\xc3\x8b\xff\x55\x8b\xec\x8d\x41\x04\x8b\xd0\x2b\xd1\x83\xc2\x03\x56\x33\xf6\xc1\xea\x02\x3b\xc1\x1b\xc0\xf7\xd0\x23\xc2\x74\x0d\x8b\x55\x08\x46\x89\x11\x8d\x49\x04\x3b\xf0\x75\xf6\x5e\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x81\xec\x28\x03\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x83\x7d\x08\xff\x57\x74\x09\xff\x75\x08\xe8\xbf\xc9\xff\xff\x59\x6a\x50\x8d\x85\xe0\xfc\xff\xff\x6a\x00\x50\xe8\xe6\xcf\xff\xff\x68\xcc\x02\x00\x00\x8d\x85\x30\xfd\xff\xff\x6a\x00\x50\xe8\xd3\xcf\xff\xff\x8d\x85\xe0\xfc\xff\xff\x83\xc4\x18\x89\x85\xd8\xfc\xff\xff\x8d\x85\x30\xfd\xff\xff\x89\x85\xdc\xfc\xff\xff\x89\x85\xe0\xfd\xff\xff\x89\x8d\xdc\xfd\xff\xff\x89\x95\xd8\xfd\xff\xff\x89\x9d\xd4\xfd\xff\xff\x89\xb5\xd0\xfd\xff\xff\x89\xbd\xcc\xfd\xff\xff\x66\x8c\x95\xf8\xfd\xff\xff\x66\x8c\x8d\xec\xfd\xff\xff\x66\x8c\x9d\xc8\xfd\xff\xff\x66\x8c\x85\xc4\xfd\xff\xff\x66\x8c\xa5\xc0\xfd\xff\xff\x66\x8c\xad\xbc\xfd\xff\xff\x9c\x8f\x85\xf0\xfd\xff\xff\x8b\x45\x04\x89\x85\xe8\xfd\xff\xff\x8d\x45\x04\x89\x85\xf4\xfd\xff\xff\xc7\x85\x30\xfd\xff\xff\x01\x00\x01\x00\x8b\x40\xfc\x89\x85\xe4\xfd\xff\xff\x8b\x45\x0c\x89\x85\xe0\xfc\xff\xff\x8b\x45\x10\x89\x85\xe4\xfc\xff\xff\x8b\x45\x04\x89\x85\xec\xfc\xff\xff\xff\x15\x7c\x00\x01\x10\x6a\x00\x8b\xf8\xff\x15\x58\x00\x01\x10\x8d\x85\xd8\xfc\xff\xff\x50\xff\x15\x54\x00\x01\x10\x85\xc0\x75\x13\x85\xff\x75\x0f\x83\x7d\x08\xff\x74\x09\xff\x75\x08\xe8\xb8\xc8\xff\xff\x59\x8b\x4d\xfc\x33\xcd\x5f\xe8\x28\xbf\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xff\x75\x08\xb9\x2c\x7c\x01\x10\xe8\x82\xfe\xff\xff\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\xe8\xd8\x15\x00\x00\x85\xc0\x74\x35\x8b\xb0\x5c\x03\x00\x00\x85\xf6\x74\x2b\xff\x75\x18\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\x8b\x4d\xfc\x83\xc4\x14\x33\xcd\x5e\xe8\xc5\xbe\xff\xff\x8b\xe5\x5d\xc3\xff\x75\x18\x8b\x35\x04\x70\x01\x10\x8b\xce\xff\x75\x14\x33\x35\x2c\x7c\x01\x10\x83\xe1\x1f\xff\x75\x10\xd3\xce\xff\x75\x0c\xff\x75\x08\x85\xf6\x75\xbe\xe8\x11\x00\x00\x00\xcc\x33\xc0\x50\x50\x50\x50\x50\xe8\x79\xff\xff\xff\x83\xc4\x14\xc3\x6a\x17\xe8\xfa\x8b\x00\x00\x85\xc0\x74\x05\x6a\x05\x59\xcd\x29\x56\x6a\x01\xbe\x17\x04\x00\xc0\x56\x6a\x02\xe8\x06\xfe\xff\xff\x83\xc4\x0c\x56\xff\x15\x5c\x00\x01\x10\x50\xff\x15\x60\x00\x01\x10\x5e\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x33\xc0\x3b\x0c\xc5\x68\x0c\x01\x10\x74\x27\x40\x83\xf8\x2d\x72\xf1\x8d\x41\xed\x83\xf8\x11\x77\x05\x6a\x0d\x58\x5d\xc3\x8d\x81\x44\xff\xff\xff\x6a\x0e\x59\x3b\xc8\x1b\xc0\x23\xc1\x83\xc0\x08\x5d\xc3\x8b\x04\xc5\x6c\x0c\x01\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x56\xe8\x18\x00\x00\x00\x8b\x4d\x08\x51\x89\x08\xe8\xa7\xff\xff\xff\x59\x8b\xf0\xe8\x18\x00\x00\x00\x89\x30\x5e\x5d\xc3\xe8\xc5\x14\x00\x00\x85\xc0\x75\x06\xb8\x30\x71\x01\x10\xc3\x83\xc0\x14\xc3\xe8\xb2\x14\x00\x00\x85\xc0\x75\x06\xb8\x2c\x71\x01\x10\xc3\x83\xc0\x10\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x53\x56\x57\x8d\x1c\x85\x80\x7c\x01\x10\x8b\x03\x8b\x15\x04\x70\x01\x10\x83\xcf\xff\x8b\xca\x8b\xf2\x83\xe1\x1f\x33\xf0\xd3\xce\x3b\xf7\x74\x69\x85\xf6\x74\x04\x8b\xc6\xeb\x63\x8b\x75\x10\x3b\x75\x14\x74\x1a\xff\x36\xe8\x59\x00\x00\x00\x59\x85\xc0\x75\x2f\x83\xc6\x04\x3b\x75\x14\x75\xec\x8b\x15\x04\x70\x01\x10\x33\xc0\x85\xc0\x74\x29\xff\x75\x0c\x50\xff\x15\xa4\x00\x01\x10\x8b\xf0\x85\xf6\x74\x13\x56\xe8\x6a\xce\xff\xff\x59\x87\x03\xeb\xb9\x8b\x15\x04\x70\x01\x10\xeb\xd9\x8b\x15\x04\x70\x01\x10\x8b\xc2\x6a\x20\x83\xe0\x1f\x59\x2b\xc8\xd3\xcf\x33\xfa\x87\x3b\x33\xc0\x5f\x5e\x5b\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x57\x8d\x3c\x85\x30\x7c\x01\x10\x8b\x0f\x85\xc9\x74\x0b\x8d\x41\x01\xf7\xd8\x1b\xc0\x23\xc1\xeb\x57\x53\x8b\x1c\x85\xd0\x0d\x01\x10\x56\x68\x00\x08\x00\x00\x6a\x00\x53\xff\x15\xa8\x00\x01\x10\x8b\xf0\x85\xf6\x75\x27\xff\x15\xfc\x00\x01\x10\x83\xf8\x57\x75\x0d\x56\x56\x53\xff\x15\xa8\x00\x01\x10\x8b\xf0\xeb\x02\x33\xf6\x85\xf6\x75\x09\x83\xc8\xff\x87\x07\x33\xc0\xeb\x11\x8b\xc6\x87\x07\x85\xc0\x74\x07\x56\xff\x15\xa0\x00\x01\x10\x8b\xc6\x5e\x5b\x5f\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x68\x78\x12\x01\x10\x68\x70\x12\x01\x10\x68\xe4\x02\x01\x10\x6a\x03\xe8\xc2\xfe\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x0f\xff\x75\x08\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\xeb\x06\xff\x15\x90\x00\x01\x10\x8b\x4d\xfc\x33\xcd\x5e\xe8\x5f\xbc\xff\xff\x8b\xe5\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x68\x80\x12\x01\x10\x68\x78\x12\x01\x10\x68\xf8\x02\x01\x10\x6a\x04\xe8\x6c\xfe\xff\xff\x83\xc4\x10\x8b\xf0\xff\x75\x08\x85\xf6\x74\x0c\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\xeb\x06\xff\x15\x9c\x00\x01\x10\x8b\x4d\xfc\x33\xcd\x5e\xe8\x09\xbc\xff\xff\x8b\xe5\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x68\x88\x12\x01\x10\x68\x80\x12\x01\x10\x68\x08\x03\x01\x10\x6a\x05\xe8\x16\xfe\xff\xff\x83\xc4\x10\x8b\xf0\xff\x75\x08\x85\xf6\x74\x0c\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\xeb\x06\xff\x15\x94\x00\x01\x10\x8b\x4d\xfc\x33\xcd\x5e\xe8\xb3\xbb\xff\xff\x8b\xe5\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x68\x90\x12\x01\x10\x68\x88\x12\x01\x10\x68\x1c\x03\x01\x10\x6a\x06\xe8\xc0\xfd\xff\xff\x83\xc4\x10\x8b\xf0\xff\x75\x0c\xff\x75\x08\x85\xf6\x74\x0c\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\xeb\x06\xff\x15\x98\x00\x01\x10\x8b\x4d\xfc\x33\xcd\x5e\xe8\x5a\xbb\xff\xff\x8b\xe5\x5d\xc2\x08\x00\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x68\xb4\x12\x01\x10\x68\xac\x12\x01\x10\x68\x30\x03\x01\x10\x6a\x14\xe8\x67\xfd\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x15\xff\x75\x10\x8b\xce\xff\x75\x0c\xff\x75\x08\xff\x15\x64\x01\x01\x10\xff\xd6\xeb\x0c\xff\x75\x0c\xff\x75\x08\xff\x15\x8c\x00\x01\x10\x8b\x4d\xfc\x33\xcd\x5e\xe8\xf8\xba\xff\xff\x8b\xe5\x5d\xc2\x0c\x00\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x68\xbc\x12\x01\x10\x68\xb4\x12\x01\x10\x68\xbc\x12\x01\x10\x6a\x16\xe8\x05\xfd\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x27\xff\x75\x28\x8b\xce\xff\x75\x24\xff\x75\x20\xff\x75\x1c\xff\x75\x18\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xff\x15\x64\x01\x01\x10\xff\xd6\xeb\x20\xff\x75\x1c\xff\x75\x18\xff\x75\x14\xff\x75\x10\xff\x75\x0c\x6a\x00\xff\x75\x08\xe8\x18\x00\x00\x00\x50\xff\x15\xd8\x00\x01\x10\x8b\x4d\xfc\x33\xcd\x5e\xe8\x70\xba\xff\xff\x8b\xe5\x5d\xc2\x24\x00\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x68\xd4\x12\x01\x10\x68\xcc\x12\x01\x10\x68\xd4\x12\x01\x10\x6a\x18\xe8\x7d\xfc\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x12\xff\x75\x0c\x8b\xce\xff\x75\x08\xff\x15\x64\x01\x01\x10\xff\xd6\xeb\x09\xff\x75\x08\xe8\x74\x2e\x00\x00\x59\x8b\x4d\xfc\x33\xcd\x5e\xe8\x14\xba\xff\xff\x8b\xe5\x5d\xc2\x08\x00\xa1\x04\x70\x01\x10\x57\x6a\x20\x83\xe0\x1f\xbf\x80\x7c\x01\x10\x59\x2b\xc8\x33\xc0\xd3\xc8\x33\x05\x04\x70\x01\x10\x6a\x20\x59\xf3\xab\xb0\x01\x5f\xc3\x8b\xff\x55\x8b\xec\x51\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x0d\x00\x7d\x01\x10\x85\xc9\x74\x0a\x33\xc0\x83\xf9\x01\x0f\x94\xc0\xeb\x54\x56\x68\x98\x12\x01\x10\x68\x90\x12\x01\x10\x68\x98\x12\x01\x10\x6a\x08\xe8\xe6\xfb\xff\xff\x8b\xf0\x83\xc4\x10\x85\xf6\x74\x27\x83\x65\xf8\x00\x8d\x45\xf8\x6a\x00\x50\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\x83\xf8\x7a\x75\x0e\x33\xc9\xba\x00\x7d\x01\x10\x41\x87\x0a\xb0\x01\xeb\x0c\x6a\x02\x58\xb9\x00\x7d\x01\x10\x87\x01\x32\xc0\x5e\x8b\x4d\xfc\x33\xcd\xe8\x65\xb9\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x80\x7d\x08\x00\x75\x27\x56\xbe\x30\x7c\x01\x10\x83\x3e\x00\x74\x10\x83\x3e\xff\x74\x08\xff\x36\xff\x15\xa0\x00\x01\x10\x83\x26\x00\x83\xc6\x04\x81\xfe\x80\x7c\x01\x10\x75\xe0\x5e\xb0\x01\x5d\xc3\x6a\x10\x68\xc0\x5b\x01\x10\xe8\x0b\xc3\xff\xff\x83\x65\xe4\x00\x6a\x08\xe8\x1c\x1d\x00\x00\x59\x83\x65\xfc\x00\x6a\x03\x5e\x89\x75\xe0\x3b\x35\xec\x7b\x01\x10\x74\x58\xa1\xf0\x7b\x01\x10\x8b\x04\xb0\x85\xc0\x74\x49\x8b\x40\x0c\xc1\xe8\x0d\xa8\x01\x74\x16\xa1\xf0\x7b\x01\x10\xff\x34\xb0\xe8\xd4\x2d\x00\x00\x59\x83\xf8\xff\x74\x03\xff\x45\xe4\xa1\xf0\x7b\x01\x10\x8b\x04\xb0\x83\xc0\x20\x50\xff\x15\xbc\x00\x01\x10\xa1\xf0\x7b\x01\x10\xff\x34\xb0\xe8\xa9\xf3\xff\xff\x59\xa1\xf0\x7b\x01\x10\x83\x24\xb0\x00\x46\xeb\x9d\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x09\x00\x00\x00\x8b\x45\xe4\xe8\xc7\xc2\xff\xff\xc3\x6a\x08\xe8\xdd\x1c\x00\x00\x59\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x56\x8d\x71\x0c\x8b\x06\x24\x03\x3c\x02\x74\x04\x33\xc0\xeb\x4b\x8b\x06\xa8\xc0\x74\xf6\x8b\x41\x04\x57\x8b\x39\x2b\xf8\x89\x01\x83\x61\x08\x00\x85\xff\x7e\x30\x57\x50\x51\xe8\x6b\x1a\x00\x00\x59\x50\xe8\x81\x34\x00\x00\x83\xc4\x0c\x3b\xf8\x74\x0b\x6a\x10\x58\xf0\x09\x06\x83\xc8\xff\xeb\x11\x8b\x06\xc1\xe8\x02\xa8\x01\x74\x06\x6a\xfd\x58\xf0\x21\x06\x33\xc0\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x75\x09\x56\xe8\x3d\x00\x00\x00\x59\xeb\x2e\x56\xe8\x7e\xff\xff\xff\x59\x85\xc0\x74\x05\x83\xc8\xff\xeb\x1e\x8b\x46\x0c\xc1\xe8\x0b\xa8\x01\x74\x12\x56\xe8\x07\x1a\x00\x00\x50\xe8\x1f\x2e\x00\x00\x59\x59\x85\xc0\x75\xdf\x33\xc0\x5e\x5d\xc3\x6a\x01\xe8\x02\x00\x00\x00\x59\xc3\x6a\x1c\x68\xe0\x5b\x01\x10\xe8\xb5\xc1\xff\xff\x83\x65\xe4\x00\x83\x65\xdc\x00\x6a\x08\xe8\xc2\x1b\x00\x00\x59\x83\x65\xfc\x00\x8b\x35\xf0\x7b\x01\x10\xa1\xec\x7b\x01\x10\x8d\x04\x86\x89\x45\xd4\x8b\x5d\x08\x89\x75\xe0\x3b\xf0\x74\x74\x8b\x3e\x89\x7d\xd8\x85\xff\x74\x56\x57\xe8\xd2\xd1\xff\xff\x59\xc7\x45\xfc\x01\x00\x00\x00\x8b\x47\x0c\xc1\xe8\x0d\xa8\x01\x74\x32\x83\xfb\x01\x75\x11\x57\xe8\x49\xff\xff\xff\x59\x83\xf8\xff\x74\x21\xff\x45\xe4\xeb\x1c\x85\xdb\x75\x18\x8b\x47\x0c\xd1\xe8\xa8\x01\x74\x0f\x57\xe8\x2b\xff\xff\xff\x59\x83\xf8\xff\x75\x03\x09\x45\xdc\x83\x65\xfc\x00\xe8\x0e\x00\x00\x00\x8b\x45\xd4\x83\xc6\x04\xeb\x95\x8b\x5d\x08\x8b\x75\xe0\xff\x75\xd8\xe8\x83\xd1\xff\xff\x59\xc3\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x14\x00\x00\x00\x83\xfb\x01\x8b\x45\xe4\x74\x03\x8b\x45\xdc\xe8\x3c\xc1\xff\xff\xc3\x8b\x5d\x08\x6a\x08\xe8\x4f\x1b\x00\x00\x59\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x57\x8d\x7e\x0c\x8b\x07\xc1\xe8\x0d\xa8\x01\x74\x24\x8b\x07\xc1\xe8\x06\xa8\x01\x74\x1b\xff\x76\x04\xe8\xc9\xf1\xff\xff\x59\xb8\xbf\xfe\xff\xff\xf0\x21\x07\x33\xc0\x89\x46\x04\x89\x06\x89\x46\x08\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x48\x8d\x45\xb8\x50\xff\x15\x80\x00\x01\x10\x66\x83\x7d\xea\x00\x0f\x84\x95\x00\x00\x00\x8b\x45\xec\x85\xc0\x0f\x84\x8a\x00\x00\x00\x53\x56\x8b\x30\x8d\x58\x04\x8d\x04\x33\x89\x45\xfc\xb8\x00\x20\x00\x00\x3b\xf0\x7c\x02\x8b\xf0\x56\xe8\x54\x36\x00\x00\xa1\x08\x7f\x01\x10\x59\x3b\xf0\x7e\x02\x8b\xf0\x57\x33\xff\x85\xf6\x74\x56\x8b\x45\xfc\x8b\x08\x83\xf9\xff\x74\x40\x83\xf9\xfe\x74\x3b\x8a\x13\xf6\xc2\x01\x74\x34\xf6\xc2\x08\x75\x0b\x51\xff\x15\xe0\x00\x01\x10\x85\xc0\x74\x21\x8b\xc7\x8b\xcf\x83\xe0\x3f\xc1\xf9\x06\x6b\xd0\x30\x8b\x45\xfc\x03\x14\x8d\x08\x7d\x01\x10\x8b\x00\x89\x42\x18\x8a\x03\x88\x42\x28\x8b\x45\xfc\x47\x83\xc0\x04\x43\x89\x45\xfc\x3b\xfe\x75\xad\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\xff\x53\x56\x57\x33\xff\x8b\xc7\x8b\xcf\x83\xe0\x3f\xc1\xf9\x06\x6b\xf0\x30\x03\x34\x8d\x08\x7d\x01\x10\x83\x7e\x18\xff\x74\x0c\x83\x7e\x18\xfe\x74\x06\x80\x4e\x28\x80\xeb\x7b\x8b\xc7\xc6\x46\x28\x81\x83\xe8\x00\x74\x10\x83\xe8\x01\x74\x07\x6a\xf4\x83\xe8\x01\xeb\x06\x6a\xf5\xeb\x02\x6a\xf6\x58\x50\xff\x15\xdc\x00\x01\x10\x8b\xd8\x83\xfb\xff\x74\x0d\x85\xdb\x74\x09\x53\xff\x15\xe0\x00\x01\x10\xeb\x02\x33\xc0\x85\xc0\x74\x1e\x25\xff\x00\x00\x00\x89\x5e\x18\x83\xf8\x02\x75\x06\x80\x4e\x28\x40\xeb\x29\x83\xf8\x03\x75\x24\x80\x4e\x28\x08\xeb\x1e\x80\x4e\x28\x40\xc7\x46\x18\xfe\xff\xff\xff\xa1\xf0\x7b\x01\x10\x85\xc0\x74\x0a\x8b\x04\xb8\xc7\x40\x10\xfe\xff\xff\xff\x47\x83\xff\x03\x0f\x85\x55\xff\xff\xff\x5f\x5e\x5b\xc3\x6a\x0c\x68\x08\x5c\x01\x10\xe8\x33\xbf\xff\xff\x6a\x07\xe8\x48\x19\x00\x00\x59\x33\xdb\x88\x5d\xe7\x89\x5d\xfc\x53\xe8\x0c\x35\x00\x00\x59\x85\xc0\x75\x0f\xe8\x68\xfe\xff\xff\xe8\x19\xff\xff\xff\xb3\x01\x88\x5d\xe7\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0b\x00\x00\x00\x8a\xc3\xe8\x3c\xbf\xff\xff\xc3\x8a\x5d\xe7\x6a\x07\xe8\x4f\x19\x00\x00\x59\xc3\x8b\xff\x56\x33\xf6\x8b\x86\x08\x7d\x01\x10\x85\xc0\x74\x0e\x50\xe8\x8e\x34\x00\x00\x83\xa6\x08\x7d\x01\x10\x00\x59\x83\xc6\x04\x81\xfe\x00\x02\x00\x00\x72\xdd\xb0\x01\x5e\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\xff\x75\x0c\x8d\x4d\xf0\xe8\x83\xd2\xff\xff\x8d\x45\xf4\x50\x6a\x04\xff\x75\x08\xe8\xed\xf3\xff\xff\x83\xc4\x0c\x80\x7d\xfc\x00\x74\x0a\x8b\x4d\xf0\x83\xa1\x50\x03\x00\x00\xfd\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xa1\x18\x7f\x01\x10\x85\xc0\x74\x0e\x6a\x00\xff\x75\x08\xe8\xb0\xff\xff\xff\x59\x59\x5d\xc3\x8b\x4d\x08\xa1\x70\x71\x01\x10\x0f\xb7\x04\x48\x83\xe0\x04\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x1c\x8d\x4d\xe4\x53\xff\x75\x10\xe8\x1d\xd2\xff\xff\x8b\x5d\x08\x81\xfb\x00\x01\x00\x00\x73\x4b\x8d\x45\xe8\x50\x53\xe8\x21\x01\x00\x00\x59\x59\x84\xc0\x74\x24\x80\x7d\xf0\x00\x8b\x45\xe8\x8b\x80\x94\x00\x00\x00\x0f\xb6\x0c\x18\x74\x0a\x8b\x45\xe4\x83\xa0\x50\x03\x00\x00\xfd\x8b\xc1\xe9\xf2\x00\x00\x00\x80\x7d\xf0\x00\x74\x0a\x8b\x4d\xe4\x83\xa1\x50\x03\x00\x00\xfd\x8b\xc3\xe9\xdb\x00\x00\x00\x33\xc0\x66\x89\x45\xfc\x88\x45\xfe\x8b\x45\xe8\x83\x78\x04\x01\x7e\x2e\x8b\xc3\x8d\x4d\xe8\xc1\xf8\x08\x89\x45\xf4\x51\x0f\xb6\xc0\x50\xe8\x8f\x35\x00\x00\x59\x59\x85\xc0\x74\x13\x8b\x45\xf4\x88\x45\xfc\x33\xc0\x6a\x02\x88\x5d\xfd\x88\x45\xfe\x59\xeb\x16\xe8\xe4\xf5\xff\xff\x33\xc9\xc7\x00\x2a\x00\x00\x00\x33\xc0\x88\x5d\xfc\x41\x88\x45\xfd\x66\x89\x45\xf8\x8d\x55\xf8\x88\x45\xfa\x8b\x45\xe8\x6a\x01\xff\x70\x08\x6a\x03\x52\x51\x8d\x4d\xfc\x51\xff\x75\x0c\xff\xb0\xa8\x00\x00\x00\x8d\x45\xe8\x50\xe8\x8a\x37\x00\x00\x83\xc4\x24\x85\xc0\x75\x18\x38\x45\xf0\x0f\x84\x67\xff\xff\xff\x8b\x45\xe4\x83\xa0\x50\x03\x00\x00\xfd\xe9\x58\xff\xff\xff\x83\xf8\x01\x75\x16\x80\x7d\xf0\x00\x0f\xb6\x45\xf8\x74\x2b\x8b\x4d\xe4\x83\xa1\x50\x03\x00\x00\xfd\xeb\x1f\x0f\xb6\x55\xf8\x0f\xb6\x45\xf9\xc1\xe2\x08\x0b\xd0\x80\x7d\xf0\x00\x74\x0a\x8b\x4d\xe4\x83\xa1\x50\x03\x00\x00\xfd\x8b\xc2\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xff\x75\x0c\x6a\x01\xff\x75\x08\xe8\x4d\xf2\xff\xff\x83\xc4\x0c\xf7\xd8\x1b\xc0\xf7\xd8\x5d\xc3\x8b\xff\x55\x8b\xec\xff\x75\x0c\x68\x00\x01\x00\x00\xff\x75\x08\xe8\x84\xfe\xff\xff\x83\xc4\x0c\x5d\xc3\x8b\xff\x55\x8b\xec\xa1\x18\x7f\x01\x10\x85\xc0\x74\x10\x6a\x00\xff\x75\x08\xe8\xce\xff\xff\xff\x59\x59\x8b\xc8\xeb\x0e\x8b\x4d\x08\x8d\x41\xbf\x83\xf8\x19\x77\x03\x83\xc1\x20\x8b\xc1\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x8b\x4d\x10\x8b\x55\x0c\x89\x10\x89\x48\x04\x85\xc9\x74\x02\x89\x11\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x6a\x01\xff\x75\x10\x51\x51\x8b\xc4\xff\x75\x0c\xff\x75\x08\x50\xe8\xca\xff\xff\xff\x83\xc4\x0c\x6a\x00\xe8\x23\xef\xff\xff\x83\xc4\x14\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\x53\x56\x8b\x75\x0c\x85\xf6\x74\x18\x8b\x5d\x10\x85\xdb\x74\x11\x80\x3e\x00\x75\x14\x8b\x45\x08\x85\xc0\x74\x05\x33\xc9\x66\x89\x08\x33\xc0\x5e\x5b\x8b\xe5\x5d\xc3\x57\xff\x75\x14\x8d\x4d\xf0\xe8\xfc\xcf\xff\xff\x8b\x45\xf4\x83\xb8\xa8\x00\x00\x00\x00\x75\x15\x8b\x4d\x08\x85\xc9\x74\x06\x0f\xb6\x06\x66\x89\x01\x33\xff\x47\xe9\x84\x00\x00\x00\x8d\x45\xf4\x50\x0f\xb6\x06\x50\xe8\xbd\x33\x00\x00\x59\x59\x85\xc0\x74\x40\x8b\x7d\xf4\x83\x7f\x04\x01\x7e\x27\x3b\x5f\x04\x7c\x25\x33\xc0\x39\x45\x08\x0f\x95\xc0\x50\xff\x75\x08\xff\x77\x04\x56\x6a\x09\xff\x77\x08\xff\x15\xc8\x00\x01\x10\x8b\x7d\xf4\x85\xc0\x75\x0b\x3b\x5f\x04\x72\x2e\x80\x7e\x01\x00\x74\x28\x8b\x7f\x04\xeb\x31\x33\xc0\x39\x45\x08\x0f\x95\xc0\x33\xff\x50\xff\x75\x08\x8b\x45\xf4\x47\x57\x56\x6a\x09\xff\x70\x08\xff\x15\xc8\x00\x01\x10\x85\xc0\x75\x0e\xe8\xc2\xf3\xff\xff\x83\xcf\xff\xc7\x00\x2a\x00\x00\x00\x80\x7d\xfc\x00\x74\x0a\x8b\x4d\xf0\x83\xa1\x50\x03\x00\x00\xfd\x8b\xc7\x5f\xe9\x31\xff\xff\xff\x8b\xff\x55\x8b\xec\x6a\x00\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\xf1\xfe\xff\xff\x83\xc4\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x14\x53\x8b\x5d\x0c\x57\x8b\x7d\x10\x85\xdb\x75\x12\x85\xff\x74\x0e\x8b\x45\x08\x85\xc0\x74\x03\x83\x20\x00\x33\xc0\xeb\x7a\x8b\x45\x08\x85\xc0\x74\x03\x83\x08\xff\x56\x81\xff\xff\xff\xff\x7f\x76\x11\xe8\x49\xf3\xff\xff\x6a\x16\x5e\x89\x30\xe8\x83\xf2\xff\xff\xeb\x53\xff\x75\x18\x8d\x4d\xec\xe8\xd0\xce\xff\xff\x8b\x45\xf0\x33\xf6\x39\xb0\xa8\x00\x00\x00\x75\x5d\x66\x8b\x45\x14\xb9\xff\x00\x00\x00\x66\x3b\xc1\x76\x36\x85\xdb\x74\x0f\x85\xff\x74\x0b\x57\x56\x53\xe8\x9c\xc0\xff\xff\x83\xc4\x0c\xe8\xff\xf2\xff\xff\x6a\x2a\x5e\x89\x30\x80\x7d\xf8\x00\x74\x0a\x8b\x4d\xec\x83\xa1\x50\x03\x00\x00\xfd\x8b\xc6\x5e\x5f\x5b\x8b\xe5\x5d\xc3\x85\xdb\x74\x06\x85\xff\x74\x5f\x88\x03\x8b\x45\x08\x85\xc0\x74\xd6\xc7\x00\x01\x00\x00\x00\xeb\xce\x8d\x4d\xfc\x89\x75\xfc\x51\x56\x57\x53\x6a\x01\x8d\x4d\x14\x51\x56\xff\x70\x08\xff\x15\xcc\x00\x01\x10\x8b\xc8\x85\xc9\x74\x10\x39\x75\xfc\x75\x9f\x8b\x45\x08\x85\xc0\x74\xa2\x89\x08\xeb\x9e\xff\x15\xfc\x00\x01\x10\x83\xf8\x7a\x75\x89\x85\xdb\x74\x0f\x85\xff\x74\x0b\x57\x56\x53\xe8\x12\xc0\xff\xff\x83\xc4\x0c\xe8\x75\xf2\xff\xff\x6a\x22\x5e\x89\x30\xe8\xaf\xf1\xff\xff\xe9\x6c\xff\xff\xff\x8b\xff\x55\x8b\xec\x6a\x00\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\xc7\xfe\xff\xff\x83\xc4\x14\x5d\xc3\x8b\xff\x55\x8b\xec\xa1\x2c\x7b\x01\x10\x56\x57\x83\xf8\x05\x7c\x7c\x8b\x75\x08\x8b\xd6\x83\xe2\x1f\x6a\x20\x58\x2b\xc2\xf7\xda\x1b\xd2\x23\xd0\x8b\x45\x0c\x3b\xc2\x73\x02\x8b\xd0\x8d\x3c\x32\x8b\xce\x3b\xf7\x74\x0a\x80\x39\x00\x74\x05\x41\x3b\xcf\x75\xf6\x2b\xce\x3b\xca\x0f\x85\xd7\x00\x00\x00\x8b\xf8\x03\xce\x2b\xfa\x8b\xc7\x83\xe0\x1f\x2b\xf8\xc5\xf4\x57\xc9\x03\xf9\xeb\x0f\xc5\xf5\x74\x01\xc5\xfd\xd7\xc0\x85\xc0\x75\x07\x83\xc1\x20\x3b\xcf\x75\xed\x8b\x45\x0c\x03\xc6\xeb\x06\x80\x39\x00\x74\x05\x41\x3b\xc8\x75\xf6\x2b\xce\xc5\xf8\x77\xe9\x94\x00\x00\x00\x83\xf8\x01\x7c\x75\x8b\x75\x08\x8b\xd6\x83\xe2\x0f\x6a\x10\x58\x2b\xc2\xf7\xda\x1b\xd2\x23\xd0\x8b\x45\x0c\x3b\xc2\x73\x02\x8b\xd0\x8d\x3c\x32\x8b\xce\x3b\xf7\x74\x0a\x80\x39\x00\x74\x05\x41\x3b\xcf\x75\xf6\x2b\xce\x3b\xca\x75\x5a\x8b\xf8\x03\xce\x2b\xfa\x66\x0f\xef\xc9\x8b\xc7\x83\xe0\x0f\x2b\xf8\x03\xf9\xeb\x12\x0f\x28\x01\x66\x0f\x74\xc1\x66\x0f\xd7\xc0\x85\xc0\x75\x07\x83\xc1\x10\x3b\xcf\x75\xea\x8b\x45\x0c\x03\xc6\xeb\x06\x80\x39\x00\x74\x05\x41\x3b\xc8\x75\xf6\x2b\xce\xeb\x1a\x8b\x55\x08\x8b\xca\x8b\x45\x0c\x03\xc2\x3b\xd0\x74\x0a\x80\x39\x00\x74\x05\x41\x3b\xc8\x75\xf6\x2b\xca\x5f\x8b\xc1\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x2c\x7b\x01\x10\x8b\x4d\x08\x56\x57\x83\xf8\x05\x0f\x8c\xbc\x00\x00\x00\xf6\xc1\x01\x74\x27\x8b\x45\x0c\x8b\xd1\x8d\x04\x41\x3b\xc8\x0f\x84\x7d\x01\x00\x00\x33\xff\x66\x39\x3a\x0f\x84\x72\x01\x00\x00\x83\xc2\x02\x3b\xd0\x75\xf0\xe9\x66\x01\x00\x00\x8b\xf1\x83\xe6\x1f\x6a\x20\x58\x2b\xc6\xf7\xde\x1b\xf6\x23\xf0\x8b\x45\x0c\xd1\xee\x3b\xc6\x73\x02\x8b\xf0\x8d\x14\x71\x33\xff\x89\x55\xfc\x8b\xd1\x3b\x4d\xfc\x74\x0d\x66\x39\x3a\x74\x08\x83\xc2\x02\x3b\x55\xfc\x75\xf3\x2b\xd1\xd1\xfa\x3b\xd6\x0f\x85\x27\x01\x00\x00\x8d\x14\x51\x8b\xc8\x2b\xce\x8b\xc1\x83\xe0\x1f\x2b\xc8\xc5\xf4\x57\xc9\x8d\x0c\x4a\xeb\x0f\xc5\xf5\x75\x02\xc5\xfd\xd7\xc0\x85\xc0\x75\x07\x83\xc2\x20\x3b\xd1\x75\xed\x8b\x45\x08\x8b\x4d\x0c\x8d\x0c\x48\xeb\x08\x66\x39\x3a\x74\x07\x83\xc2\x02\x3b\xd1\x75\xf4\x2b\xd0\xd1\xfa\xc5\xf8\x77\xe9\xda\x00\x00\x00\x83\xf8\x01\x0f\x8c\xb3\x00\x00\x00\xf6\xc1\x01\x74\x27\x8b\x45\x0c\x8b\xd1\x8d\x04\x41\x3b\xc8\x0f\x84\xb8\x00\x00\x00\x33\xff\x66\x39\x3a\x0f\x84\xad\x00\x00\x00\x83\xc2\x02\x3b\xd0\x75\xf0\xe9\xa1\x00\x00\x00\x8b\xf1\x83\xe6\x0f\x6a\x10\x58\x2b\xc6\xf7\xde\x1b\xf6\x23\xf0\x8b\x45\x0c\xd1\xee\x3b\xc6\x73\x02\x8b\xf0\x8d\x14\x71\x33\xff\x89\x55\xfc\x8b\xd1\x3b\x4d\xfc\x74\x0d\x66\x39\x3a\x74\x08\x83\xc2\x02\x3b\x55\xfc\x75\xf3\x2b\xd1\xd1\xfa\x3b\xd6\x75\x66\x8d\x14\x51\x66\x0f\xef\xc9\x8b\xc8\x2b\xce\x8b\xc1\x83\xe0\x0f\x2b\xc8\x8d\x0c\x4a\xeb\x12\x0f\x28\x02\x66\x0f\x75\xc1\x66\x0f\xd7\xc0\x85\xc0\x75\x07\x83\xc2\x10\x3b\xd1\x75\xea\x8b\x45\x08\x8b\x4d\x0c\x8d\x0c\x48\xeb\x08\x66\x39\x3a\x74\x07\x83\xc2\x02\x3b\xd1\x75\xf4\x2b\xd0\xeb\x1c\x8b\x45\x0c\x8b\xd1\x8d\x04\x41\x3b\xc8\x74\x0e\x33\xff\x66\x39\x3a\x74\x07\x83\xc2\x02\x3b\xd0\x75\xf4\x2b\xd1\xd1\xfa\x5f\x8b\xc2\x5e\x8b\xe5\x5d\xc3\x6a\x08\x68\x48\x5c\x01\x10\xe8\x24\xb7\xff\xff\x8b\x45\x08\xff\x30\xe8\x36\x11\x00\x00\x59\x83\x65\xfc\x00\x8b\x4d\x0c\x8b\x41\x04\x8b\x00\xff\x30\x8b\x01\xff\x30\xe8\xf9\x02\x00\x00\x59\x59\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x08\x00\x00\x00\xe8\x35\xb7\xff\xff\xc2\x0c\x00\x8b\x45\x10\xff\x30\xe8\x46\x11\x00\x00\x59\xc3\x6a\x08\x68\x68\x5c\x01\x10\xe8\xd4\xb6\xff\xff\x8b\x45\x08\xff\x30\xe8\xe6\x10\x00\x00\x59\x83\x65\xfc\x00\x8b\x45\x0c\x8b\x00\x8b\x00\x8b\x48\x48\x85\xc9\x74\x18\x83\xc8\xff\xf0\x0f\xc1\x01\x75\x0f\x81\xf9\x30\x75\x01\x10\x74\x07\x51\xe8\xa7\xe7\xff\xff\x59\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x08\x00\x00\x00\xe8\xd4\xb6\xff\xff\xc2\x0c\x00\x8b\x45\x10\xff\x30\xe8\xe5\x10\x00\x00\x59\xc3\x6a\x08\x68\x88\x5c\x01\x10\xe8\x73\xb6\xff\xff\x8b\x45\x08\xff\x30\xe8\x85\x10\x00\x00\x59\x83\x65\xfc\x00\x6a\x00\x8b\x45\x0c\x8b\x00\xff\x30\xe8\x4d\x02\x00\x00\x59\x59\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x08\x00\x00\x00\xe8\x89\xb6\xff\xff\xc2\x0c\x00\x8b\x45\x10\xff\x30\xe8\x9a\x10\x00\x00\x59\xc3\x6a\x08\x68\x28\x5c\x01\x10\xe8\x28\xb6\xff\xff\x8b\x45\x08\xff\x30\xe8\x3a\x10\x00\x00\x59\x83\x65\xfc\x00\x8b\x45\x0c\x8b\x00\x8b\x00\x8b\x40\x48\xf0\xff\x00\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x08\x00\x00\x00\xe8\x41\xb6\xff\xff\xc2\x0c\x00\x8b\x45\x10\xff\x30\xe8\x52\x10\x00\x00\x59\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\xe8\xfe\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x70\xfe\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\xf9\xfe\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x1c\xff\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x8b\x45\x08\x33\xc9\x41\x6a\x43\x89\x48\x18\x8b\x45\x08\xc7\x00\x28\x0b\x01\x10\x8b\x45\x08\x89\x88\x50\x03\x00\x00\x8b\x45\x08\x59\xc7\x40\x48\x30\x75\x01\x10\x8b\x45\x08\x66\x89\x48\x6c\x8b\x45\x08\x66\x89\x88\x72\x01\x00\x00\x8b\x45\x08\x83\xa0\x4c\x03\x00\x00\x00\x8d\x45\x08\x89\x45\xfc\x8d\x45\xfc\x50\x6a\x05\xe8\x7d\xff\xff\xff\x8d\x45\x08\x89\x45\xf8\x8d\x45\x0c\x89\x45\xfc\x8d\x45\xf8\x50\x6a\x04\xe8\x16\xff\xff\xff\x83\xc4\x10\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\x7d\x08\x00\x74\x12\xff\x75\x08\xe8\x0e\x00\x00\x00\xff\x75\x08\xe8\xbf\xe5\xff\xff\x59\x59\x5d\xc2\x04\x00\x8b\xff\x55\x8b\xec\x51\x8b\x45\x08\x8b\x08\x81\xf9\x28\x0b\x01\x10\x74\x0a\x51\xe8\xa0\xe5\xff\xff\x8b\x45\x08\x59\xff\x70\x3c\xe8\x94\xe5\xff\xff\x8b\x45\x08\xff\x70\x30\xe8\x89\xe5\xff\xff\x8b\x45\x08\xff\x70\x34\xe8\x7e\xe5\xff\xff\x8b\x45\x08\xff\x70\x38\xe8\x73\xe5\xff\xff\x8b\x45\x08\xff\x70\x28\xe8\x68\xe5\xff\xff\x8b\x45\x08\xff\x70\x2c\xe8\x5d\xe5\xff\xff\x8b\x45\x08\xff\x70\x40\xe8\x52\xe5\xff\xff\x8b\x45\x08\xff\x70\x44\xe8\x47\xe5\xff\xff\x8b\x45\x08\xff\xb0\x60\x03\x00\x00\xe8\x39\xe5\xff\xff\x8d\x45\x08\x89\x45\xfc\x8d\x45\xfc\x50\x6a\x05\xe8\x35\xfe\xff\xff\x8d\x45\x08\x89\x45\xfc\x8d\x45\xfc\x50\x6a\x04\xe8\x74\xfe\xff\xff\x83\xc4\x34\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x83\x7e\x4c\x00\x74\x28\xff\x76\x4c\xe8\xc4\x30\x00\x00\x8b\x46\x4c\x59\x3b\x05\x1c\x7f\x01\x10\x74\x14\x3d\x70\x71\x01\x10\x74\x0d\x83\x78\x0c\x00\x75\x07\x50\xe8\xd9\x2e\x00\x00\x59\x8b\x45\x0c\x89\x46\x4c\x5e\x85\xc0\x74\x07\x50\xe8\x4a\x2e\x00\x00\x59\x5d\xc3\xa1\x68\x71\x01\x10\x83\xf8\xff\x74\x21\x56\x50\xe8\xbe\xed\xff\xff\x8b\xf0\x85\xf6\x74\x13\x6a\x00\xff\x35\x68\x71\x01\x10\xe8\x01\xee\xff\xff\x56\xe8\xc1\xfe\xff\xff\x5e\xc3\x8b\xff\x56\x57\xff\x15\xfc\x00\x01\x10\x8b\xf0\xa1\x68\x71\x01\x10\x83\xf8\xff\x74\x0c\x50\xe8\x87\xed\xff\xff\x8b\xf8\x85\xff\x75\x49\x68\x64\x03\x00\x00\x6a\x01\xe8\x90\xe5\xff\xff\x8b\xf8\x59\x59\x85\xff\x75\x09\x50\xe8\x5d\xe4\xff\xff\x59\xeb\x38\x57\xff\x35\x68\x71\x01\x10\xe8\xae\xed\xff\xff\x85\xc0\x75\x03\x57\xeb\xe5\x68\x1c\x7f\x01\x10\x57\xe8\xe9\xfd\xff\xff\x6a\x00\xe8\x35\xe4\xff\xff\x83\xc4\x0c\x85\xff\x74\x0c\x56\xff\x15\xb0\x00\x01\x10\x8b\xc7\x5f\x5e\xc3\x56\xff\x15\xb0\x00\x01\x10\xe8\xf8\xe4\xff\xff\xcc\x8b\xff\x53\x56\x57\xff\x15\xfc\x00\x01\x10\x8b\xf0\x33\xdb\xa1\x68\x71\x01\x10\x83\xf8\xff\x74\x0c\x50\xe8\x00\xed\xff\xff\x8b\xf8\x85\xff\x75\x51\x68\x64\x03\x00\x00\x6a\x01\xe8\x09\xe5\xff\xff\x8b\xf8\x59\x59\x85\xff\x75\x09\x53\xe8\xd6\xe3\xff\xff\x59\xeb\x2b\x57\xff\x35\x68\x71\x01\x10\xe8\x27\xed\xff\xff\x85\xc0\x75\x03\x57\xeb\xe5\x68\x1c\x7f\x01\x10\x57\xe8\x62\xfd\xff\xff\x53\xe8\xaf\xe3\xff\xff\x83\xc4\x0c\x85\xff\x75\x09\x56\xff\x15\xb0\x00\x01\x10\xeb\x09\x56\xff\x15\xb0\x00\x01\x10\x8b\xdf\x5f\x5e\x8b\xc3\x5b\xc3\x68\x2d\x6d\x00\x10\xe8\xe4\xeb\xff\xff\xa3\x68\x71\x01\x10\x83\xf8\xff\x75\x03\x32\xc0\xc3\xe8\x5f\xff\xff\xff\x85\xc0\x75\x09\x50\xe8\x06\x00\x00\x00\x59\xeb\xeb\xb0\x01\xc3\xa1\x68\x71\x01\x10\x83\xf8\xff\x74\x0d\x50\xe8\x08\xec\xff\xff\x83\x0d\x68\x71\x01\x10\xff\xb0\x01\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x0c\x8b\x06\x3b\x05\x1c\x7f\x01\x10\x74\x17\x8b\x4d\x08\xa1\x54\x77\x01\x10\x85\x81\x50\x03\x00\x00\x75\x07\xe8\x6e\x2f\x00\x00\x89\x06\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x0c\x8b\x06\x3b\x05\x50\x77\x01\x10\x74\x17\x8b\x4d\x08\xa1\x54\x77\x01\x10\x85\x81\x50\x03\x00\x00\x75\x07\xe8\x61\x11\x00\x00\x89\x06\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\xb9\xff\x07\x00\x00\x53\x56\x33\xd2\x8b\x18\x8b\x70\x04\x8b\xc6\xc1\xe8\x14\x23\xc1\x57\x3b\xc1\x75\x43\x3b\xd2\x75\x3f\x8b\xfe\x8b\xc3\x81\xe7\xff\xff\x0f\x00\x0b\xc7\x75\x03\x40\xeb\x30\x8b\xce\x8b\xc2\x81\xe1\x00\x00\x00\x80\x0b\xc1\xb8\x00\x00\x08\x00\x74\x0d\x3b\xda\x75\x09\x3b\xf8\x75\x05\x6a\x04\x58\xeb\x10\x23\xf0\x0b\xd6\x74\x04\x6a\x02\xeb\xf3\x6a\x03\xeb\xef\x33\xc0\x5f\x5e\x5b\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x33\xd2\x8b\x48\x04\x8b\xc2\x81\xe1\x00\x00\x00\x80\x0b\xc1\x74\x01\x42\x8a\xc2\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x30\x53\x56\x57\x8b\x7d\x1c\x33\xdb\x85\xff\x79\x02\x8b\xfb\x8b\x75\x0c\x8d\x4d\xd0\xff\x75\x28\x88\x1e\xe8\x12\xc5\xff\xff\x8d\x47\x0b\x39\x45\x10\x77\x14\xe8\x67\xe9\xff\xff\x6a\x22\x5f\x89\x38\xe8\xa1\xe8\xff\xff\xe9\xa8\x02\x00\x00\x8b\x55\x08\x8b\x02\x8b\x4a\x04\x89\x45\xe0\x8b\xc1\xc1\xe8\x14\x25\xff\x07\x00\x00\x3d\xff\x07\x00\x00\x75\x52\x3b\xdb\x75\x4e\x53\xff\x75\x24\x53\x57\xff\x75\x18\xff\x75\x14\xff\x75\x10\x56\x52\xe8\x8b\x02\x00\x00\x8b\xf8\x83\xc4\x24\x85\xff\x74\x07\x88\x1e\xe9\x62\x02\x00\x00\x6a\x65\x56\xe8\x4f\x84\x00\x00\x59\x59\x85\xc0\x74\x13\x38\x5d\x20\x0f\x94\xc1\xfe\xc9\x80\xe1\xe0\x80\xc1\x70\x88\x08\x88\x58\x03\x8b\xfb\xe9\x3a\x02\x00\x00\x81\xe1\x00\x00\x00\x80\x8b\xc3\x0b\xc1\x74\x04\xc6\x06\x2d\x46\x8b\x4a\x04\x33\xdb\x38\x5d\x20\x6a\x30\x0f\x94\xc3\xc7\x45\xf4\xff\x03\x00\x00\x4b\x33\xc0\x83\xe3\xe0\x81\xe1\x00\x00\xf0\x7f\x83\xc3\x27\x0b\xc1\x89\x5d\xe4\x58\x75\x1f\x88\x06\x46\x8b\x42\x04\x8b\x0a\x25\xff\xff\x0f\x00\x0b\xc8\x75\x05\x21\x4d\xf4\xeb\x0d\xc7\x45\xf4\xfe\x03\x00\x00\xeb\x04\xc6\x06\x31\x46\x8b\xce\x46\x89\x4d\xe8\x85\xff\x75\x05\xc6\x01\x00\xeb\x0f\x8b\x45\xd4\x8b\x80\x88\x00\x00\x00\x8b\x00\x8a\x00\x88\x01\x8b\x42\x04\x25\xff\xff\x0f\x00\x89\x45\xf0\x77\x09\x83\x3a\x00\x0f\x86\xc5\x00\x00\x00\x83\x65\xfc\x00\xb9\x00\x00\x0f\x00\x6a\x30\x58\x89\x45\xf8\x89\x4d\xf0\x85\xff\x7e\x53\x8b\x02\x8b\x52\x04\x23\x45\xfc\x23\xd1\x8b\x4d\xf8\x81\xe2\xff\xff\x0f\x00\x0f\xbf\xc9\xe8\x0c\x77\x00\x00\x6a\x30\x59\x66\x03\xc1\x0f\xb7\xc0\x83\xf8\x39\x76\x02\x03\xc3\x8b\x4d\xf0\x8b\x55\x08\x88\x06\x46\x8b\x45\xfc\x0f\xac\xc8\x04\x89\x45\xfc\x8b\x45\xf8\xc1\xe9\x04\x83\xe8\x04\x4f\x89\x4d\xf0\x89\x45\xf8\x66\x85\xc0\x79\xa9\x66\x85\xc0\x78\x57\x8b\x02\x8b\x52\x04\x23\x45\xfc\x23\xd1\x8b\x4d\xf8\x81\xe2\xff\xff\x0f\x00\x0f\xbf\xc9\xe8\xb4\x76\x00\x00\x66\x83\xf8\x08\x76\x36\x6a\x30\x8d\x46\xff\x5b\x8a\x08\x80\xf9\x66\x74\x05\x80\xf9\x46\x75\x05\x88\x18\x48\xeb\xef\x8b\x5d\xe4\x3b\x45\xe8\x74\x14\x8a\x08\x80\xf9\x39\x75\x07\x80\xc3\x3a\x88\x18\xeb\x09\xfe\xc1\x88\x08\xeb\x03\xfe\x40\xff\x85\xff\x7e\x10\x57\x6a\x30\x58\x50\x56\xe8\x19\xb5\xff\xff\x83\xc4\x0c\x03\xf7\x8b\x45\xe8\x80\x38\x00\x75\x02\x8b\xf0\x80\x7d\x20\x00\xb1\x34\x8b\x55\x08\x0f\x94\xc0\xfe\xc8\x24\xe0\x04\x70\x88\x06\x8b\x02\x8b\x52\x04\xe8\x3c\x76\x00\x00\x8b\xc8\x33\xdb\x81\xe1\xff\x07\x00\x00\x2b\x4d\xf4\x1b\xdb\x78\x0f\x7f\x04\x85\xc9\x72\x09\xc6\x46\x01\x2b\x83\xc6\x02\xeb\x0e\xc6\x46\x01\x2d\x83\xc6\x02\xf7\xd9\x83\xd3\x00\xf7\xdb\x8b\xfe\x6a\x30\x58\x88\x06\x85\xdb\x7c\x3f\xb8\xe8\x03\x00\x00\x7f\x04\x3b\xc8\x72\x16\x6a\x00\x50\x53\x51\xe8\x0e\x75\x00\x00\x04\x30\x89\x55\xe4\x88\x06\x46\x3b\xf7\x75\x0b\x85\xdb\x7c\x1a\x7f\x05\x83\xf9\x64\x72\x13\x6a\x00\x6a\x64\x53\x51\xe8\xec\x74\x00\x00\x04\x30\x89\x55\xe4\x88\x06\x46\x3b\xf7\x75\x0b\x85\xdb\x7c\x1a\x7f\x05\x83\xf9\x0a\x72\x13\x6a\x00\x6a\x0a\x53\x51\xe8\xca\x74\x00\x00\x04\x30\x89\x55\xe4\x88\x06\x46\x6a\x30\x58\x02\xc8\x33\xff\x88\x0e\xc6\x46\x01\x00\x80\x7d\xdc\x00\x74\x0a\x8b\x4d\xd0\x83\xa1\x50\x03\x00\x00\xfd\x8b\xc7\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8d\x45\xf4\x56\x8b\x75\x1c\x57\xff\x75\x18\xff\x75\x14\x8d\x7e\x01\x50\x8b\x45\x08\x57\xff\x70\x04\xff\x30\xe8\xe2\x31\x00\x00\x83\xc9\xff\x83\xc4\x18\x39\x4d\x10\x74\x17\x8b\x4d\x10\x33\xc0\x83\x7d\xf4\x2d\x0f\x94\xc0\x2b\xc8\x33\xc0\x85\xf6\x0f\x9f\xc0\x2b\xc8\x8d\x45\xf4\x50\x57\x8b\x7d\x0c\x51\x33\xc9\x83\x7d\xf4\x2d\x0f\x94\xc1\x33\xc0\x85\xf6\x0f\x9f\xc0\x03\xcf\x03\xc1\x50\xe8\x09\x2c\x00\x00\x83\xc4\x10\x85\xc0\x74\x05\xc6\x07\x00\xeb\x1c\xff\x75\x28\x8d\x45\xf4\x6a\x00\x50\xff\x75\x24\xff\x75\x20\x56\xff\x75\x10\x57\xe8\x09\x00\x00\x00\x83\xc4\x20\x5f\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\x56\x57\x8b\x7d\x10\x85\xff\x7e\x04\x8b\xc7\xeb\x02\x33\xc0\x83\xc0\x09\x39\x45\x0c\x77\x17\xe8\xd8\xe5\xff\xff\x6a\x22\x5e\x89\x30\xe8\x12\xe5\xff\xff\x8b\xc6\x5f\x5e\x8b\xe5\x5d\xc3\x53\xff\x75\x24\x8d\x4d\xf0\xe8\x58\xc1\xff\xff\x8a\x55\x20\x8b\x5d\x08\x84\xd2\x74\x25\x8b\x4d\x1c\x33\xc0\x85\xff\x0f\x9f\xc0\x50\x33\xc0\x83\x39\x2d\x0f\x94\xc0\x03\xc3\x50\xff\x75\x0c\x53\xe8\x04\x04\x00\x00\x8a\x55\x20\x83\xc4\x10\x8b\x45\x1c\x8b\xf3\x83\x38\x2d\x75\x06\xc6\x03\x2d\x8d\x73\x01\x85\xff\x7e\x15\x8a\x46\x01\x88\x06\x46\x8b\x45\xf4\x8b\x80\x88\x00\x00\x00\x8b\x00\x8a\x00\x88\x06\x33\xc0\x84\xd2\x0f\x94\xc0\x03\xc7\x03\xf0\x83\xc8\xff\x39\x45\x0c\x74\x07\x8b\xc3\x2b\xc6\x03\x45\x0c\x68\x28\x13\x01\x10\x50\x56\xe8\x90\xde\xff\xff\x83\xc4\x0c\x5b\x85\xc0\x75\x76\x8d\x4e\x02\x38\x45\x14\x74\x03\xc6\x06\x45\x8b\x55\x1c\x8b\x42\x08\x80\x38\x30\x74\x2f\x8b\x52\x04\x83\xea\x01\x79\x06\xf7\xda\xc6\x46\x01\x2d\x6a\x64\x5f\x3b\xd7\x7c\x08\x8b\xc2\x99\xf7\xff\x00\x46\x02\x6a\x0a\x5f\x3b\xd7\x7c\x08\x8b\xc2\x99\xf7\xff\x00\x46\x03\x00\x56\x04\x83\x7d\x18\x02\x75\x14\x80\x39\x30\x75\x0f\x6a\x03\x8d\x41\x01\x50\x51\xe8\x9d\x7a\x00\x00\x83\xc4\x0c\x80\x7d\xfc\x00\x74\x0a\x8b\x45\xf0\x83\xa0\x50\x03\x00\x00\xfd\x33\xc0\xe9\xf2\xfe\xff\xff\x33\xc0\x50\x50\x50\x50\x50\xe8\x06\xe4\xff\xff\xcc\x8b\xff\x55\x8b\xec\x83\xec\x0c\x33\xc0\x56\x57\xff\x75\x18\x8d\x7d\xf4\xff\x75\x14\xab\xab\xab\x8d\x45\xf4\x8b\x7d\x1c\x50\x8b\x45\x08\x57\xff\x70\x04\xff\x30\xe8\xf7\x2f\x00\x00\x83\xc9\xff\x83\xc4\x18\x39\x4d\x10\x74\x0e\x8b\x4d\x10\x33\xc0\x83\x7d\xf4\x2d\x0f\x94\xc0\x2b\xc8\x8b\x75\x0c\x8d\x45\xf4\x50\x8b\x45\xf8\x03\xc7\x50\x33\xc0\x83\x7d\xf4\x2d\x51\x0f\x94\xc0\x03\xc6\x50\xe8\x2b\x2a\x00\x00\x83\xc4\x10\x85\xc0\x74\x05\xc6\x06\x00\xeb\x16\xff\x75\x20\x8d\x45\xf4\x6a\x00\x50\x57\xff\x75\x10\x56\xe8\x09\x00\x00\x00\x83\xc4\x18\x5f\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\x8d\x4d\xf0\x53\x56\x57\xff\x75\x1c\xe8\xac\xbf\xff\xff\x8b\x55\x14\x8b\x7d\x10\x8b\x5d\x08\x8b\x4a\x04\x49\x80\x7d\x18\x00\x74\x14\x3b\xcf\x75\x10\x33\xc0\x83\x3a\x2d\x0f\x94\xc0\x03\xc1\x66\xc7\x04\x18\x30\x00\x83\x3a\x2d\x8b\xf3\x75\x06\xc6\x03\x2d\x8d\x73\x01\x8b\x42\x04\x85\xc0\x7f\x15\x6a\x01\x56\xff\x75\x0c\x53\xe8\x3a\x02\x00\x00\x83\xc4\x10\xc6\x06\x30\x46\xeb\x02\x03\xf0\x85\xff\x7e\x52\x6a\x01\x56\xff\x75\x0c\x53\xe8\x1f\x02\x00\x00\x8b\x45\xf4\x83\xc4\x10\x8b\x80\x88\x00\x00\x00\x8b\x00\x8a\x00\x88\x06\x46\x8b\x45\x14\x8b\x48\x04\x85\xc9\x79\x29\x80\x7d\x18\x00\x75\x08\x8b\xc1\xf7\xd8\x3b\xc7\x7d\x04\x8b\xf9\xf7\xdf\x57\x56\xff\x75\x0c\x53\xe8\xe5\x01\x00\x00\x57\x6a\x30\x56\xe8\xfe\xb0\xff\xff\x83\xc4\x1c\x80\x7d\xfc\x00\x5f\x5e\x5b\x74\x0a\x8b\x45\xf0\x83\xa0\x50\x03\x00\x00\xfd\x33\xc0\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\x53\x56\x57\xff\x75\x18\x33\xc0\x8d\x7d\xf0\xff\x75\x14\xab\xab\xab\x8d\x45\xf0\x8b\x7d\x1c\x50\x8b\x45\x08\x57\xff\x70\x04\xff\x30\xe8\x92\x2e\x00\x00\x8b\x45\xf4\x33\xc9\x8b\x5d\x0c\x83\xc4\x18\x83\x7d\xf0\x2d\x0f\x94\xc1\x48\x89\x45\xfc\x83\xc8\xff\x8d\x34\x19\x39\x45\x10\x74\x05\x8b\x45\x10\x2b\xc1\x8d\x4d\xf0\x51\x57\x50\x56\xe8\xcc\x28\x00\x00\x83\xc4\x10\x85\xc0\x74\x05\xc6\x03\x00\xeb\x55\x8b\x45\xf4\x48\x39\x45\xfc\x0f\x9c\xc1\x83\xf8\xfc\x7c\x2a\x3b\xc7\x7d\x26\x84\xc9\x74\x0a\x8a\x06\x46\x84\xc0\x75\xf9\x88\x46\xfe\xff\x75\x28\x8d\x45\xf0\x6a\x01\x50\x57\xff\x75\x10\x53\xe8\x89\xfe\xff\xff\x83\xc4\x18\xeb\x1c\xff\x75\x28\x8d\x45\xf0\x6a\x01\x50\xff\x75\x24\xff\x75\x20\x57\xff\x75\x10\x53\xe8\x93\xfc\xff\xff\x83\xc4\x20\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x48\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x55\x14\x8b\x4d\x10\x53\x8a\x5d\x0c\x0f\xb6\xc3\x83\xc0\x04\x3b\xd0\x73\x15\x6a\x0c\xc6\x01\x00\x58\x8b\x4d\xfc\x33\xcd\x5b\xe8\x27\xa0\xff\xff\x8b\xe5\x5d\xc3\x84\xdb\x74\x08\xc6\x01\x2d\x41\x4a\xc6\x01\x00\xb8\xe8\x12\x01\x10\xc7\x45\xdc\xf8\x12\x01\x10\x89\x45\xbc\x33\xdb\x38\x5d\x18\x89\x45\xc0\xb8\xec\x12\x01\x10\x89\x45\xc4\x0f\x95\xc3\x89\x45\xc8\x4b\xb8\xf4\x12\x01\x10\xc7\x45\xe4\x04\x13\x01\x10\x89\x45\xd4\x83\xe3\x02\x89\x45\xd8\x89\x45\xe8\x89\x45\xf8\x8b\x45\x08\x56\xbe\xf0\x12\x01\x10\xc7\x45\xec\x10\x13\x01\x10\x57\x8d\x3c\x85\xfc\xff\xff\xff\x89\x75\xcc\x8d\x04\x1f\x89\x75\xd0\x89\x75\xe0\x89\x75\xf0\xc7\x45\xf4\x1c\x13\x01\x10\x8b\x74\x85\xbc\x8d\x46\x01\x89\x45\xb8\x8a\x06\x46\x84\xc0\x75\xf9\x2b\x75\xb8\x3b\xf2\x1b\xc0\x47\x03\xc7\x03\xc3\xff\x74\x85\xbc\x52\x51\xe8\xfb\xda\xff\xff\x83\xc4\x0c\x5f\x5e\x85\xc0\x0f\x84\x41\xff\xff\xff\x33\xc0\x50\x50\x50\x50\x50\xe8\xe2\xe0\xff\xff\xcc\x8b\xff\x55\x8b\xec\x8b\x55\x14\x85\xd2\x74\x26\x56\x8b\x75\x10\x8b\xce\x57\x8d\x79\x01\x8a\x01\x41\x84\xc0\x75\xf9\x2b\xcf\x8d\x41\x01\x50\x8d\x04\x16\x56\x50\xe8\x25\x77\x00\x00\x83\xc4\x0c\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x56\x57\x8b\x7d\x0c\x85\xff\x75\x16\xe8\x44\xe1\xff\xff\x6a\x16\x5e\x89\x30\xe8\x7e\xe0\xff\xff\x8b\xc6\xe9\x1e\x01\x00\x00\x53\x8b\x5d\x10\x85\xdb\x74\x0c\x83\x7d\x14\x00\x74\x06\x83\x7d\x18\x00\x77\x16\xe8\x1a\xe1\xff\xff\x6a\x16\x5e\x89\x30\xe8\x54\xe0\xff\xff\x8b\xc6\xe9\xf3\x00\x00\x00\x8b\x75\x1c\x83\xfe\x41\x74\x13\x83\xfe\x45\x74\x0e\x83\xfe\x46\x74\x09\xc6\x45\xfc\x00\x83\xfe\x47\x75\x04\xc6\x45\xfc\x01\x8b\x45\x24\x83\xe0\x08\x83\xc8\x00\x75\x32\xff\x75\x08\xe8\xb3\xf6\xff\xff\x89\x45\xf8\x59\x85\xc0\x74\x22\xff\x75\xfc\x53\x57\xff\x75\x08\xe8\x0a\xf7\xff\xff\x59\x0f\xb6\xc0\x50\xff\x75\xf8\xe8\x30\xfe\xff\xff\x83\xc4\x14\xe9\x97\x00\x00\x00\x8b\x45\x24\x83\xe0\x10\x83\xc8\x00\x74\x04\x6a\x03\xeb\x02\x6a\x02\x58\x83\xfe\x61\x7f\x28\x74\x0a\x83\xee\x41\x74\x05\x83\xee\x04\xeb\x1f\xff\x75\x2c\x50\xff\x75\xfc\xff\x75\x20\xff\x75\x18\xff\x75\x14\x53\x57\xff\x75\x08\xe8\xd6\xf6\xff\xff\xeb\x55\x83\xee\x65\xff\x75\x2c\x74\x36\x83\xee\x01\x74\x19\x50\xff\x75\xfc\xff\x75\x20\xff\x75\x18\xff\x75\x14\x53\x57\xff\x75\x08\xe8\xfd\xfc\xff\xff\xeb\x2f\xff\x75\x20\xff\x75\x18\xff\x75\x14\x53\x57\xff\x75\x08\xe8\x84\xfb\xff\xff\x83\xc4\x1c\xeb\x1a\x50\xff\x75\xfc\xff\x75\x20\xff\x75\x18\xff\x75\x14\x53\x57\xff\x75\x08\xe8\x82\xf9\xff\xff\x83\xc4\x24\x5b\x5f\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x85\xc0\x75\x15\xe8\xfe\xdf\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x37\xdf\xff\xff\x83\xc8\xff\x5d\xc3\x8b\x40\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x0c\x83\x6a\x08\x01\x79\x0d\x52\xff\x75\x08\xe8\x3f\x41\x00\x00\x59\x59\x5d\xc3\x8b\x02\x8b\x4d\x08\x88\x08\xff\x02\x0f\xb6\xc1\x5d\xc3\x8b\x0d\x04\x70\x01\x10\x33\xc0\x83\xc9\x01\x39\x0d\x0c\x7f\x01\x10\x0f\x94\xc0\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x56\xe8\x8d\xff\xff\xff\x50\xe8\x0e\x41\x00\x00\x59\x59\x85\xc0\x75\x07\x32\xc0\xe9\x90\x00\x00\x00\x53\x57\x6a\x01\xe8\x44\xb7\xff\xff\x59\x6a\x02\x5b\x3b\xf0\x75\x07\xbf\x10\x7f\x01\x10\xeb\x10\x53\xe8\x2f\xb7\xff\xff\x59\x3b\xf0\x75\x69\xbf\x14\x7f\x01\x10\xff\x05\xf4\x7b\x01\x10\x8d\x4e\x0c\x8b\x01\xa9\xc0\x04\x00\x00\x75\x52\xb8\x82\x02\x00\x00\xf0\x09\x01\x8b\x07\x85\xc0\x75\x2b\x68\x00\x10\x00\x00\xe8\x3d\xd8\xff\xff\x6a\x00\x89\x07\xe8\xfa\xd7\xff\xff\x8b\x07\x59\x59\x85\xc0\x75\x10\x8d\x4e\x14\x89\x5e\x08\x89\x4e\x04\x89\x0e\x89\x5e\x18\xeb\x15\x89\x46\x04\x8b\x07\x89\x06\xc7\x46\x08\x00\x10\x00\x00\xc7\x46\x18\x00\x10\x00\x00\xb0\x01\xeb\x02\x32\xc0\x5f\x5b\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x80\x7d\x08\x00\x74\x2c\x56\x8b\x75\x0c\x57\x8d\x7e\x0c\x8b\x07\xc1\xe8\x09\xa8\x01\x74\x19\x56\xe8\x22\xe4\xff\xff\x59\xb8\x7f\xfd\xff\xff\xf0\x21\x07\x33\xc0\x89\x46\x18\x89\x46\x04\x89\x06\x5f\x5e\x5d\xc3\x33\xc0\xb9\x18\x7f\x01\x10\x40\x87\x01\xc3\x6a\x08\x68\xa8\x5c\x01\x10\xe8\x6b\xa6\xff\xff\xbe\x70\x71\x01\x10\x39\x35\x1c\x7f\x01\x10\x74\x2a\x6a\x04\xe8\x73\x00\x00\x00\x59\x83\x65\xfc\x00\x56\x68\x1c\x7f\x01\x10\xe8\x11\x24\x00\x00\x59\x59\xa3\x1c\x7f\x01\x10\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x06\x00\x00\x00\xe8\x75\xa6\xff\xff\xc3\x6a\x04\xe8\x8b\x00\x00\x00\x59\xc3\x8b\xff\x56\x57\xbf\x20\x7f\x01\x10\x33\xf6\x6a\x00\x68\xa0\x0f\x00\x00\x57\xe8\xcd\xe0\xff\xff\x85\xc0\x74\x18\xff\x05\x58\x80\x01\x10\x83\xc6\x18\x83\xc7\x18\x81\xfe\x38\x01\x00\x00\x72\xdb\xb0\x01\xeb\x0a\x6a\x00\xe8\x1d\x00\x00\x00\x59\x32\xc0\x5f\x5e\xc3\x8b\xff\x55\x8b\xec\x6b\x45\x08\x18\x05\x20\x7f\x01\x10\x50\xff\x15\xb4\x00\x01\x10\x5d\xc3\x8b\xff\x56\x8b\x35\x58\x80\x01\x10\x85\xf6\x74\x20\x6b\xc6\x18\x57\x8d\xb8\x08\x7f\x01\x10\x57\xff\x15\xbc\x00\x01\x10\xff\x0d\x58\x80\x01\x10\x83\xef\x18\x83\xee\x01\x75\xeb\x5f\xb0\x01\x5e\xc3\x8b\xff\x55\x8b\xec\x6b\x45\x08\x18\x05\x20\x7f\x01\x10\x50\xff\x15\xb8\x00\x01\x10\x5d\xc3\x6a\x08\x68\xe8\x5c\x01\x10\xe8\x79\xa5\xff\xff\x8b\x45\x08\xff\x30\xe8\x8b\xff\xff\xff\x59\x83\x65\xfc\x00\x8b\x4d\x0c\xe8\x48\x00\x00\x00\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x08\x00\x00\x00\xe8\x97\xa5\xff\xff\xc2\x0c\x00\x8b\x45\x10\xff\x30\xe8\xa8\xff\xff\xff\x59\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x99\xff\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x56\x8b\xf1\x6a\x0c\x8b\x06\x8b\x00\x8b\x40\x48\x8b\x40\x04\xa3\x60\x80\x01\x10\x8b\x06\x8b\x00\x8b\x40\x48\x8b\x40\x08\xa3\x64\x80\x01\x10\x8b\x06\x8b\x00\x8b\x40\x48\x8b\x80\x1c\x02\x00\x00\xa3\x5c\x80\x01\x10\x8b\x06\x8b\x00\x8b\x40\x48\x83\xc0\x0c\x50\x6a\x0c\x68\x68\x80\x01\x10\xe8\x16\x3c\x00\x00\x8b\x06\xb9\x01\x01\x00\x00\x51\x8b\x00\x8b\x40\x48\x83\xc0\x18\x50\x51\x68\x28\x73\x01\x10\xe8\xfa\x3b\x00\x00\x8b\x06\xb9\x00\x01\x00\x00\x51\x8b\x00\x8b\x40\x48\x05\x19\x01\x00\x00\x50\x51\x68\x30\x74\x01\x10\xe8\xdc\x3b\x00\x00\xa1\x50\x77\x01\x10\x83\xc4\x30\x83\xc9\xff\xf0\x0f\xc1\x08\x75\x13\xa1\x50\x77\x01\x10\x3d\x30\x75\x01\x10\x74\x07\x50\xe8\x76\xd5\xff\xff\x59\x8b\x06\x8b\x00\x8b\x40\x48\xa3\x50\x77\x01\x10\x8b\x06\x8b\x00\x8b\x40\x48\xf0\xff\x00\x5e\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x2d\xa4\x03\x00\x00\x74\x28\x83\xe8\x04\x74\x1c\x83\xe8\x0d\x74\x10\x83\xe8\x01\x74\x04\x33\xc0\x5d\xc3\xa1\x00\x18\x01\x10\x5d\xc3\xa1\xfc\x17\x01\x10\x5d\xc3\xa1\xf8\x17\x01\x10\x5d\xc3\xa1\xf4\x17\x01\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\x8d\x4d\xf0\x6a\x00\xe8\xdf\xb7\xff\xff\x83\x25\x74\x80\x01\x10\x00\x8b\x45\x08\x83\xf8\xfe\x75\x12\xc7\x05\x74\x80\x01\x10\x01\x00\x00\x00\xff\x15\xec\x00\x01\x10\xeb\x2c\x83\xf8\xfd\x75\x12\xc7\x05\x74\x80\x01\x10\x01\x00\x00\x00\xff\x15\xe4\x00\x01\x10\xeb\x15\x83\xf8\xfc\x75\x10\x8b\x45\xf4\xc7\x05\x74\x80\x01\x10\x01\x00\x00\x00\x8b\x40\x08\x80\x7d\xfc\x00\x74\x0a\x8b\x4d\xf0\x83\xa1\x50\x03\x00\x00\xfd\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x53\x8b\x5d\x08\x56\x57\x68\x01\x01\x00\x00\x33\xff\x8d\x73\x18\x57\x56\xe8\x59\xa9\xff\xff\x89\x7b\x04\x33\xc0\x89\x7b\x08\x83\xc4\x0c\x89\xbb\x1c\x02\x00\x00\xb9\x01\x01\x00\x00\x8d\x7b\x0c\xab\xab\xab\xbf\x30\x75\x01\x10\x2b\xfb\x8a\x04\x37\x88\x06\x46\x83\xe9\x01\x75\xf5\x8d\x8b\x19\x01\x00\x00\xba\x00\x01\x00\x00\x8a\x04\x39\x88\x01\x41\x83\xea\x01\x75\xf5\x5f\x5e\x5b\x5d\xc3\x8b\xff\x55\x8b\xec\x81\xec\x20\x07\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x53\x56\x8b\x75\x08\x8d\x85\xe8\xf8\xff\xff\x57\x50\xff\x76\x04\xff\x15\xf0\x00\x01\x10\x33\xdb\xbf\x00\x01\x00\x00\x85\xc0\x0f\x84\xf0\x00\x00\x00\x8b\xc3\x88\x84\x05\xfc\xfe\xff\xff\x40\x3b\xc7\x72\xf4\x8a\x85\xee\xf8\xff\xff\x8d\x8d\xee\xf8\xff\xff\xc6\x85\xfc\xfe\xff\xff\x20\xeb\x1f\x0f\xb6\x51\x01\x0f\xb6\xc0\xeb\x0d\x3b\xc7\x73\x0d\xc6\x84\x05\xfc\xfe\xff\xff\x20\x40\x3b\xc2\x76\xef\x83\xc1\x02\x8a\x01\x84\xc0\x75\xdd\x53\xff\x76\x04\x8d\x85\xfc\xf8\xff\xff\x50\x57\x8d\x85\xfc\xfe\xff\xff\x50\x6a\x01\x53\xe8\x35\x3f\x00\x00\x53\xff\x76\x04\x8d\x85\xfc\xfd\xff\xff\x57\x50\x57\x8d\x85\xfc\xfe\xff\xff\x50\x57\xff\xb6\x1c\x02\x00\x00\x53\xe8\xa2\x1c\x00\x00\x83\xc4\x40\x8d\x85\xfc\xfc\xff\xff\x53\xff\x76\x04\x57\x50\x57\x8d\x85\xfc\xfe\xff\xff\x50\x68\x00\x02\x00\x00\xff\xb6\x1c\x02\x00\x00\x53\xe8\x7a\x1c\x00\x00\x83\xc4\x24\x8b\xcb\x0f\xb7\x84\x4d\xfc\xf8\xff\xff\xa8\x01\x74\x0e\x80\x4c\x0e\x19\x10\x8a\x84\x0d\xfc\xfd\xff\xff\xeb\x10\xa8\x02\x74\x15\x80\x4c\x0e\x19\x20\x8a\x84\x0d\xfc\xfc\xff\xff\x88\x84\x0e\x19\x01\x00\x00\xeb\x07\x88\x9c\x0e\x19\x01\x00\x00\x41\x3b\xcf\x72\xc1\xeb\x59\x6a\x9f\x8d\x96\x19\x01\x00\x00\x8b\xcb\x58\x2b\xc2\x89\x85\xe0\xf8\xff\xff\x03\xd1\x03\xc2\x89\x85\xe4\xf8\xff\xff\x83\xc0\x20\x83\xf8\x19\x77\x0a\x80\x4c\x0e\x19\x10\x8d\x41\x20\xeb\x13\x83\xbd\xe4\xf8\xff\xff\x19\x77\x0e\x8d\x04\x0e\x80\x48\x19\x20\x8d\x41\xe0\x88\x02\xeb\x02\x88\x1a\x8b\x85\xe0\xf8\xff\xff\x8d\x96\x19\x01\x00\x00\x41\x3b\xcf\x72\xba\x8b\x4d\xfc\x5f\x5e\x33\xcd\x5b\xe8\xc4\x97\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\xe8\x0d\xee\xff\xff\x89\x45\xfc\xe8\x0a\x01\x00\x00\xff\x75\x08\xe8\x77\xfd\xff\xff\x59\x8b\x4d\xfc\x89\x45\xf4\x8b\x49\x48\x3b\x41\x04\x75\x04\x33\xc0\xeb\x53\x53\x56\x57\x68\x20\x02\x00\x00\xe8\xb0\xd2\xff\xff\x8b\xf8\x83\xcb\xff\x59\x85\xff\x74\x2e\x8b\x75\xfc\xb9\x88\x00\x00\x00\x8b\x76\x48\xf3\xa5\x8b\xf8\x57\xff\x75\xf4\x83\x27\x00\xe8\x5f\x01\x00\x00\x8b\xf0\x59\x59\x3b\xf3\x75\x1d\xe8\x78\xd9\xff\xff\xc7\x00\x16\x00\x00\x00\x8b\xf3\x57\xe8\x36\xd2\xff\xff\x59\x5f\x8b\xc6\x5e\x5b\x8b\xe5\x5d\xc3\x80\x7d\x0c\x00\x75\x05\xe8\x98\xfa\xff\xff\x8b\x45\xfc\x8b\x40\x48\xf0\x0f\xc1\x18\x4b\x75\x15\x8b\x45\xfc\x81\x78\x48\x30\x75\x01\x10\x74\x09\xff\x70\x48\xe8\x00\xd2\xff\xff\x59\xc7\x07\x01\x00\x00\x00\x8b\xcf\x8b\x45\xfc\x33\xff\x89\x48\x48\x8b\x45\xfc\xf6\x80\x50\x03\x00\x00\x02\x75\xa7\xf6\x05\x54\x77\x01\x10\x01\x75\x9e\x8d\x45\xfc\x89\x45\xf4\x8d\x45\xf4\x50\x6a\x05\xe8\x80\xfb\xff\xff\x80\x7d\x0c\x00\x59\x59\x74\x85\xa1\x50\x77\x01\x10\xa3\x2c\x72\x01\x10\xe9\x76\xff\xff\xff\x80\x3d\x78\x80\x01\x10\x00\x75\x12\x6a\x01\x6a\xfd\xe8\xed\xfe\xff\xff\x59\x59\xc6\x05\x78\x80\x01\x10\x01\xb0\x01\xc3\x6a\x0c\x68\xc8\x5c\x01\x10\xe8\x81\xa0\xff\xff\x33\xf6\x89\x75\xe4\xe8\xe5\xec\xff\xff\x8b\xf8\x8b\x0d\x54\x77\x01\x10\x85\x8f\x50\x03\x00\x00\x74\x11\x39\x77\x4c\x74\x0c\x8b\x77\x48\x85\xf6\x75\x68\xe8\x3f\xd2\xff\xff\x6a\x05\xe8\x6b\xfa\xff\xff\x59\x89\x75\xfc\x8b\x77\x48\x89\x75\xe4\x3b\x35\x50\x77\x01\x10\x74\x30\x85\xf6\x74\x18\x83\xc8\xff\xf0\x0f\xc1\x06\x75\x0f\x81\xfe\x30\x75\x01\x10\x74\x07\x56\xe8\x29\xd1\xff\xff\x59\xa1\x50\x77\x01\x10\x89\x47\x48\x8b\x35\x50\x77\x01\x10\x89\x75\xe4\xf0\xff\x06\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x05\x00\x00\x00\xeb\xa0\x8b\x75\xe4\x6a\x05\xe8\x59\xfa\xff\xff\x59\xc3\x8b\xc6\xe8\x32\xa0\xff\xff\xc3\x8b\xff\x55\x8b\xec\x83\xec\x20\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x53\x56\xff\x75\x08\x8b\x75\x0c\xe8\xb4\xfb\xff\xff\x8b\xd8\x59\x85\xdb\x75\x0e\x56\xe8\x1a\xfc\xff\xff\x59\x33\xc0\xe9\xad\x01\x00\x00\x57\x33\xff\x8b\xcf\x8b\xc7\x89\x4d\xe4\x39\x98\x38\x72\x01\x10\x0f\x84\xea\x00\x00\x00\x41\x83\xc0\x30\x89\x4d\xe4\x3d\xf0\x00\x00\x00\x72\xe6\x81\xfb\xe8\xfd\x00\x00\x0f\x84\xc8\x00\x00\x00\x81\xfb\xe9\xfd\x00\x00\x0f\x84\xbc\x00\x00\x00\x0f\xb7\xc3\x50\xff\x15\xe8\x00\x01\x10\x85\xc0\x0f\x84\xaa\x00\x00\x00\x8d\x45\xe8\x50\x53\xff\x15\xf0\x00\x01\x10\x85\xc0\x0f\x84\x84\x00\x00\x00\x68\x01\x01\x00\x00\x8d\x46\x18\x57\x50\xe8\x17\xa5\xff\xff\x89\x5e\x04\x83\xc4\x0c\x33\xdb\x89\xbe\x1c\x02\x00\x00\x43\x39\x5d\xe8\x76\x51\x80\x7d\xee\x00\x8d\x45\xee\x74\x21\x8a\x48\x01\x84\xc9\x74\x1a\x0f\xb6\xd1\x0f\xb6\x08\xeb\x06\x80\x4c\x0e\x19\x04\x41\x3b\xca\x76\xf6\x83\xc0\x02\x80\x38\x00\x75\xdf\x8d\x46\x1a\xb9\xfe\x00\x00\x00\x80\x08\x08\x40\x83\xe9\x01\x75\xf7\xff\x76\x04\xe8\x9a\xfa\xff\xff\x83\xc4\x04\x89\x86\x1c\x02\x00\x00\x89\x5e\x08\xeb\x03\x89\x7e\x08\x33\xc0\x8d\x7e\x0c\xab\xab\xab\xe9\xbe\x00\x00\x00\x39\x3d\x74\x80\x01\x10\x74\x0b\x56\xe8\x1f\xfb\xff\xff\xe9\xb1\x00\x00\x00\x83\xc8\xff\xe9\xac\x00\x00\x00\x68\x01\x01\x00\x00\x8d\x46\x18\x57\x50\xe8\x78\xa4\xff\xff\x83\xc4\x0c\x6b\x45\xe4\x30\x89\x45\xe0\x8d\x80\x48\x72\x01\x10\x89\x45\xe4\x80\x38\x00\x8b\xc8\x74\x35\x8a\x41\x01\x84\xc0\x74\x2b\x0f\xb6\x11\x0f\xb6\xc0\xeb\x17\x81\xfa\x00\x01\x00\x00\x73\x13\x8a\x87\x34\x72\x01\x10\x08\x44\x16\x19\x42\x0f\xb6\x41\x01\x3b\xd0\x76\xe5\x83\xc1\x02\x80\x39\x00\x75\xce\x8b\x45\xe4\x47\x83\xc0\x08\x89\x45\xe4\x83\xff\x04\x72\xb8\x53\x89\x5e\x04\xc7\x46\x08\x01\x00\x00\x00\xe8\xe7\xf9\xff\xff\x83\xc4\x04\x89\x86\x1c\x02\x00\x00\x8b\x45\xe0\x8d\x4e\x0c\x6a\x06\x8d\x90\x3c\x72\x01\x10\x5f\x66\x8b\x02\x8d\x52\x02\x66\x89\x01\x8d\x49\x02\x83\xef\x01\x75\xef\x56\xe8\xce\xfa\xff\xff\x59\x33\xc0\x5f\x8b\x4d\xfc\x5e\x33\xcd\x5b\xe8\x12\x94\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x57\x33\xff\x66\x39\x3a\x74\x21\x56\x8b\xca\x8d\x71\x02\x66\x8b\x01\x83\xc1\x02\x66\x3b\xc7\x75\xf5\x2b\xce\xd1\xf9\x8d\x14\x4a\x83\xc2\x02\x66\x39\x3a\x75\xe1\x5e\x8d\x42\x02\x5f\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x53\x56\x57\xff\x15\xf4\x00\x01\x10\x8b\xf0\x33\xff\x85\xf6\x74\x56\x56\xe8\xac\xff\xff\xff\x59\x57\x57\x57\x8b\xd8\x57\x2b\xde\xd1\xfb\x53\x56\x57\x57\xff\x15\xcc\x00\x01\x10\x89\x45\xfc\x85\xc0\x74\x34\x50\xe8\xc5\xce\xff\xff\x8b\xf8\x59\x85\xff\x74\x1c\x33\xc0\x50\x50\xff\x75\xfc\x57\x53\x56\x50\x50\xff\x15\xcc\x00\x01\x10\x85\xc0\x74\x06\x8b\xdf\x33\xff\xeb\x02\x33\xdb\x57\xe8\x60\xce\xff\xff\x59\xeb\x02\x8b\xdf\x85\xf6\x74\x07\x56\xff\x15\xf8\x00\x01\x10\x5f\x5e\x8b\xc3\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x5d\xe9\x00\x00\x00\x00\x8b\xff\x55\x8b\xec\x56\x8b\x75\x0c\x85\xf6\x74\x1b\x6a\xe0\x33\xd2\x58\xf7\xf6\x3b\x45\x10\x73\x0f\xe8\x52\xd5\xff\xff\xc7\x00\x0c\x00\x00\x00\x33\xc0\xeb\x42\x53\x8b\x5d\x08\x57\x85\xdb\x74\x0b\x53\xe8\xba\x3a\x00\x00\x59\x8b\xf8\xeb\x02\x33\xff\x0f\xaf\x75\x10\x56\x53\xe8\xdb\x3a\x00\x00\x8b\xd8\x59\x59\x85\xdb\x74\x15\x3b\xfe\x73\x11\x2b\xf7\x8d\x04\x3b\x56\x6a\x00\x50\xe8\xa2\xa2\xff\xff\x83\xc4\x0c\x5f\x8b\xc3\x5b\x5e\x5d\xc3\xff\x15\x50\x00\x01\x10\x85\xc0\xa3\x7c\x80\x01\x10\x0f\x95\xc0\xc3\x83\x25\x7c\x80\x01\x10\x00\xb0\x01\xc3\xff\x15\x4c\x00\x01\x10\xa3\x88\x80\x01\x10\xff\x15\x48\x00\x01\x10\xa3\x8c\x80\x01\x10\xb0\x01\xc3\xb0\x01\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x57\x8b\x7d\x08\x3b\x7d\x0c\x75\x04\xb0\x01\xeb\x57\x56\x8b\xf7\x53\x8b\x1e\x85\xdb\x74\x0e\x8b\xcb\xff\x15\x64\x01\x01\x10\xff\xd3\x84\xc0\x74\x08\x83\xc6\x08\x3b\x75\x0c\x75\xe4\x3b\x75\x0c\x75\x04\xb0\x01\xeb\x2c\x3b\xf7\x74\x26\x83\xc6\xfc\x83\x7e\xfc\x00\x74\x13\x8b\x1e\x85\xdb\x74\x0d\x6a\x00\x8b\xcb\xff\x15\x64\x01\x01\x10\xff\xd3\x59\x83\xee\x08\x8d\x46\x04\x3b\xc7\x75\xdd\x32\xc0\x5b\x5e\x8b\x4d\xfc\x33\xcd\x5f\xe8\x26\x92\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x8b\x75\x0c\x39\x75\x08\x74\x23\x83\xc6\xfc\x57\x8b\x3e\x85\xff\x74\x0d\x6a\x00\x8b\xcf\xff\x15\x64\x01\x01\x10\xff\xd7\x59\x83\xee\x08\x8d\x46\x04\x3b\x45\x08\x75\xe2\x5f\x8b\x4d\xfc\xb0\x01\x33\xcd\x5e\xe8\xd9\x91\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xff\x75\x08\xb9\x90\x80\x01\x10\xe8\x33\xd1\xff\xff\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\xe8\x2e\x00\x00\x00\x8b\xf0\x85\xf6\x74\x17\xff\x75\x08\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\x59\x85\xc0\x74\x05\x33\xc0\x40\xeb\x02\x33\xc0\x8b\x4d\xfc\x33\xcd\x5e\xe8\x81\x91\xff\xff\x8b\xe5\x5d\xc3\x6a\x0c\x68\x08\x5d\x01\x10\xe8\x5d\x9b\xff\xff\x83\x65\xe4\x00\x6a\x00\xe8\x6e\xf5\xff\xff\x59\x83\x65\xfc\x00\x8b\x35\x04\x70\x01\x10\x8b\xce\x83\xe1\x1f\x33\x35\x90\x80\x01\x10\xd3\xce\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0b\x00\x00\x00\x8b\xc6\xe8\x6a\x9b\xff\xff\xc3\x8b\x75\xe4\x6a\x00\xe8\x7d\xf5\xff\xff\x59\xc3\x6a\x0c\x68\x48\x5d\x01\x10\xe8\x0b\x9b\xff\xff\x83\x65\xe4\x00\x8b\x45\x08\xff\x30\xe8\x19\xf5\xff\xff\x59\x83\x65\xfc\x00\x8b\x35\x04\x70\x01\x10\x8b\xce\x83\xe1\x1f\x33\x35\x9c\x80\x01\x10\xd3\xce\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0d\x00\x00\x00\x8b\xc6\xe8\x15\x9b\xff\xff\xc2\x0c\x00\x8b\x75\xe4\x8b\x4d\x10\xff\x31\xe8\x23\xf5\xff\xff\x59\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x82\xff\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x48\x83\xe8\x01\x74\x2d\x83\xe8\x04\x74\x13\x83\xe8\x09\x74\x1c\x83\xe8\x06\x74\x10\x83\xe8\x01\x74\x04\x33\xc0\x5d\xc3\xb8\x9c\x80\x01\x10\x5d\xc3\xb8\x98\x80\x01\x10\x5d\xc3\xb8\xa0\x80\x01\x10\x5d\xc3\xb8\x94\x80\x01\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x6b\x0d\xb8\x0b\x01\x10\x0c\x8b\x45\x0c\x03\xc8\x3b\xc1\x74\x0f\x8b\x55\x08\x39\x50\x04\x74\x09\x83\xc0\x0c\x3b\xc1\x75\xf4\x33\xc0\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x8d\x45\xff\x50\x6a\x03\xe8\x5d\xff\xff\xff\x59\x59\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xff\x75\x08\xb9\x94\x80\x01\x10\xe8\x86\xcf\xff\xff\xff\x75\x08\xb9\x98\x80\x01\x10\xe8\x79\xcf\xff\xff\xff\x75\x08\xb9\x9c\x80\x01\x10\xe8\x6c\xcf\xff\xff\xff\x75\x08\xb9\xa0\x80\x01\x10\xe8\x5f\xcf\xff\xff\x5d\xc3\xe8\x42\xe6\xff\xff\x83\xc0\x08\xc3\x6a\x2c\x68\x28\x5d\x01\x10\xe8\x64\x5f\x00\x00\x33\xdb\x89\x5d\xd4\x21\x5d\xcc\xb1\x01\x88\x4d\xe3\x8b\x75\x08\x6a\x08\x5f\x3b\xf7\x7f\x18\x74\x35\x8d\x46\xff\x83\xe8\x01\x74\x22\x48\x83\xe8\x01\x74\x27\x48\x83\xe8\x01\x75\x4c\xeb\x14\x83\xfe\x0b\x74\x1a\x83\xfe\x0f\x74\x0a\x83\xfe\x14\x7e\x3b\x83\xfe\x16\x7f\x36\x56\xe8\xe6\xfe\xff\xff\x83\xc4\x04\xeb\x45\xe8\x63\xe6\xff\xff\x8b\xd8\x89\x5d\xd4\x85\xdb\x75\x08\x83\xc8\xff\xe9\x92\x01\x00\x00\xff\x33\x56\xe8\x05\xff\xff\xff\x59\x59\x33\xc9\x85\xc0\x0f\x95\xc1\x85\xc9\x75\x12\xe8\x81\xd1\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\xba\xd0\xff\xff\xeb\xd1\x83\xc0\x08\x32\xc9\x88\x4d\xe3\x89\x45\xd8\x83\x65\xd0\x00\x84\xc9\x74\x0b\x6a\x03\xe8\x3b\xf3\xff\xff\x59\x8a\x4d\xe3\x83\x65\xdc\x00\xc6\x45\xe2\x00\x83\x65\xfc\x00\x8b\x45\xd8\x84\xc9\x74\x14\x8b\x15\x04\x70\x01\x10\x8b\xca\x83\xe1\x1f\x33\x10\xd3\xca\x8a\x4d\xe3\xeb\x02\x8b\x10\x8b\xc2\x89\x45\xdc\x33\xd2\x83\xf8\x01\x0f\x94\xc2\x89\x55\xc8\x88\x55\xe2\x84\xd2\x0f\x85\x8a\x00\x00\x00\x85\xc0\x75\x13\x84\xc9\x74\x08\x6a\x03\xe8\x2c\xf3\xff\xff\x59\x6a\x03\xe8\x24\xc2\xff\xff\x3b\xf7\x74\x0a\x83\xfe\x0b\x74\x05\x83\xfe\x04\x75\x23\x8b\x43\x04\x89\x45\xd0\x83\x63\x04\x00\x3b\xf7\x75\x3b\xe8\xc6\xfe\xff\xff\x8b\x00\x89\x45\xcc\xe8\xbc\xfe\xff\xff\xc7\x00\x8c\x00\x00\x00\x3b\xf7\x75\x22\x6b\x05\xbc\x0b\x01\x10\x0c\x03\x03\x6b\x0d\xc0\x0b\x01\x10\x0c\x03\xc8\x89\x45\xc4\x3b\xc1\x74\x25\x83\x60\x08\x00\x83\xc0\x0c\xeb\xf0\xa1\x04\x70\x01\x10\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\x33\xc0\xd3\xc8\x33\x05\x04\x70\x01\x10\x8b\x4d\xd8\x89\x01\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x31\x00\x00\x00\x80\x7d\xc8\x00\x75\x6b\x3b\xf7\x75\x36\xe8\xa0\xe4\xff\xff\xff\x70\x08\x57\x8b\x4d\xdc\xff\x15\x64\x01\x01\x10\xff\x55\xdc\x59\xeb\x2b\x6a\x08\x5f\x8b\x75\x08\x8b\x5d\xd4\x8a\x45\xe2\x89\x45\xc8\x80\x7d\xe3\x00\x74\x08\x6a\x03\xe8\x67\xf2\xff\xff\x59\xc3\x56\x8b\x4d\xdc\xff\x15\x64\x01\x01\x10\xff\x55\xdc\x59\x3b\xf7\x74\x0a\x83\xfe\x0b\x74\x05\x83\xfe\x04\x75\x15\x8b\x45\xd0\x89\x43\x04\x3b\xf7\x75\x0b\xe8\x44\xe4\xff\xff\x8b\x4d\xcc\x89\x48\x08\x33\xc0\xe8\xb2\x5d\x00\x00\xc3\xa1\x04\x70\x01\x10\x8b\xc8\x33\x05\xa4\x80\x01\x10\x83\xe1\x1f\xd3\xc8\xf7\xd8\x1b\xc0\xf7\xd8\xc3\x8b\xff\x55\x8b\xec\xff\x75\x08\xb9\xa4\x80\x01\x10\xe8\x21\xcd\xff\xff\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x8b\x35\x04\x70\x01\x10\x8b\xce\x33\x35\xa4\x80\x01\x10\x83\xe1\x1f\xd3\xce\x85\xf6\x75\x04\x33\xc0\xeb\x0e\xff\x75\x08\x8b\xce\xff\x15\x64\x01\x01\x10\xff\xd6\x59\x8b\x4d\xfc\x33\xcd\x5e\xe8\x6a\x8d\xff\xff\x8b\xe5\x5d\xc3\xa1\xa8\x80\x01\x10\xc3\x8b\xff\x55\x8b\xec\x51\xe8\xaf\xe3\xff\xff\x8b\x48\x4c\x89\x4d\xfc\x8d\x4d\xfc\x51\x50\xe8\xee\xe4\xff\xff\x8b\x45\xfc\x59\x59\x8b\x00\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x24\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x53\xff\x75\x10\x8b\x5d\x08\x8d\x4d\xe0\xe8\xde\xaa\xff\xff\x8d\x43\x01\x3d\x00\x01\x00\x00\x77\x0b\x8b\x45\xe4\x8b\x00\x0f\xb7\x04\x58\xeb\x7a\x8b\xc3\x8d\x4d\xe4\xc1\xf8\x08\x89\x45\xdc\x51\x0f\xb6\xc0\x50\xe8\xa3\x0e\x00\x00\x59\x59\x85\xc0\x74\x13\x8b\x45\xdc\x88\x45\xf0\x33\xc0\x6a\x02\x88\x5d\xf1\x88\x45\xf2\x59\xeb\x0b\x33\xc0\x88\x5d\xf0\x33\xc9\x88\x45\xf1\x41\x89\x45\xf4\x66\x89\x45\xf8\x8b\x45\xe4\x6a\x01\xff\x70\x08\x8d\x45\xf4\x50\x51\x8d\x45\xf0\x50\x8d\x45\xe4\x6a\x01\x50\xe8\x24\x33\x00\x00\x83\xc4\x1c\x85\xc0\x75\x13\x38\x45\xec\x74\x0a\x8b\x45\xe0\x83\xa0\x50\x03\x00\x00\xfd\x33\xc0\xeb\x17\x0f\xb7\x45\xf4\x23\x45\x0c\x80\x7d\xec\x00\x74\x0a\x8b\x4d\xe0\x83\xa1\x50\x03\x00\x00\xfd\x8b\x4d\xfc\x33\xcd\x5b\xe8\x6c\x8c\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\x53\x56\x57\x33\xff\xbb\xe3\x00\x00\x00\x89\x7d\xf4\x89\x5d\xf8\x8d\x04\x3b\xc7\x45\xfc\x55\x00\x00\x00\x99\x2b\xc2\x8b\xc8\xd1\xf9\x6a\x41\x5f\x89\x4d\xf0\x8b\x34\xcd\x60\x2f\x01\x10\x8b\x4d\x08\x6a\x5a\x2b\xce\x5b\x0f\xb7\x04\x31\x66\x3b\xc7\x72\x0d\x66\x3b\xc3\x77\x08\x83\xc0\x20\x0f\xb7\xd0\xeb\x02\x8b\xd0\x0f\xb7\x06\x66\x3b\xc7\x72\x0b\x66\x3b\xc3\x77\x06\x83\xc0\x20\x0f\xb7\xc0\x83\xc6\x02\x83\x6d\xfc\x01\x74\x0a\x66\x85\xd2\x74\x05\x66\x3b\xd0\x74\xc2\x8b\x4d\xf0\x8b\x7d\xf4\x8b\x5d\xf8\x0f\xb7\xc0\x0f\xb7\xd2\x2b\xd0\x74\x1f\x85\xd2\x79\x08\x8d\x59\xff\x89\x5d\xf8\xeb\x06\x8d\x79\x01\x89\x7d\xf4\x3b\xfb\x0f\x8e\x6f\xff\xff\xff\x83\xc8\xff\xeb\x07\x8b\x04\xcd\x64\x2f\x01\x10\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\x7d\x08\x00\x74\x1d\xff\x75\x08\xe8\x31\xff\xff\xff\x59\x85\xc0\x78\x10\x3d\xe4\x00\x00\x00\x73\x09\x8b\x04\xc5\x38\x1e\x01\x10\x5d\xc3\x33\xc0\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x75\x15\xe8\x95\xcd\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\xce\xcc\xff\xff\x83\xc8\xff\xeb\x51\x8b\x46\x0c\x57\x83\xcf\xff\xc1\xe8\x0d\xa8\x01\x74\x39\x56\xe8\xbf\xd2\xff\xff\x56\x8b\xf8\xe8\x45\xd4\xff\xff\x56\xe8\x54\xed\xff\xff\x50\xe8\x24\x34\x00\x00\x83\xc4\x10\x85\xc0\x79\x05\x83\xcf\xff\xeb\x13\x83\x7e\x1c\x00\x74\x0d\xff\x76\x1c\xe8\x0f\xc6\xff\xff\x83\x66\x1c\x00\x59\x56\xe8\x1a\x35\x00\x00\x59\x8b\xc7\x5f\x5e\x5d\xc3\x6a\x10\x68\x68\x5d\x01\x10\xe8\xea\x94\xff\xff\x8b\x75\x08\x89\x75\xe0\x33\xc0\x85\xf6\x0f\x95\xc0\x85\xc0\x75\x15\xe8\x0f\xcd\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x48\xcc\xff\xff\x83\xc8\xff\xeb\x3b\x8b\x46\x0c\xc1\xe8\x0c\x56\xa8\x01\x74\x08\xe8\xd1\x34\x00\x00\x59\xeb\xe8\x83\x65\xe4\x00\xe8\x03\xa5\xff\xff\x59\x83\x65\xfc\x00\x56\xe8\x31\xff\xff\xff\x59\x8b\xf0\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0b\x00\x00\x00\x8b\xc6\xe8\xca\x94\xff\xff\xc3\x8b\x75\xe4\xff\x75\xe0\xe8\xe7\xa4\xff\xff\x59\xc3\x6a\x0c\x68\x88\x5d\x01\x10\xe8\x6a\x94\xff\xff\x33\xf6\x89\x75\xe4\x8b\x45\x08\xff\x30\xe8\xe2\x0a\x00\x00\x59\x89\x75\xfc\x8b\x45\x0c\x8b\x00\x8b\x38\x8b\xd7\xc1\xfa\x06\x8b\xc7\x83\xe0\x3f\x6b\xc8\x30\x8b\x04\x95\x08\x7d\x01\x10\xf6\x44\x08\x28\x01\x74\x21\x57\xe8\x8d\x0b\x00\x00\x59\x50\xff\x15\x40\x00\x01\x10\x85\xc0\x75\x1d\xe8\x46\xcc\xff\xff\x8b\xf0\xff\x15\xfc\x00\x01\x10\x89\x06\xe8\x4a\xcc\xff\xff\xc7\x00\x09\x00\x00\x00\x83\xce\xff\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0d\x00\x00\x00\x8b\xc6\xe8\x36\x94\xff\xff\xc2\x0c\x00\x8b\x75\xe4\x8b\x4d\x10\xff\x31\xe8\x8a\x0a\x00\x00\x59\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x44\xff\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x56\x8b\x75\x08\x83\xfe\xfe\x75\x0d\xe8\xdd\xcb\xff\xff\xc7\x00\x09\x00\x00\x00\xeb\x4b\x85\xf6\x78\x37\x3b\x35\x08\x7f\x01\x10\x73\x2f\x8b\xc6\x8b\xd6\x83\xe0\x3f\xc1\xfa\x06\x6b\xc8\x30\x8b\x04\x95\x08\x7d\x01\x10\xf6\x44\x08\x28\x01\x74\x14\x8d\x45\x08\x89\x45\xfc\x8d\x45\xfc\x50\x56\xe8\x85\xff\xff\xff\x59\x59\xeb\x13\xe8\x95\xcb\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\xce\xca\xff\xff\x83\xc8\xff\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x38\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x45\x0c\x8b\xc8\x83\xe0\x3f\xc1\xf9\x06\x53\x6b\xd8\x30\x56\x8b\x04\x8d\x08\x7d\x01\x10\x57\x8b\x7d\x10\x89\x7d\xd0\x89\x4d\xd4\x8b\x44\x18\x18\x89\x45\xd8\x8b\x45\x14\x03\xc7\x89\x45\xdc\xff\x15\x38\x00\x01\x10\x8b\x75\x08\x8b\x4d\xdc\x89\x45\xc8\x33\xc0\x89\x06\x89\x46\x04\x89\x46\x08\x3b\xf9\x0f\x83\x3d\x01\x00\x00\x8a\x2f\x33\xc0\x66\x89\x45\xe8\x8b\x45\xd4\x88\x6d\xe5\x8b\x14\x85\x08\x7d\x01\x10\x8a\x4c\x1a\x2d\xf6\xc1\x04\x74\x19\x8a\x44\x1a\x2e\x80\xe1\xfb\x88\x45\xf4\x8d\x45\xf4\x6a\x02\x88\x6d\xf5\x88\x4c\x1a\x2d\x50\xeb\x3a\xe8\x5c\xfb\xff\xff\x0f\xb6\x0f\xba\x00\x80\x00\x00\x66\x85\x14\x48\x74\x24\x3b\x7d\xdc\x0f\x83\xc1\x00\x00\x00\x6a\x02\x8d\x45\xe8\x57\x50\xe8\x1f\xd7\xff\xff\x83\xc4\x0c\x83\xf8\xff\x0f\x84\xd2\x00\x00\x00\x47\xeb\x18\x6a\x01\x57\x8d\x45\xe8\x50\xe8\x04\xd7\xff\xff\x83\xc4\x0c\x83\xf8\xff\x0f\x84\xb7\x00\x00\x00\x33\xc9\x8d\x45\xec\x51\x51\x6a\x05\x50\x6a\x01\x8d\x45\xe8\x47\x50\x51\xff\x75\xc8\xff\x15\xcc\x00\x01\x10\x89\x45\xcc\x85\xc0\x0f\x84\x91\x00\x00\x00\x6a\x00\x8d\x4d\xe0\x51\x50\x8d\x45\xec\x50\xff\x75\xd8\xff\x15\x3c\x00\x01\x10\x85\xc0\x74\x71\x8b\x46\x08\x2b\x45\xd0\x03\xc7\x89\x46\x04\x8b\x45\xcc\x39\x45\xe0\x72\x66\x80\x7d\xe5\x0a\x75\x2c\x6a\x0d\x58\x6a\x00\x66\x89\x45\xe4\x8d\x45\xe0\x50\x6a\x01\x8d\x45\xe4\x50\xff\x75\xd8\xff\x15\x3c\x00\x01\x10\x85\xc0\x74\x38\x83\x7d\xe0\x01\x72\x3a\xff\x46\x08\xff\x46\x04\x3b\x7d\xdc\x0f\x82\xee\xfe\xff\xff\xeb\x29\x8b\x55\xd4\x8a\x07\x8b\x0c\x95\x08\x7d\x01\x10\x88\x44\x19\x2e\x8b\x04\x95\x08\x7d\x01\x10\x80\x4c\x18\x2d\x04\xff\x46\x04\xeb\x08\xff\x15\xfc\x00\x01\x10\x89\x06\x8b\x4d\xfc\x8b\xc6\x5f\x5e\x33\xcd\x5b\xe8\xac\x87\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x53\x56\x8b\x75\x08\x33\xc0\x57\x8b\x7d\x0c\x89\x06\x89\x46\x04\x89\x46\x08\x8b\x45\x10\x03\xc7\x89\x45\xfc\x3b\xf8\x73\x3f\x0f\xb7\x1f\x53\xe8\x77\x33\x00\x00\x59\x66\x3b\xc3\x75\x28\x83\x46\x04\x02\x83\xfb\x0a\x75\x15\x6a\x0d\x5b\x53\xe8\x5f\x33\x00\x00\x59\x66\x3b\xc3\x75\x10\xff\x46\x04\xff\x46\x08\x83\xc7\x02\x3b\x7d\xfc\x72\xcb\xeb\x08\xff\x15\xfc\x00\x01\x10\x89\x06\x5f\x8b\xc6\x5e\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x56\x8b\x75\x08\x56\xe8\xca\x2a\x00\x00\x59\x85\xc0\x75\x04\x32\xc0\xeb\x58\x57\x8b\xfe\x83\xe6\x3f\xc1\xff\x06\x6b\xf6\x30\x8b\x04\xbd\x08\x7d\x01\x10\xf6\x44\x30\x28\x80\x74\x1f\xe8\x5d\xdd\xff\xff\x8b\x40\x4c\x83\xb8\xa8\x00\x00\x00\x00\x75\x12\x8b\x04\xbd\x08\x7d\x01\x10\x80\x7c\x30\x29\x00\x75\x04\x32\xc0\xeb\x1a\x8d\x45\xfc\x50\x8b\x04\xbd\x08\x7d\x01\x10\xff\x74\x30\x18\xff\x15\x34\x00\x01\x10\x85\xc0\x0f\x95\xc0\x5f\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xb8\x10\x14\x00\x00\xe8\xe2\x57\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x4d\x0c\x8b\xc1\xc1\xf8\x06\x83\xe1\x3f\x6b\xc9\x30\x53\x8b\x5d\x10\x8b\x04\x85\x08\x7d\x01\x10\x56\x8b\x75\x08\x57\x8b\x4c\x08\x18\x8b\x45\x14\x83\x26\x00\x03\xc3\x83\x66\x04\x00\x83\x66\x08\x00\x89\x8d\xf0\xeb\xff\xff\x89\x85\xf8\xeb\xff\xff\xeb\x65\x8d\xbd\xfc\xeb\xff\xff\x3b\xd8\x73\x1e\x8a\x03\x43\x3c\x0a\x75\x07\xff\x46\x08\xc6\x07\x0d\x47\x88\x07\x8d\x45\xfb\x47\x3b\xf8\x8b\x85\xf8\xeb\xff\xff\x72\xde\x8d\x85\xfc\xeb\xff\xff\x2b\xf8\x8d\x85\xf4\xeb\xff\xff\x6a\x00\x50\x57\x8d\x85\xfc\xeb\xff\xff\x50\x51\xff\x15\x3c\x00\x01\x10\x85\xc0\x74\x1f\x8b\x85\xf4\xeb\xff\xff\x01\x46\x04\x3b\xc7\x72\x1a\x8b\x85\xf8\xeb\xff\xff\x8b\x8d\xf0\xeb\xff\xff\x3b\xd8\x72\x97\xeb\x08\xff\x15\xfc\x00\x01\x10\x89\x06\x8b\x4d\xfc\x8b\xc6\x5f\x5e\x33\xcd\x5b\xe8\xea\x85\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xb8\x10\x14\x00\x00\xe8\x03\x57\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x4d\x0c\x8b\xc1\xc1\xf8\x06\x83\xe1\x3f\x6b\xc9\x30\x53\x8b\x5d\x10\x8b\x04\x85\x08\x7d\x01\x10\x56\x8b\x75\x08\x57\x8b\x4c\x08\x18\x8b\x45\x14\x03\xc3\x89\x8d\xf0\xeb\xff\xff\x33\xd2\x89\x85\xf8\xeb\xff\xff\x89\x16\x89\x56\x04\x89\x56\x08\xeb\x75\x8d\xbd\xfc\xeb\xff\xff\x3b\xd8\x73\x2b\x0f\xb7\x03\x83\xc3\x02\x83\xf8\x0a\x75\x0d\x83\x46\x08\x02\x6a\x0d\x5a\x66\x89\x17\x83\xc7\x02\x66\x89\x07\x8d\x45\xfa\x83\xc7\x02\x3b\xf8\x8b\x85\xf8\xeb\xff\xff\x72\xd1\x8d\x85\xfc\xeb\xff\xff\x2b\xf8\x8d\x85\xf4\xeb\xff\xff\x6a\x00\x50\x83\xe7\xfe\x8d\x85\xfc\xeb\xff\xff\x57\x50\x51\xff\x15\x3c\x00\x01\x10\x85\xc0\x74\x1f\x8b\x85\xf4\xeb\xff\xff\x01\x46\x04\x3b\xc7\x72\x1a\x8b\x85\xf8\xeb\xff\xff\x8b\x8d\xf0\xeb\xff\xff\x3b\xd8\x72\x87\xeb\x08\xff\x15\xfc\x00\x01\x10\x89\x06\x8b\x4d\xfc\x8b\xc6\x5f\x5e\x33\xcd\x5b\xe8\xfc\x84\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xb8\x18\x14\x00\x00\xe8\x15\x56\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x4d\x0c\x8b\xc1\xc1\xf8\x06\x83\xe1\x3f\x6b\xc9\x30\x53\x56\x8b\x04\x85\x08\x7d\x01\x10\x33\xdb\x8b\x75\x08\x57\x8b\x44\x08\x18\x8b\x4d\x10\x8b\xf9\x89\x85\xec\xeb\xff\xff\x8b\x45\x14\x03\xc1\x89\x1e\x89\x5e\x04\x89\x85\xf4\xeb\xff\xff\x89\x5e\x08\x3b\xc8\x0f\x83\xba\x00\x00\x00\x8b\xb5\xf4\xeb\xff\xff\x8d\x85\x50\xf9\xff\xff\x3b\xfe\x73\x21\x0f\xb7\x0f\x83\xc7\x02\x83\xf9\x0a\x75\x09\x6a\x0d\x5a\x66\x89\x10\x83\xc0\x02\x66\x89\x08\x83\xc0\x02\x8d\x4d\xf8\x3b\xc1\x72\xdb\x53\x53\x68\x55\x0d\x00\x00\x8d\x8d\xf8\xeb\xff\xff\x51\x8d\x8d\x50\xf9\xff\xff\x2b\xc1\xd1\xf8\x50\x8b\xc1\x50\x53\x68\xe9\xfd\x00\x00\xff\x15\xcc\x00\x01\x10\x8b\x75\x08\x89\x85\xe8\xeb\xff\xff\x85\xc0\x74\x4c\x6a\x00\x8d\x8d\xf0\xeb\xff\xff\x2b\xc3\x51\x50\x8d\x85\xf8\xeb\xff\xff\x03\xc3\x50\xff\xb5\xec\xeb\xff\xff\xff\x15\x3c\x00\x01\x10\x85\xc0\x74\x27\x03\x9d\xf0\xeb\xff\xff\x8b\x85\xe8\xeb\xff\xff\x3b\xd8\x72\xcb\x8b\xc7\x2b\x45\x10\x89\x46\x04\x3b\xbd\xf4\xeb\xff\xff\x73\x0f\x33\xdb\xe9\x4e\xff\xff\xff\xff\x15\xfc\x00\x01\x10\x89\x06\x8b\x4d\xfc\x8b\xc6\x5f\x5e\x33\xcd\x5b\xe8\xcf\x83\xff\xff\x8b\xe5\x5d\xc3\x6a\x14\x68\xa8\x5d\x01\x10\xe8\xab\x8d\xff\xff\x8b\x75\x08\x83\xfe\xfe\x75\x18\xe8\xc6\xc5\xff\xff\x83\x20\x00\xe8\xd1\xc5\xff\xff\xc7\x00\x09\x00\x00\x00\xe9\xb6\x00\x00\x00\x85\xf6\x0f\x88\x96\x00\x00\x00\x3b\x35\x08\x7f\x01\x10\x0f\x83\x8a\x00\x00\x00\x8b\xde\xc1\xfb\x06\x8b\xc6\x83\xe0\x3f\x6b\xc8\x30\x89\x4d\xe0\x8b\x04\x9d\x08\x7d\x01\x10\x0f\xb6\x44\x08\x28\x83\xe0\x01\x74\x69\x56\xe8\xd7\x03\x00\x00\x59\x83\xcf\xff\x89\x7d\xe4\x83\x65\xfc\x00\x8b\x04\x9d\x08\x7d\x01\x10\x8b\x4d\xe0\xf6\x44\x08\x28\x01\x75\x15\xe8\x6a\xc5\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x4c\xc5\xff\xff\x83\x20\x00\xeb\x14\xff\x75\x10\xff\x75\x0c\x56\xe8\x47\x00\x00\x00\x83\xc4\x0c\x8b\xf8\x89\x7d\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0a\x00\x00\x00\x8b\xc7\xeb\x29\x8b\x75\x08\x8b\x7d\xe4\x56\xe8\x99\x03\x00\x00\x59\xc3\xe8\x10\xc5\xff\xff\x83\x20\x00\xe8\x1b\xc5\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x54\xc4\xff\xff\x83\xc8\xff\xe8\x13\x8d\xff\xff\xc3\x8b\xff\x55\x8b\xec\x83\xec\x30\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x4d\x10\x89\x4d\xf8\x56\x8b\x75\x08\x57\x8b\x7d\x0c\x89\x7d\xd0\x85\xc9\x75\x07\x33\xc0\xe9\xce\x01\x00\x00\x85\xff\x75\x1f\xe8\xbd\xc4\xff\xff\x21\x38\xe8\xc9\xc4\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x02\xc4\xff\xff\x83\xc8\xff\xe9\xab\x01\x00\x00\x53\x8b\xc6\x8b\xde\xc1\xfb\x06\x83\xe0\x3f\x6b\xd0\x30\x89\x5d\xe4\x8b\x04\x9d\x08\x7d\x01\x10\x89\x45\xd4\x89\x55\xe8\x8a\x5c\x10\x29\x80\xfb\x02\x74\x05\x80\xfb\x01\x75\x28\x8b\xc1\xf7\xd0\xa8\x01\x75\x1d\xe8\x6a\xc4\xff\xff\x83\x20\x00\xe8\x75\xc4\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\xae\xc3\xff\xff\xe9\x51\x01\x00\x00\x8b\x45\xd4\xf6\x44\x10\x28\x20\x74\x0f\x6a\x02\x6a\x00\x6a\x00\x56\xe8\x0a\x2e\x00\x00\x83\xc4\x10\x56\xe8\xe4\xfa\xff\xff\x59\x84\xc0\x74\x39\x84\xdb\x74\x22\xfe\xcb\x80\xfb\x01\x0f\x87\xee\x00\x00\x00\xff\x75\xf8\x8d\x45\xec\x57\x50\xe8\x56\xfa\xff\xff\x83\xc4\x0c\x8b\xf0\xe9\x9c\x00\x00\x00\xff\x75\xf8\x8d\x45\xec\x57\x56\x50\xe8\x8b\xf8\xff\xff\x83\xc4\x10\xeb\xe6\x8b\x45\xe4\x8b\x0c\x85\x08\x7d\x01\x10\x8b\x45\xe8\xf6\x44\x01\x28\x80\x74\x46\x0f\xbe\xc3\x83\xe8\x00\x74\x2e\x83\xe8\x01\x74\x19\x83\xe8\x01\x0f\x85\x9a\x00\x00\x00\xff\x75\xf8\x8d\x45\xec\x57\x56\x50\xe8\xc3\xfb\xff\xff\xeb\xc1\xff\x75\xf8\x8d\x45\xec\x57\x56\x50\xe8\xa1\xfc\xff\xff\xeb\xb1\xff\x75\xf8\x8d\x45\xec\x57\x56\x50\xe8\xc4\xfa\xff\xff\xeb\xa1\x8b\x44\x01\x18\x33\xc9\x51\x89\x4d\xec\x89\x4d\xf0\x89\x4d\xf4\x8d\x4d\xf0\x51\xff\x75\xf8\x57\x50\xff\x15\x3c\x00\x01\x10\x85\xc0\x75\x09\xff\x15\xfc\x00\x01\x10\x89\x45\xec\x8d\x75\xec\x8d\x7d\xd8\xa5\xa5\xa5\x8b\x45\xdc\x85\xc0\x75\x63\x8b\x45\xd8\x85\xc0\x74\x24\x6a\x05\x5e\x3b\xc6\x75\x14\xe8\x5f\xc3\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x41\xc3\xff\xff\x89\x30\xeb\x3c\x50\xe8\x14\xc3\xff\xff\x59\xeb\x33\x8b\x7d\xd0\x8b\x45\xe4\x8b\x4d\xe8\x8b\x04\x85\x08\x7d\x01\x10\xf6\x44\x08\x28\x40\x74\x09\x80\x3f\x1a\x75\x04\x33\xc0\xeb\x1b\xe8\x22\xc3\xff\xff\xc7\x00\x1c\x00\x00\x00\xe8\x04\xc3\xff\xff\x83\x20\x00\x83\xc8\xff\xeb\x03\x2b\x45\xe0\x5b\x8b\x4d\xfc\x5f\x33\xcd\x5e\xe8\xd8\x80\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x53\x57\x6a\x30\x6a\x40\xe8\xda\xbc\xff\xff\x8b\xf8\x33\xdb\x89\x7d\xf8\x59\x59\x85\xff\x75\x04\x8b\xfb\xeb\x48\x8d\x87\x00\x0c\x00\x00\x3b\xf8\x74\x3e\x56\x8d\x77\x20\x8b\xf8\x53\x68\xa0\x0f\x00\x00\x8d\x46\xe0\x50\xe8\x3e\xc5\xff\xff\x83\x4e\xf8\xff\x89\x1e\x8d\x76\x30\x89\x5e\xd4\x8d\x46\xe0\xc7\x46\xd8\x00\x00\x0a\x0a\xc6\x46\xdc\x0a\x80\x66\xdd\xf8\x88\x5e\xde\x3b\xc7\x75\xcc\x8b\x7d\xf8\x5e\x53\xe8\x56\xbb\xff\xff\x59\x8b\xc7\x5f\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x74\x25\x53\x8d\x9e\x00\x0c\x00\x00\x57\x8b\xfe\x3b\xf3\x74\x0e\x57\xff\x15\xbc\x00\x01\x10\x83\xc7\x30\x3b\xfb\x75\xf2\x56\xe8\x1e\xbb\xff\xff\x59\x5f\x5b\x5e\x5d\xc3\x6a\x14\x68\xc8\x5d\x01\x10\xe8\x05\x8a\xff\xff\x81\x7d\x08\x00\x20\x00\x00\x1b\xc0\xf7\xd8\x75\x17\xe8\x2e\xc2\xff\xff\x6a\x09\x5e\x89\x30\xe8\x68\xc1\xff\xff\x8b\xc6\xe8\x28\x8a\xff\xff\xc3\x33\xf6\x89\x75\xe4\x6a\x07\xe8\xf1\xe3\xff\xff\x59\x89\x75\xfc\x8b\xfe\xa1\x08\x7f\x01\x10\x89\x7d\xe0\x39\x45\x08\x7c\x1f\x39\x34\xbd\x08\x7d\x01\x10\x75\x31\xe8\xf4\xfe\xff\xff\x89\x04\xbd\x08\x7d\x01\x10\x85\xc0\x75\x14\x6a\x0c\x5e\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x15\x00\x00\x00\xeb\xac\xa1\x08\x7f\x01\x10\x83\xc0\x40\xa3\x08\x7f\x01\x10\x47\xeb\xbb\x8b\x75\xe4\x6a\x07\xe8\xdf\xe3\xff\xff\x59\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x8b\xc8\x83\xe0\x3f\xc1\xf9\x06\x6b\xc0\x30\x03\x04\x8d\x08\x7d\x01\x10\x50\xff\x15\xb4\x00\x01\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x8b\xc8\x83\xe0\x3f\xc1\xf9\x06\x6b\xc0\x30\x03\x04\x8d\x08\x7d\x01\x10\x50\xff\x15\xb8\x00\x01\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x53\x56\x8b\x75\x08\x57\x85\xf6\x78\x67\x3b\x35\x08\x7f\x01\x10\x73\x5f\x8b\xc6\x8b\xfe\x83\xe0\x3f\xc1\xff\x06\x6b\xd8\x30\x8b\x04\xbd\x08\x7d\x01\x10\xf6\x44\x03\x28\x01\x74\x44\x83\x7c\x03\x18\xff\x74\x3d\xe8\x4b\x2b\x00\x00\x83\xf8\x01\x75\x23\x33\xc0\x2b\xf0\x74\x14\x83\xee\x01\x74\x0a\x83\xee\x01\x75\x13\x50\x6a\xf4\xeb\x08\x50\x6a\xf5\xeb\x03\x50\x6a\xf6\xff\x15\x30\x00\x01\x10\x8b\x04\xbd\x08\x7d\x01\x10\x83\x4c\x03\x18\xff\x33\xc0\xeb\x16\xe8\xf3\xc0\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\xd5\xc0\xff\xff\x83\x20\x00\x83\xc8\xff\x5f\x5e\x5b\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x83\xf9\xfe\x75\x15\xe8\xb8\xc0\xff\xff\x83\x20\x00\xe8\xc3\xc0\xff\xff\xc7\x00\x09\x00\x00\x00\xeb\x43\x85\xc9\x78\x27\x3b\x0d\x08\x7f\x01\x10\x73\x1f\x8b\xc1\x83\xe1\x3f\xc1\xf8\x06\x6b\xc9\x30\x8b\x04\x85\x08\x7d\x01\x10\xf6\x44\x08\x28\x01\x74\x06\x8b\x44\x08\x18\x5d\xc3\xe8\x78\xc0\xff\xff\x83\x20\x00\xe8\x83\xc0\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\xbc\xbf\xff\xff\x83\xc8\xff\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\xff\x75\x0c\x8d\x4d\xf0\xe8\xfe\x9b\xff\xff\x8b\x45\xf4\x0f\xb6\x4d\x08\x8b\x00\x0f\xb7\x04\x48\x25\x00\x80\x00\x00\x80\x7d\xfc\x00\x74\x0a\x8b\x4d\xf0\x83\xa1\x50\x03\x00\x00\xfd\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x53\x56\x8b\x75\x18\x57\x85\xf6\x7e\x14\x56\xff\x75\x14\xe8\x37\x2a\x00\x00\x59\x3b\xc6\x59\x8d\x70\x01\x7c\x02\x8b\xf0\x8b\x7d\x24\x85\xff\x75\x0b\x8b\x45\x08\x8b\x00\x8b\x78\x08\x89\x7d\x24\x33\xc0\x39\x45\x28\x6a\x00\x6a\x00\x56\xff\x75\x14\x0f\x95\xc0\x8d\x04\xc5\x01\x00\x00\x00\x50\x57\xff\x15\xc8\x00\x01\x10\x89\x45\xf8\x85\xc0\x0f\x84\x8d\x01\x00\x00\x8d\x14\x00\x8d\x4a\x08\x3b\xd1\x1b\xc0\x85\xc1\x74\x52\x8d\x4a\x08\x3b\xd1\x1b\xc0\x23\xc1\x8d\x4a\x08\x3d\x00\x04\x00\x00\x77\x1d\x3b\xd1\x1b\xc0\x23\xc1\xe8\xd8\x4e\x00\x00\x8b\xdc\x85\xdb\x0f\x84\x4c\x01\x00\x00\xc7\x03\xcc\xcc\x00\x00\xeb\x1d\x3b\xd1\x1b\xc0\x23\xc1\x50\xe8\x8b\xb8\xff\xff\x8b\xd8\x59\x85\xdb\x0f\x84\x2d\x01\x00\x00\xc7\x03\xdd\xdd\x00\x00\x83\xc3\x08\xeb\x02\x33\xdb\x85\xdb\x0f\x84\x18\x01\x00\x00\xff\x75\xf8\x53\x56\xff\x75\x14\x6a\x01\x57\xff\x15\xc8\x00\x01\x10\x85\xc0\x0f\x84\xff\x00\x00\x00\x8b\x7d\xf8\x33\xc0\x50\x50\x50\x50\x50\x57\x53\xff\x75\x10\xff\x75\x0c\xe8\x1c\xc2\xff\xff\x8b\xf0\x85\xf6\x0f\x84\xde\x00\x00\x00\xf7\x45\x10\x00\x04\x00\x00\x74\x38\x8b\x45\x20\x85\xc0\x0f\x84\xcc\x00\x00\x00\x3b\xf0\x0f\x8f\xc2\x00\x00\x00\x33\xc9\x51\x51\x51\x50\xff\x75\x1c\x57\x53\xff\x75\x10\xff\x75\x0c\xe8\xe0\xc1\xff\xff\x8b\xf0\x85\xf6\x0f\x85\xa4\x00\x00\x00\xe9\x9d\x00\x00\x00\x8d\x14\x36\x8d\x4a\x08\x3b\xd1\x1b\xc0\x85\xc1\x74\x4a\x8d\x4a\x08\x3b\xd1\x1b\xc0\x23\xc1\x8d\x4a\x08\x3d\x00\x04\x00\x00\x77\x19\x3b\xd1\x1b\xc0\x23\xc1\xe8\xf3\x4d\x00\x00\x8b\xfc\x85\xff\x74\x64\xc7\x07\xcc\xcc\x00\x00\xeb\x19\x3b\xd1\x1b\xc0\x23\xc1\x50\xe8\xaa\xb7\xff\xff\x8b\xf8\x59\x85\xff\x74\x49\xc7\x07\xdd\xdd\x00\x00\x83\xc7\x08\xeb\x02\x33\xff\x85\xff\x74\x38\x6a\x00\x6a\x00\x6a\x00\x56\x57\xff\x75\xf8\x53\xff\x75\x10\xff\x75\x0c\xe8\x5c\xc1\xff\xff\x85\xc0\x74\x1d\x33\xc0\x50\x50\x39\x45\x20\x75\x3a\x50\x50\x56\x57\x50\xff\x75\x24\xff\x15\xcc\x00\x01\x10\x8b\xf0\x85\xf6\x75\x2e\x57\xe8\x7c\x00\x00\x00\x59\x33\xf6\x53\xe8\x73\x00\x00\x00\x59\x8b\xc6\x8d\x65\xec\x5f\x5e\x5b\x8b\x4d\xfc\x33\xcd\xe8\x0b\x7c\xff\xff\x8b\xe5\x5d\xc3\xff\x75\x20\xff\x75\x1c\xeb\xc0\x57\xe8\x4e\x00\x00\x00\x59\xeb\xd2\x8b\xff\x55\x8b\xec\x83\xec\x10\xff\x75\x08\x8d\x4d\xf0\xe8\xa8\x99\xff\xff\xff\x75\x28\x8d\x45\xf4\xff\x75\x24\xff\x75\x20\xff\x75\x1c\xff\x75\x18\xff\x75\x14\xff\x75\x10\xff\x75\x0c\x50\xe8\xaf\xfd\xff\xff\x83\xc4\x24\x80\x7d\xfc\x00\x74\x0a\x8b\x4d\xf0\x83\xa1\x50\x03\x00\x00\xfd\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x85\xc0\x74\x12\x83\xe8\x08\x81\x38\xdd\xdd\x00\x00\x75\x07\x50\xe8\x81\xb6\xff\xff\x59\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\xf0\xff\x40\x0c\x8b\x48\x7c\x85\xc9\x74\x03\xf0\xff\x01\x8b\x88\x84\x00\x00\x00\x85\xc9\x74\x03\xf0\xff\x01\x8b\x88\x80\x00\x00\x00\x85\xc9\x74\x03\xf0\xff\x01\x8b\x88\x8c\x00\x00\x00\x85\xc9\x74\x03\xf0\xff\x01\x56\x6a\x06\x8d\x48\x28\x5e\x81\x79\xf8\x30\x72\x01\x10\x74\x09\x8b\x11\x85\xd2\x74\x03\xf0\xff\x02\x83\x79\xf4\x00\x74\x0a\x8b\x51\xfc\x85\xd2\x74\x03\xf0\xff\x02\x83\xc1\x10\x83\xee\x01\x75\xd6\xff\xb0\x9c\x00\x00\x00\xe8\x4e\x01\x00\x00\x59\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x53\x56\x8b\x75\x08\x57\x8b\x86\x88\x00\x00\x00\x85\xc0\x74\x6c\x3d\x60\x77\x01\x10\x74\x65\x8b\x46\x7c\x85\xc0\x74\x5e\x83\x38\x00\x75\x59\x8b\x86\x84\x00\x00\x00\x85\xc0\x74\x18\x83\x38\x00\x75\x13\x50\xe8\xc3\xb5\xff\xff\xff\xb6\x88\x00\x00\x00\xe8\xba\x1e\x00\x00\x59\x59\x8b\x86\x80\x00\x00\x00\x85\xc0\x74\x18\x83\x38\x00\x75\x13\x50\xe8\xa1\xb5\xff\xff\xff\xb6\x88\x00\x00\x00\xe8\x96\x1f\x00\x00\x59\x59\xff\x76\x7c\xe8\x8c\xb5\xff\xff\xff\xb6\x88\x00\x00\x00\xe8\x81\xb5\xff\xff\x59\x59\x8b\x86\x8c\x00\x00\x00\x85\xc0\x74\x45\x83\x38\x00\x75\x40\x8b\x86\x90\x00\x00\x00\x2d\xfe\x00\x00\x00\x50\xe8\x5f\xb5\xff\xff\x8b\x86\x94\x00\x00\x00\xbf\x80\x00\x00\x00\x2b\xc7\x50\xe8\x4c\xb5\xff\xff\x8b\x86\x98\x00\x00\x00\x2b\xc7\x50\xe8\x3e\xb5\xff\xff\xff\xb6\x8c\x00\x00\x00\xe8\x33\xb5\xff\xff\x83\xc4\x10\xff\xb6\x9c\x00\x00\x00\xe8\x97\x00\x00\x00\x59\x6a\x06\x58\x8d\x9e\xa0\x00\x00\x00\x89\x45\xfc\x8d\x7e\x28\x81\x7f\xf8\x30\x72\x01\x10\x74\x1d\x8b\x07\x85\xc0\x74\x14\x83\x38\x00\x75\x0f\x50\xe8\xfb\xb4\xff\xff\xff\x33\xe8\xf4\xb4\xff\xff\x59\x59\x8b\x45\xfc\x83\x7f\xf4\x00\x74\x16\x8b\x47\xfc\x85\xc0\x74\x0c\x83\x38\x00\x75\x07\x50\xe8\xd7\xb4\xff\xff\x59\x8b\x45\xfc\x83\xc3\x04\x83\xc7\x10\x83\xe8\x01\x89\x45\xfc\x75\xb0\x56\xe8\xbf\xb4\xff\xff\x59\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x85\xc9\x74\x16\x81\xf9\x90\x16\x01\x10\x74\x0e\x33\xc0\x40\xf0\x0f\xc1\x81\xb0\x00\x00\x00\x40\x5d\xc3\xb8\xff\xff\xff\x7f\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x74\x20\x81\xfe\x90\x16\x01\x10\x74\x18\x8b\x86\xb0\x00\x00\x00\x85\xc0\x75\x0e\x56\xe8\x0e\x1f\x00\x00\x56\xe8\x63\xb4\xff\xff\x59\x59\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x85\xc9\x74\x16\x81\xf9\x90\x16\x01\x10\x74\x0e\x83\xc8\xff\xf0\x0f\xc1\x81\xb0\x00\x00\x00\x48\x5d\xc3\xb8\xff\xff\xff\x7f\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x85\xc0\x74\x73\xf0\xff\x48\x0c\x8b\x48\x7c\x85\xc9\x74\x03\xf0\xff\x09\x8b\x88\x84\x00\x00\x00\x85\xc9\x74\x03\xf0\xff\x09\x8b\x88\x80\x00\x00\x00\x85\xc9\x74\x03\xf0\xff\x09\x8b\x88\x8c\x00\x00\x00\x85\xc9\x74\x03\xf0\xff\x09\x56\x6a\x06\x8d\x48\x28\x5e\x81\x79\xf8\x30\x72\x01\x10\x74\x09\x8b\x11\x85\xd2\x74\x03\xf0\xff\x0a\x83\x79\xf4\x00\x74\x0a\x8b\x51\xfc\x85\xd2\x74\x03\xf0\xff\x0a\x83\xc1\x10\x83\xee\x01\x75\xd6\xff\xb0\x9c\x00\x00\x00\xe8\x5a\xff\xff\xff\x59\x5e\x5d\xc3\x6a\x0c\x68\xe8\x5d\x01\x10\xe8\xa1\x82\xff\xff\x83\x65\xe4\x00\xe8\x06\xcf\xff\xff\x8b\xf8\x8b\x0d\x54\x77\x01\x10\x85\x8f\x50\x03\x00\x00\x74\x07\x8b\x77\x4c\x85\xf6\x75\x43\x6a\x04\xe8\x96\xdc\xff\xff\x59\x83\x65\xfc\x00\xff\x35\x1c\x7f\x01\x10\x8d\x47\x4c\x50\xe8\x30\x00\x00\x00\x59\x59\x8b\xf0\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0c\x00\x00\x00\x85\xf6\x75\x11\xe8\x33\xb4\xff\xff\x8b\x75\xe4\x6a\x04\xe8\xa4\xdc\xff\xff\x59\xc3\x8b\xc6\xe8\x7d\x82\xff\xff\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x0c\x57\x85\xf6\x74\x3c\x8b\x45\x08\x85\xc0\x74\x35\x8b\x38\x3b\xfe\x75\x04\x8b\xc6\xeb\x2d\x56\x89\x30\xe8\x98\xfc\xff\xff\x59\x85\xff\x74\xef\x57\xe8\xd6\xfe\xff\xff\x83\x7f\x0c\x00\x59\x75\xe2\x81\xff\x70\x71\x01\x10\x74\xda\x57\xe8\xf5\xfc\xff\xff\x59\xeb\xd1\x33\xc0\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x56\x85\xd2\x75\x16\xe8\x0f\xba\xff\xff\x6a\x16\x5e\x89\x30\xe8\x49\xb9\xff\xff\x8b\xc6\xe9\x96\x00\x00\x00\x83\x7d\x0c\x00\x76\xe4\x8b\x4d\x10\xc6\x02\x00\x85\xc9\x7e\x04\x8b\xc1\xeb\x02\x33\xc0\x40\x39\x45\x0c\x77\x09\xe8\xdd\xb9\xff\xff\x6a\x22\xeb\xcc\x8b\x75\x14\x85\xf6\x74\xbe\x53\x8d\x5a\x01\x8b\xc3\x57\x8b\x7e\x08\xc6\x02\x30\x85\xc9\x7e\x16\x8a\x1f\x84\xdb\x74\x03\x47\xeb\x02\xb3\x30\x88\x18\x40\x49\x85\xc9\x7f\xed\x8d\x5a\x01\xc6\x00\x00\x85\xc9\x78\x12\x80\x3f\x35\x7c\x0d\xeb\x03\xc6\x00\x30\x48\x80\x38\x39\x74\xf7\xfe\x00\x80\x3a\x31\x75\x05\xff\x46\x04\xeb\x1c\x8b\xcb\x8d\x71\x01\x8a\x01\x41\x84\xc0\x75\xf9\x2b\xce\x8d\x41\x01\x50\x53\x52\xe8\x34\x4f\x00\x00\x83\xc4\x0c\x5f\x33\xc0\x5b\x5e\x5d\xc3\x8b\xff\x56\x8b\xf1\x56\xe8\x97\x23\x00\x00\x8b\x06\x83\xe0\x1f\x59\x3c\x1f\x75\x06\xc6\x46\x08\x00\xeb\x0b\x56\xe8\xe7\x23\x00\x00\x59\xc6\x46\x08\x01\x8b\xc6\x5e\xc3\x8b\xff\x55\x8b\xec\x81\xec\x1c\x02\x00\x00\x53\x8b\x5d\x08\x8b\x03\x85\xc0\x75\x07\x33\xd2\x5b\x8b\xe5\x5d\xc3\x57\x8b\x7d\x0c\x8b\x0f\x85\xc9\x75\x0a\x5f\x33\xc0\x33\xd2\x5b\x8b\xe5\x5d\xc3\x56\x8d\x70\xff\x8d\x41\xff\x89\x75\xf4\x85\xc0\x0f\x85\x2d\x01\x00\x00\x8b\x4f\x04\x89\x4d\xd8\x83\xf9\x01\x75\x2f\x8b\x73\x04\x8d\x4b\x04\x50\x89\x85\xe4\xfd\xff\xff\x89\x03\x8d\x85\xe8\xfd\xff\xff\x50\x68\xcc\x01\x00\x00\x51\xe8\xdc\x17\x00\x00\x83\xc4\x10\x8b\xc6\x33\xd2\x5e\x5f\x5b\x8b\xe5\x5d\xc3\x85\xf6\x75\x49\x8b\x73\x04\x8d\x85\xe8\xfd\xff\xff\x6a\x00\x50\x8d\x7b\x04\xc7\x85\xe4\xfd\xff\xff\x00\x00\x00\x00\x68\xcc\x01\x00\x00\x57\xc7\x03\x00\x00\x00\x00\xe8\xa0\x17\x00\x00\x33\xd2\x8b\xc6\xf7\x75\xd8\x83\xc4\x10\x33\xc9\x3b\xca\x89\x17\x1b\xc9\x5e\xf7\xd9\x33\xd2\x5f\x89\x0b\x5b\x8b\xe5\x5d\xc3\x33\xff\xc7\x45\xf8\x00\x00\x00\x00\xc7\x45\xfc\x00\x00\x00\x00\x89\x7d\xf0\x83\xfe\xff\x74\x44\x8b\x45\xf4\x46\x40\x89\x45\xe4\x8d\x34\xb3\x8d\x64\x24\x00\x6a\x00\x51\x33\xc0\x0b\x06\x57\x50\xe8\x02\x45\x00\x00\x89\x55\xc0\x8d\x76\xfc\x33\xd2\x89\x5d\xf0\x8b\xf9\x03\xd0\x8b\x4d\xf8\x83\xd1\x00\x89\x55\xf8\x83\x6d\xe4\x01\x89\x4d\xfc\x8b\x4d\xd8\x75\xce\x8b\x5d\x08\x6a\x00\x8d\x85\xe8\xfd\xff\xff\xc7\x85\xe4\xfd\xff\xff\x00\x00\x00\x00\x50\x8d\x73\x04\xc7\x03\x00\x00\x00\x00\x68\xcc\x01\x00\x00\x56\xe8\xfe\x16\x00\x00\x8b\x45\xf0\x83\xc4\x10\x8b\x55\xfc\x33\xc9\x3b\xc8\x89\x3e\x89\x43\x08\x8b\x45\xf8\x1b\xc9\xf7\xd9\x5e\x41\x5f\x89\x0b\x5b\x8b\xe5\x5d\xc3\x3b\xc6\x77\x47\x8b\xd6\x8d\x48\x01\x2b\xd0\x89\x4d\xc8\x8b\xce\x3b\xf2\x7c\x32\x8b\xc1\x46\x2b\xc2\x8d\x34\xb3\x8d\x3c\x87\x83\xc7\x04\x8b\x07\x3b\x06\x75\x0d\x49\x83\xef\x04\x83\xee\x04\x3b\xca\x7d\xef\xeb\x11\x8b\x75\x0c\x8b\xc1\x2b\xc2\x8b\x44\x86\x04\x3b\x44\x8b\x04\x73\x01\x42\x85\xd2\x75\x0b\x5e\x5f\x33\xc0\x33\xd2\x5b\x8b\xe5\x5d\xc3\x8b\x7d\xc8\x8b\x45\x0c\x8b\x34\xb8\x8b\x44\xb8\xfc\x89\x45\xe0\x0f\xbd\xc6\x89\x75\xcc\x74\x09\xb9\x1f\x00\x00\x00\x2b\xc8\xeb\x05\xb9\x20\x00\x00\x00\xb8\x20\x00\x00\x00\x89\x4d\xdc\x2b\xc1\x89\x45\xc4\x85\xc9\x74\x29\x8b\x45\xe0\x8b\x4d\xc4\xd3\xe8\x8b\x4d\xdc\xd3\x65\xe0\xd3\xe6\x0b\xf0\x89\x75\xcc\x83\xff\x02\x76\x0f\x8b\x75\x0c\x8b\x4d\xc4\x8b\x44\xbe\xf8\xd3\xe8\x09\x45\xe0\x33\xf6\xc7\x45\xb8\x00\x00\x00\x00\x83\xc2\xff\x89\x55\xe4\x0f\x88\x2c\x02\x00\x00\x8d\x4b\x04\x8d\x0c\x91\x89\x4d\xf0\x8d\x04\x3a\x8d\x4b\xfc\x89\x45\xf8\x8d\x0c\x81\x89\x4d\xb4\x3b\x45\xf4\x77\x05\x8b\x41\x08\xeb\x02\x33\xc0\x83\x7d\xdc\x00\x8b\x51\x04\x8b\x09\x89\x45\xd0\xc7\x45\xd8\x00\x00\x00\x00\x89\x45\xfc\x89\x4d\xec\x76\x49\x8b\xf9\x8b\xc2\x8b\x4d\xc4\x33\xf6\x8b\x55\xfc\xd3\xef\x8b\x4d\xdc\xe8\x11\x46\x00\x00\x8b\x4d\xdc\x0b\xf2\x0b\xf8\x8b\xc6\x8b\x75\xec\x8b\xd7\xd3\xe6\x83\x7d\xf8\x03\x89\x45\xfc\x89\x75\xec\x72\x17\x8b\x45\xc8\x03\x45\xe4\x8b\x4d\xc4\x8b\x44\x83\xf8\xd3\xe8\x0b\xf0\x8b\x45\xfc\x89\x75\xec\x6a\x00\xff\x75\xcc\x50\x52\xe8\x32\x43\x00\x00\x89\x5d\xd8\x33\xf6\x8b\xd8\x89\x75\xd8\x8b\xc2\x89\x5d\xfc\x89\x45\xe8\x8b\xf9\x89\x5d\xbc\x89\x45\xc0\x85\xc0\x75\x05\x83\xfb\xff\x76\x2a\x6a\x00\xff\x75\xcc\x83\xc3\x01\x83\xd0\xff\x50\x53\xe8\xfd\x43\x00\x00\x03\xf8\x13\xf2\x83\xcb\xff\x33\xc0\x89\x75\xd8\x89\x5d\xfc\x89\x5d\xbc\x89\x45\xe8\x89\x45\xc0\x85\xf6\x77\x50\x72\x05\x83\xff\xff\x77\x49\x50\x53\x33\xc9\x8b\xf7\x0b\x4d\xec\x6a\x00\xff\x75\xe0\x89\x4d\xfc\xe8\xc4\x43\x00\x00\x3b\xd6\x72\x29\x77\x05\x3b\x45\xfc\x76\x22\x8b\x45\xe8\x83\xc3\xff\x89\x5d\xbc\x83\xd0\xff\x03\x7d\xcc\x89\x45\xe8\x83\x55\xd8\x00\x89\x45\xc0\x75\x0a\x83\xff\xff\x76\xbf\xeb\x03\x8b\x45\xe8\x89\x5d\xfc\x85\xc0\x75\x08\x85\xdb\x0f\x84\xb4\x00\x00\x00\x8b\x4d\xc8\x33\xff\x33\xf6\x85\xc9\x74\x55\x8b\x45\x0c\x8b\x5d\xf0\x83\xc0\x04\x89\x45\xec\x89\x4d\xf4\x8b\x00\x89\x45\xd8\x8b\x45\xc0\xf7\x65\xd8\x8b\xc8\x8b\x45\xbc\xf7\x65\xd8\x03\xd1\x03\xf8\x8b\x03\x8b\xcf\x13\xf2\x8b\xfe\x33\xf6\x3b\xc1\x73\x05\x83\xc7\x01\x13\xf6\x2b\xc1\x89\x03\x83\xc3\x04\x8b\x45\xec\x83\xc0\x04\x83\x6d\xf4\x01\x89\x45\xec\x75\xc0\x8b\x5d\xfc\x8b\x4d\xc8\x33\xc0\x3b\xc6\x77\x47\x72\x05\x39\x7d\xd0\x73\x40\x85\xc9\x74\x35\x8b\x75\x0c\x8b\xf9\x8b\x55\xf0\x83\xc6\x04\x8b\xd8\x8d\xa4\x24\x00\x00\x00\x00\x8b\x0a\x8d\x76\x04\x33\xc0\x8d\x52\x04\x03\x4e\xfc\x13\xc0\x03\xcb\x89\x4a\xfc\x83\xd0\x00\x8b\xd8\x83\xef\x01\x75\xe2\x8b\x5d\xfc\x83\xc3\xff\x83\x55\xe8\xff\x8b\x45\xf8\x48\x89\x45\xf4\x8b\x75\xb8\x33\xc0\x8b\x55\xe4\x03\xc3\x8b\x4d\xb4\x8b\xf8\x8b\x45\xf8\x83\xd6\x00\x83\x6d\xf0\x04\x4a\x8b\x5d\x08\x83\xe9\x04\x48\x89\x7d\xb8\x89\x55\xe4\x89\x4d\xb4\x89\x45\xf8\x85\xd2\x0f\x89\xee\xfd\xff\xff\xeb\x02\x33\xff\x8b\x55\xf4\x42\x8b\xc2\x3b\x03\x73\x1c\x8d\x48\x01\x8d\x0c\x8b\xeb\x06\x8d\x9b\x00\x00\x00\x00\xc7\x01\x00\x00\x00\x00\x8d\x49\x04\x40\x3b\x03\x72\xf2\x89\x13\x85\xd2\x74\x0f\x8b\x0b\x83\x3c\x8b\x00\x75\x07\x83\xc1\xff\x89\x0b\x75\xf1\x8b\xd6\x8b\xc7\x5e\x5f\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x81\xec\x64\x09\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x53\x8b\x5d\x18\x8d\x8d\x6c\xf8\xff\xff\x56\x57\x8b\x7d\x14\x89\xbd\x80\xf8\xff\xff\x89\x9d\x84\xf8\xff\xff\xe8\xf3\xfa\xff\xff\x8b\x75\x0c\x33\xc0\x8b\xce\x81\xe1\x00\x00\x00\x80\x0b\xc1\xb0\x2d\x75\x02\x04\xf3\x0f\xbe\xc0\x8b\xce\x89\x07\x81\xe1\x00\x00\xf0\x7f\x33\xc0\x89\x5f\x08\x0b\xc1\x8b\x7d\x08\x75\x22\x8b\xce\x8b\xc7\x81\xe1\xff\xff\x0f\x00\x0b\xc1\x75\x14\x8b\x85\x80\xf8\xff\xff\x68\x74\x48\x01\x10\x83\x60\x04\x00\xe9\xd3\x12\x00\x00\x8d\x45\x08\x50\xe8\xdb\xc9\xff\xff\x59\x85\xc0\x74\x0d\x8b\x8d\x80\xf8\xff\xff\xc7\x41\x04\x01\x00\x00\x00\x83\xe8\x01\x0f\x84\xaa\x12\x00\x00\x83\xe8\x01\x0f\x84\x9a\x12\x00\x00\x83\xe8\x01\x0f\x84\x8a\x12\x00\x00\x83\xe8\x01\x0f\x84\x7a\x12\x00\x00\x8b\x45\x10\x81\xe6\xff\xff\xff\x7f\x83\xa5\x7c\xf8\xff\xff\x00\x40\x89\x7d\x08\x89\x75\x0c\xdd\x45\x08\xdd\x95\x98\xf8\xff\xff\x8b\xbd\x9c\xf8\xff\xff\x8b\xcf\x89\x85\x88\xf8\xff\xff\xc1\xe9\x14\x8b\xc1\x25\xff\x07\x00\x00\x83\xc8\x00\x75\x06\xb2\x01\x33\xf6\xeb\x09\x32\xd2\xbe\x00\x00\x10\x00\x33\xc0\x8b\x9d\x98\xf8\xff\xff\x81\xe7\xff\xff\x0f\x00\x03\xd8\x13\xfe\x33\xc0\x84\xd2\x0f\x95\xc0\x81\xe1\xff\x07\x00\x00\x40\x8d\xb1\xcc\xfb\xff\xff\x03\xf0\x89\xb5\xb4\xf8\xff\xff\xe8\x81\x1e\x00\x00\x51\x51\xdd\x1c\x24\xe8\x87\x1f\x00\x00\x59\x59\xe8\xc0\x42\x00\x00\x89\x85\x94\xf8\xff\xff\x3d\xff\xff\xff\x7f\x74\x07\x3d\x00\x00\x00\x80\x75\x08\x33\xc0\x89\x85\x94\xf8\xff\xff\x89\x9d\x30\xfe\xff\xff\x33\xdb\x85\xff\x89\xbd\x34\xfe\xff\xff\x0f\x95\xc3\x43\x89\x9d\x2c\xfe\xff\xff\x85\xf6\x0f\x88\xed\x03\x00\x00\x83\xa5\x90\xfa\xff\xff\x00\x6a\x02\x5e\xc7\x85\x94\xfa\xff\xff\x00\x00\x10\x00\x89\xb5\x8c\xfa\xff\xff\x3b\xde\x0f\x85\x00\x02\x00\x00\x33\xc9\x8b\x84\x0d\x90\xfa\xff\xff\x3b\x84\x0d\x30\xfe\xff\xff\x0f\x85\xea\x01\x00\x00\x83\xc1\x04\x83\xf9\x08\x75\xe4\x8b\x85\xb4\xf8\xff\xff\x33\xd2\x83\xc0\x02\x8b\xf0\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\x89\x85\xa4\xf8\xff\xff\x33\xc0\xc1\xee\x05\x40\x89\xb5\xb0\xf8\xff\xff\x89\x8d\x90\xf8\xff\xff\xe8\xf0\x41\x00\x00\x83\xa5\x9c\xf8\xff\xff\x00\x48\x0f\xbd\xcf\x89\x85\xa8\xf8\xff\xff\xf7\xd0\x89\x85\x8c\xf8\xff\xff\x74\x03\x41\xeb\x02\x33\xc9\x6a\x20\x58\x2b\xc1\x8d\x56\x02\x39\x85\xa4\xf8\xff\xff\x89\x95\xac\xf8\xff\xff\x0f\x97\xc0\x83\xfa\x73\x88\x85\xbb\xf8\xff\xff\x0f\x97\xc1\x83\xfa\x73\x75\x08\x84\xc0\x74\x04\xb0\x01\xeb\x02\x32\xc0\x84\xc9\x0f\x85\xef\x00\x00\x00\x84\xc0\x0f\x85\xe7\x00\x00\x00\x6a\x72\x59\x3b\xd1\x72\x08\x8b\xd1\x89\x8d\xac\xf8\xff\xff\x8b\xca\x89\x8d\xa0\xf8\xff\xff\x83\xfa\xff\x0f\x84\x96\x00\x00\x00\x8b\xf2\x8d\x85\x30\xfe\xff\xff\x8b\x95\xb0\xf8\xff\xff\x2b\xf2\x8d\x04\xb0\x89\x85\xb4\xf8\xff\xff\x3b\xca\x72\x6d\x3b\xf3\x73\x04\x8b\x38\xeb\x02\x33\xff\x8d\x46\xff\x3b\xc3\x73\x0b\x8b\x85\xb4\xf8\xff\xff\x8b\x40\xfc\xeb\x02\x33\xc0\x23\x85\x8c\xf8\xff\xff\x23\xbd\xa8\xf8\xff\xff\x8b\x8d\x90\xf8\xff\xff\xd3\xe8\x8b\x8d\xa4\xf8\xff\xff\xd3\xe7\x8b\x8d\xa0\xf8\xff\xff\x0b\xc7\x89\x84\x8d\x30\xfe\xff\xff\x49\x8b\x85\xb4\xf8\xff\xff\x4e\x83\xe8\x04\x89\x8d\xa0\xf8\xff\xff\x89\x85\xb4\xf8\xff\xff\x83\xf9\xff\x74\x08\x8b\x9d\x2c\xfe\xff\xff\xeb\x8f\x8b\x95\xac\xf8\xff\xff\x8b\xb5\xb0\xf8\xff\xff\x85\xf6\x74\x0c\x8b\xce\x8d\xbd\x30\xfe\xff\xff\x33\xc0\xf3\xab\x80\xbd\xbb\xf8\xff\xff\x00\xbb\xcc\x01\x00\x00\x74\x0b\x8d\x42\x01\x89\x85\x2c\xfe\xff\xff\xeb\x33\x89\x95\x2c\xfe\xff\xff\xeb\x2b\x33\xc0\xbb\xcc\x01\x00\x00\x50\x89\x85\x8c\xfa\xff\xff\x89\x85\x2c\xfe\xff\xff\x8d\x85\x90\xfa\xff\xff\x50\x8d\x85\x30\xfe\xff\xff\x53\x50\xe8\x29\x10\x00\x00\x83\xc4\x10\x83\xa5\x94\xfa\xff\xff\x00\x33\xc9\x6a\x04\x58\x41\x89\x85\x90\xfa\xff\xff\x89\x8d\x8c\xfa\xff\xff\x89\x8d\x5c\xfc\xff\xff\x50\x8d\x85\x90\xfa\xff\xff\x50\x8d\x85\x60\xfc\xff\xff\x53\x50\xe8\xf2\x0f\x00\x00\x83\xc4\x10\xe9\x5c\x04\x00\x00\x8b\x85\xb4\xf8\xff\xff\x33\xd2\x40\x8b\xf8\x83\xe0\x1f\x6a\x20\x59\x2b\xc8\x89\x85\xb0\xf8\xff\xff\x33\xc0\xc1\xef\x05\x40\x89\xbd\xb4\xf8\xff\xff\x89\x8d\x90\xf8\xff\xff\xe8\x10\x40\x00\x00\x8b\x8c\x9d\x2c\xfe\xff\xff\x48\x83\xa5\x9c\xf8\xff\xff\x00\x0f\xbd\xc9\x89\x85\xa8\xf8\xff\xff\xf7\xd0\x89\x85\x8c\xf8\xff\xff\x74\x03\x41\xeb\x02\x33\xc9\x6a\x20\x58\x2b\xc1\x8d\x14\x3b\x39\x85\xb0\xf8\xff\xff\x89\x95\xa0\xf8\xff\xff\x0f\x97\xc0\x83\xfa\x73\x88\x85\xbb\xf8\xff\xff\x0f\x97\xc1\x83\xfa\x73\x75\x08\x84\xc0\x74\x04\xb0\x01\xeb\x02\x32\xc0\x84\xc9\x0f\x85\xec\x00\x00\x00\x84\xc0\x0f\x85\xe4\x00\x00\x00\x6a\x72\x59\x3b\xd1\x72\x08\x8b\xd1\x89\x8d\xa0\xf8\xff\xff\x8b\xc2\x89\x85\xac\xf8\xff\xff\x83\xfa\xff\x0f\x84\x93\x00\x00\x00\x8b\xf2\x8d\x8d\x30\xfe\xff\xff\x8b\x95\xb4\xf8\xff\xff\x2b\xf2\x8d\x0c\xb1\x89\x8d\xa4\xf8\xff\xff\x3b\xc2\x72\x67\x3b\xf3\x73\x04\x8b\x39\xeb\x02\x33\xff\x8d\x46\xff\x3b\xc3\x73\x05\x8b\x41\xfc\xeb\x02\x33\xc0\x23\xbd\xa8\xf8\xff\xff\x23\x85\x8c\xf8\xff\xff\x8b\x8d\xb0\xf8\xff\xff\xd3\xe7\x8b\x8d\x90\xf8\xff\xff\xd3\xe8\x8b\x8d\xa4\xf8\xff\xff\x0b\xf8\x8b\x85\xac\xf8\xff\xff\x83\xe9\x04\x89\x8d\xa4\xf8\xff\xff\x89\xbc\x85\x30\xfe\xff\xff\x48\x4e\x89\x85\xac\xf8\xff\xff\x83\xf8\xff\x74\x08\x8b\x9d\x2c\xfe\xff\xff\xeb\x95\x8b\x95\xa0\xf8\xff\xff\x8b\xbd\xb4\xf8\xff\xff\x6a\x02\x5e\x85\xff\x74\x0c\x8b\xcf\x33\xc0\x8d\xbd\x30\xfe\xff\xff\xf3\xab\x80\xbd\xbb\xf8\xff\xff\x00\xbb\xcc\x01\x00\x00\x74\x0b\x8d\x42\x01\x89\x85\x2c\xfe\xff\xff\xeb\x33\x89\x95\x2c\xfe\xff\xff\xeb\x2b\x33\xc0\xbb\xcc\x01\x00\x00\x50\x89\x85\x8c\xfa\xff\xff\x89\x85\x2c\xfe\xff\xff\x8d\x85\x90\xfa\xff\xff\x50\x8d\x85\x30\xfe\xff\xff\x53\x50\xe8\x45\x0e\x00\x00\x83\xc4\x10\x83\xa5\x94\xfa\xff\xff\x00\x33\xc0\x40\x89\xb5\x90\xfa\xff\xff\x89\x85\x8c\xfa\xff\xff\x89\x85\x5c\xfc\xff\xff\x6a\x04\xe9\x19\xfe\xff\xff\x81\xfe\x02\xfc\xff\xff\x0f\x84\x19\x01\x00\x00\x83\xa5\x90\xfa\xff\xff\x00\x6a\x02\x59\xc7\x85\x94\xfa\xff\xff\x00\x00\x10\x00\x89\x8d\x8c\xfa\xff\xff\x3b\xd9\x0f\x85\xf7\x00\x00\x00\x33\xd2\x8b\x84\x15\x90\xfa\xff\xff\x3b\x84\x15\x30\xfe\xff\xff\x0f\x85\xe1\x00\x00\x00\x83\xc2\x04\x83\xfa\x08\x75\xe4\x83\xa5\x9c\xf8\xff\xff\x00\x0f\xbd\xc7\x74\x05\x8d\x50\x01\xeb\x02\x33\xd2\x6a\x20\x58\x2b\xc2\x8b\xf1\x3b\xc1\x8d\x85\x38\xfe\xff\xff\x89\x85\xac\xf8\xff\xff\x8b\xf8\x0f\x92\x85\xbb\xf8\xff\xff\x3b\xf3\x73\x0a\x8b\x17\x89\x95\xb0\xf8\xff\xff\xeb\x07\x83\xa5\xb0\xf8\xff\xff\x00\x8d\x46\xff\x3b\xc3\x73\x05\x8b\x57\xfc\xeb\x02\x33\xd2\x8b\x85\xb0\xf8\xff\xff\x83\xef\x04\xc1\xe0\x02\xc1\xea\x1e\x33\xd0\x8b\x85\xac\xf8\xff\xff\x4e\x89\x10\x83\xe8\x04\x89\x85\xac\xf8\xff\xff\x83\xfe\xff\x74\x08\x8b\x9d\x2c\xfe\xff\xff\xeb\xad\x33\xc0\x38\x85\xbb\xf8\xff\xff\x0f\x95\xc0\x03\xc1\x2b\x8d\xb4\xf8\xff\xff\x8b\xf9\x89\x85\x2c\xfe\xff\xff\xc1\xef\x05\x8d\x85\x90\xfa\xff\xff\x8b\xf7\x89\x8d\xa8\xf8\xff\xff\xc1\xe6\x02\x56\x6a\x00\x50\xe8\x9d\x7b\xff\xff\x8b\x8d\xa8\xf8\xff\xff\x33\xc0\x40\x83\xe1\x1f\xd3\xe0\x89\x84\x35\x90\xfa\xff\xff\x8d\x47\x01\xe9\x40\x01\x00\x00\x8b\x84\x9d\x2c\xfe\xff\xff\x83\xa5\x9c\xf8\xff\xff\x00\x0f\xbd\xc0\x74\x05\x8d\x48\x01\xeb\x02\x33\xc9\x6a\x20\x58\x2b\xc1\x83\xf8\x01\x0f\x92\xc0\x83\xfb\x73\x88\x85\xbb\xf8\xff\xff\x0f\x97\xc1\x83\xfb\x73\x75\x08\x84\xc0\x74\x04\xb0\x01\xeb\x02\x32\xc0\x84\xc9\x0f\x85\x9b\x00\x00\x00\x84\xc0\x0f\x85\x93\x00\x00\x00\x6a\x72\x59\x3b\xd9\x73\x02\x8b\xcb\x83\xf9\xff\x74\x69\x8d\xbd\x30\xfe\xff\xff\x8b\xf1\x8d\x3c\x8f\x89\xbd\xac\xf8\xff\xff\x3b\xf3\x73\x0a\x8b\x17\x89\x95\xb0\xf8\xff\xff\xeb\x07\x83\xa5\xb0\xf8\xff\xff\x00\x8d\x46\xff\x3b\xc3\x73\x05\x8b\x57\xfc\xeb\x02\x33\xd2\x8b\x85\xb0\xf8\xff\xff\x83\xef\x04\x03\xc0\xc1\xea\x1f\x33\xd0\x8b\x85\xac\xf8\xff\xff\x4e\x89\x10\x83\xe8\x04\x89\x85\xac\xf8\xff\xff\x83\xfe\xff\x74\x08\x8b\x9d\x2c\xfe\xff\xff\xeb\xae\x8b\xb5\xb4\xf8\xff\xff\x80\xbd\xbb\xf8\xff\xff\x00\x74\x0b\x8d\x41\x01\x89\x85\x2c\xfe\xff\xff\xeb\x33\x89\x8d\x2c\xfe\xff\xff\xeb\x2b\x83\xa5\x8c\xfa\xff\xff\x00\x8d\x85\x90\xfa\xff\xff\x83\xa5\x2c\xfe\xff\xff\x00\x6a\x00\x50\x8d\x85\x30\xfe\xff\xff\x68\xcc\x01\x00\x00\x50\xe8\xef\x0b\x00\x00\x83\xc4\x10\x33\xff\x8d\x85\x90\xfa\xff\xff\x47\x2b\xfe\x8b\xdf\xc1\xeb\x05\x8b\xf3\xc1\xe6\x02\x56\x6a\x00\x50\xe8\x54\x7a\xff\xff\x33\xc0\x83\xe7\x1f\x40\x8b\xcf\xd3\xe0\x89\x84\x35\x90\xfa\xff\xff\x8d\x43\x01\x89\x85\x8c\xfa\xff\xff\xbb\xcc\x01\x00\x00\x89\x85\x5c\xfc\xff\xff\xc1\xe0\x02\x50\x8d\x85\x90\xfa\xff\xff\x50\x8d\x85\x60\xfc\xff\xff\x53\x50\xe8\x91\x0b\x00\x00\x83\xc4\x1c\x8b\x85\x94\xf8\xff\xff\x33\xd2\x6a\x0a\x59\x89\x8d\x8c\xf8\xff\xff\x85\xc0\x0f\x88\x63\x04\x00\x00\xf7\xf1\x89\x85\x90\xf8\xff\xff\x8b\xca\x89\x8d\x9c\xf8\xff\xff\x85\xc0\x0f\x84\x71\x03\x00\x00\x83\xf8\x26\x76\x03\x6a\x26\x58\x0f\xb6\x0c\x85\xb6\x47\x01\x10\x0f\xb6\x34\x85\xb7\x47\x01\x10\x8b\xf9\x89\x85\xa4\xf8\xff\xff\xc1\xe7\x02\x57\x8d\x04\x31\x89\x85\x8c\xfa\xff\xff\x8d\x85\x90\xfa\xff\xff\x6a\x00\x50\xe8\xa8\x79\xff\xff\x8b\xc6\xc1\xe0\x02\x50\x8b\x85\xa4\xf8\xff\xff\x0f\xb7\x04\x85\xb4\x47\x01\x10\x8d\x04\x85\xb0\x3e\x01\x10\x50\x8d\x85\x90\xfa\xff\xff\x03\xc7\x50\xe8\x2e\x3c\x00\x00\x8b\x8d\x8c\xfa\xff\xff\x83\xc4\x18\x89\x8d\xa0\xf8\xff\xff\x83\xf9\x01\x77\x7a\x8b\xbd\x90\xfa\xff\xff\x85\xff\x75\x13\x33\xc0\x89\x85\xbc\xf8\xff\xff\x89\x85\x5c\xfc\xff\xff\xe9\x9f\x02\x00\x00\x83\xff\x01\x0f\x84\xae\x02\x00\x00\x83\xbd\x5c\xfc\xff\xff\x00\x0f\x84\xa1\x02\x00\x00\x8b\x85\x5c\xfc\xff\xff\x33\xc9\x89\x85\xa8\xf8\xff\xff\x33\xf6\x8b\xc7\xf7\xa4\xb5\x60\xfc\xff\xff\x03\xc1\x89\x84\xb5\x60\xfc\xff\xff\x83\xd2\x00\x46\x8b\xca\x3b\xb5\xa8\xf8\xff\xff\x75\xe0\xe9\xac\x00\x00\x00\x89\x8c\x85\x60\xfc\xff\xff\xff\x85\x5c\xfc\xff\xff\xe9\x5a\x02\x00\x00\x83\xbd\x5c\xfc\xff\xff\x01\x0f\x87\xbe\x00\x00\x00\x8b\xbd\x60\xfc\xff\xff\x8b\xc1\xc1\xe0\x02\x50\x8d\x85\x90\xfa\xff\xff\x89\x8d\x5c\xfc\xff\xff\x50\x8d\x85\x60\xfc\xff\xff\x53\x50\xe8\x37\x0a\x00\x00\x83\xc4\x10\x85\xff\x75\x1a\x33\xc0\x89\x85\x8c\xfa\xff\xff\x89\x85\x5c\xfc\xff\xff\x50\x8d\x85\x90\xfa\xff\xff\xe9\xf5\x01\x00\x00\x83\xff\x01\x0f\x84\xfd\x01\x00\x00\x83\xbd\x5c\xfc\xff\xff\x00\x0f\x84\xf0\x01\x00\x00\x8b\x85\x5c\xfc\xff\xff\x33\xc9\x89\x85\xa8\xf8\xff\xff\x33\xf6\x8b\xc7\xf7\xa4\xb5\x60\xfc\xff\xff\x03\xc1\x89\x84\xb5\x60\xfc\xff\xff\x83\xd2\x00\x46\x8b\xca\x3b\xb5\xa8\xf8\xff\xff\x75\xe0\x85\xc9\x0f\x84\xb8\x01\x00\x00\x8b\x85\x5c\xfc\xff\xff\x83\xf8\x73\x0f\x82\x3d\xff\xff\xff\x33\xc0\x89\x85\x8c\xfa\xff\xff\x89\x85\x5c\xfc\xff\xff\x50\x8d\x85\x90\xfa\xff\xff\xe9\xec\x01\x00\x00\x3b\x8d\x5c\xfc\xff\xff\x8d\xbd\x90\xfa\xff\xff\x0f\x92\xc0\x84\xc0\x0f\x85\x83\x00\x00\x00\x8d\xbd\x60\xfc\xff\xff\x8d\x95\x90\xfa\xff\xff\x89\x95\xb0\xf8\xff\xff\x84\xc0\x75\x06\x8b\x8d\x5c\xfc\xff\xff\x89\x8d\xac\xf8\xff\xff\x84\xc0\x74\x0c\x8b\x85\x5c\xfc\xff\xff\x89\x85\xa0\xf8\xff\xff\x33\xd2\x33\xf6\x89\x95\xbc\xf8\xff\xff\x85\xc9\x0f\x84\x11\x01\x00\x00\x8d\x85\xc0\xf8\xff\xff\x2b\xf8\x89\xbd\x7c\xf8\xff\xff\x8d\x04\xb7\x8b\x84\x05\xc0\xf8\xff\xff\x89\x85\xa8\xf8\xff\xff\x85\xc0\x75\x25\x3b\xf2\x0f\x85\xde\x00\x00\x00\x21\x84\xb5\xc0\xf8\xff\xff\x8d\x56\x01\x89\x95\xbc\xf8\xff\xff\xe9\xc9\x00\x00\x00\x8d\x95\x60\xfc\xff\xff\xeb\x81\x33\xc0\x33\xff\x8b\xce\x89\x85\xb4\xf8\xff\xff\x39\x85\xa0\xf8\xff\xff\x0f\x84\x94\x00\x00\x00\x83\xf9\x73\x74\x57\x3b\xca\x75\x17\x83\xa4\x8d\xc0\xf8\xff\xff\x00\x40\x03\xc6\x89\x85\xbc\xf8\xff\xff\x8b\x85\xb4\xf8\xff\xff\x8b\x95\xb0\xf8\xff\xff\x8b\x04\x82\xf7\xa5\xa8\xf8\xff\xff\x03\xc7\x83\xd2\x00\x01\x84\x8d\xc0\xf8\xff\xff\x8b\x85\xb4\xf8\xff\xff\x83\xd2\x00\x40\x41\x89\x85\xb4\xf8\xff\xff\x8b\xfa\x8b\x95\xbc\xf8\xff\xff\x3b\x85\xa0\xf8\xff\xff\x75\xa4\x85\xff\x74\x34\x83\xf9\x73\x0f\x84\xb4\x00\x00\x00\x3b\xca\x75\x11\x83\xa4\x8d\xc0\xf8\xff\xff\x00\x8d\x41\x01\x89\x85\xbc\xf8\xff\xff\x8b\xc7\x33\xff\x01\x84\x8d\xc0\xf8\xff\xff\x8b\x95\xbc\xf8\xff\xff\x13\xff\x41\xeb\xc8\x83\xf9\x73\x0f\x84\x80\x00\x00\x00\x8b\xbd\x7c\xf8\xff\xff\x8b\x8d\xac\xf8\xff\xff\x46\x3b\xf1\x0f\x85\xfd\xfe\xff\xff\x8b\xc2\x89\x95\x5c\xfc\xff\xff\xc1\xe0\x02\x50\x8d\x85\xc0\xf8\xff\xff\x50\x8d\x85\x60\xfc\xff\xff\x53\x50\xe8\x13\x08\x00\x00\x83\xc4\x10\xb0\x01\x84\xc0\x74\x6c\x8b\x85\x90\xf8\xff\xff\x2b\x85\xa4\xf8\xff\xff\x89\x85\x90\xf8\xff\xff\x0f\x85\x95\xfc\xff\xff\x8b\x8d\x9c\xf8\xff\xff\x85\xc9\x0f\x84\x13\x05\x00\x00\x8b\x3c\x8d\x4c\x48\x01\x10\x85\xff\x75\x5d\x33\xc0\x89\x85\x9c\xf6\xff\xff\x89\x85\x5c\xfc\xff\xff\x50\xeb\x3a\x33\xc0\x89\x85\x9c\xf6\xff\xff\x89\x85\x5c\xfc\xff\xff\x50\x8d\x85\xa0\xf6\xff\xff\x50\x8d\x85\x60\xfc\xff\xff\x53\x50\xe8\xa5\x07\x00\x00\x83\xc4\x10\x32\xc0\xeb\x90\x83\xa5\x9c\xf6\xff\xff\x00\x83\xa5\x5c\xfc\xff\xff\x00\x6a\x00\x8d\x85\xa0\xf6\xff\xff\x50\x8d\x85\x60\xfc\xff\xff\xe9\xa1\x04\x00\x00\x83\xff\x01\x0f\x84\xa2\x04\x00\x00\x8b\x85\x5c\xfc\xff\xff\x89\x85\x9c\xf8\xff\xff\x85\xc0\x0f\x84\x8e\x04\x00\x00\x33\xf6\x33\xc9\x8b\xc7\xf7\xa4\x8d\x60\xfc\xff\xff\x03\xc6\x89\x84\x8d\x60\xfc\xff\xff\x83\xd2\x00\x41\x8b\xf2\x3b\x8d\x9c\xf8\xff\xff\x75\xe0\x85\xf6\x0f\x84\x62\x04\x00\x00\x8b\x85\x5c\xfc\xff\xff\x83\xf8\x73\x0f\x83\x4b\xff\xff\xff\x89\xb4\x85\x60\xfc\xff\xff\xff\x85\x5c\xfc\xff\xff\xe9\x41\x04\x00\x00\xf7\xd8\xf7\xf1\x89\x85\xac\xf8\xff\xff\x8b\xca\x89\x8d\xa8\xf8\xff\xff\x85\xc0\x0f\x84\x4c\x03\x00\x00\x83\xf8\x26\x76\x03\x6a\x26\x58\x0f\xb6\x0c\x85\xb6\x47\x01\x10\x0f\xb6\x34\x85\xb7\x47\x01\x10\x8b\xf9\x89\x85\xb4\xf8\xff\xff\xc1\xe7\x02\x57\x8d\x04\x31\x89\x85\x8c\xfa\xff\xff\x8d\x85\x90\xfa\xff\xff\x6a\x00\x50\xe8\x43\x75\xff\xff\x8b\xc6\xc1\xe0\x02\x50\x8b\x85\xb4\xf8\xff\xff\x0f\xb7\x04\x85\xb4\x47\x01\x10\x8d\x04\x85\xb0\x3e\x01\x10\x50\x8d\x85\x90\xfa\xff\xff\x03\xc7\x50\xe8\xc9\x37\x00\x00\x8b\x8d\x8c\xfa\xff\xff\x83\xc4\x18\x89\x8d\xa0\xf8\xff\xff\x83\xf9\x01\x0f\x87\x93\x00\x00\x00\x8b\xbd\x90\xfa\xff\xff\x85\xff\x75\x1a\x33\xc0\x89\x85\x9c\xf6\xff\xff\x89\x85\x2c\xfe\xff\xff\x50\x8d\x85\xa0\xf6\xff\xff\xe9\x72\x02\x00\x00\x83\xff\x01\x0f\x84\x7a\x02\x00\x00\x83\xbd\x2c\xfe\xff\xff\x00\x0f\x84\x6d\x02\x00\x00\x8b\x85\x2c\xfe\xff\xff\x33\xc9\x89\x85\x9c\xf8\xff\xff\x33\xf6\x8b\xc7\xf7\xa4\xb5\x30\xfe\xff\xff\x03\xc1\x89\x84\xb5\x30\xfe\xff\xff\x83\xd2\x00\x46\x8b\xca\x3b\xb5\x9c\xf8\xff\xff\x75\xe0\x85\xc9\x0f\x84\x35\x02\x00\x00\x8b\x85\x2c\xfe\xff\xff\x83\xf8\x73\x0f\x83\xc4\x02\x00\x00\x89\x8c\x85\x30\xfe\xff\xff\xff\x85\x2c\xfe\xff\xff\xe9\x14\x02\x00\x00\x83\xbd\x2c\xfe\xff\xff\x01\x77\x7c\x8b\xbd\x30\xfe\xff\xff\x8b\xc1\xc1\xe0\x02\x50\x8d\x85\x90\xfa\xff\xff\x89\x8d\x2c\xfe\xff\xff\x50\x8d\x85\x30\xfe\xff\xff\x53\x50\xe8\xb9\x05\x00\x00\x83\xc4\x10\x85\xff\x0f\x84\x3d\xff\xff\xff\x83\xff\x01\x0f\x84\xd1\x01\x00\x00\x83\xbd\x2c\xfe\xff\xff\x00\x0f\x84\xc4\x01\x00\x00\x8b\x85\x2c\xfe\xff\xff\x33\xc9\x89\x85\x9c\xf8\xff\xff\x33\xf6\x8b\xc7\xf7\xa4\xb5\x30\xfe\xff\xff\x03\xc1\x89\x84\xb5\x30\xfe\xff\xff\x83\xd2\x00\x46\x8b\xca\x3b\xb5\x9c\xf8\xff\xff\x75\xe0\xe9\x52\xff\xff\xff\x3b\x8d\x2c\xfe\xff\xff\x8d\xbd\x90\xfa\xff\xff\x0f\x92\xc0\x84\xc0\x0f\x85\x83\x00\x00\x00\x8d\xbd\x30\xfe\xff\xff\x8d\x95\x90\xfa\xff\xff\x89\x95\x90\xf8\xff\xff\x84\xc0\x75\x06\x8b\x8d\x2c\xfe\xff\xff\x89\x8d\xb0\xf8\xff\xff\x84\xc0\x74\x0c\x8b\x85\x2c\xfe\xff\xff\x89\x85\xa0\xf8\xff\xff\x33\xd2\x33\xf6\x89\x95\xbc\xf8\xff\xff\x85\xc9\x0f\x84\x11\x01\x00\x00\x8d\x85\xc0\xf8\xff\xff\x2b\xf8\x89\xbd\x7c\xf8\xff\xff\x8d\x04\xb7\x8b\x84\x05\xc0\xf8\xff\xff\x89\x85\x9c\xf8\xff\xff\x85\xc0\x75\x25\x3b\xf2\x0f\x85\xde\x00\x00\x00\x21\x84\xb5\xc0\xf8\xff\xff\x8d\x56\x01\x89\x95\xbc\xf8\xff\xff\xe9\xc9\x00\x00\x00\x8d\x95\x30\xfe\xff\xff\xeb\x81\x33\xc0\x33\xff\x8b\xce\x89\x85\xa4\xf8\xff\xff\x39\x85\xa0\xf8\xff\xff\x0f\x84\x94\x00\x00\x00\x83\xf9\x73\x74\x57\x3b\xca\x75\x17\x83\xa4\x8d\xc0\xf8\xff\xff\x00\x40\x03\xc6\x89\x85\xbc\xf8\xff\xff\x8b\x85\xa4\xf8\xff\xff\x8b\x95\x90\xf8\xff\xff\x8b\x04\x82\xf7\xa5\x9c\xf8\xff\xff\x03\xc7\x83\xd2\x00\x01\x84\x8d\xc0\xf8\xff\xff\x8b\x85\xa4\xf8\xff\xff\x83\xd2\x00\x40\x41\x89\x85\xa4\xf8\xff\xff\x8b\xfa\x8b\x95\xbc\xf8\xff\xff\x3b\x85\xa0\xf8\xff\xff\x75\xa4\x85\xff\x74\x34\x83\xf9\x73\x0f\x84\x0a\x01\x00\x00\x3b\xca\x75\x11\x83\xa4\x8d\xc0\xf8\xff\xff\x00\x8d\x41\x01\x89\x85\xbc\xf8\xff\xff\x8b\xc7\x33\xff\x01\x84\x8d\xc0\xf8\xff\xff\x8b\x95\xbc\xf8\xff\xff\x13\xff\x41\xeb\xc8\x83\xf9\x73\x0f\x84\xd6\x00\x00\x00\x8b\xbd\x7c\xf8\xff\xff\x8b\x8d\xb0\xf8\xff\xff\x46\x3b\xf1\x0f\x85\xfd\xfe\xff\xff\x8b\xc2\x89\x95\x2c\xfe\xff\xff\xc1\xe0\x02\x50\x8d\x85\xc0\xf8\xff\xff\x50\x8d\x85\x30\xfe\xff\xff\x53\x50\xe8\xd7\x03\x00\x00\x83\xc4\x10\xb0\x01\x84\xc0\x0f\x84\xc1\x00\x00\x00\x8b\x85\xac\xf8\xff\xff\x2b\x85\xb4\xf8\xff\xff\x89\x85\xac\xf8\xff\xff\x0f\x85\xba\xfc\xff\xff\x8b\x8d\xa8\xf8\xff\xff\x85\xc9\x0f\x84\xd3\x00\x00\x00\x8b\x04\x8d\x4c\x48\x01\x10\x89\x85\x9c\xf8\xff\xff\x85\xc0\x0f\x84\x98\x00\x00\x00\x83\xf8\x01\x0f\x84\xb5\x00\x00\x00\x8b\x8d\x2c\xfe\xff\xff\x85\xc9\x0f\x84\xa7\x00\x00\x00\x33\xff\x33\xf6\xf7\xa4\xb5\x30\xfe\xff\xff\x03\xc7\x89\x84\xb5\x30\xfe\xff\xff\x8b\x85\x9c\xf8\xff\xff\x83\xd2\x00\x46\x8b\xfa\x3b\xf1\x75\xe0\x85\xff\x74\x7f\x8b\x85\x2c\xfe\xff\xff\x83\xf8\x73\x73\x4e\x89\xbc\x85\x30\xfe\xff\xff\xff\x85\x2c\xfe\xff\xff\xeb\x65\x33\xc0\x50\x89\x85\x9c\xf6\xff\xff\x89\x85\x2c\xfe\xff\xff\x8d\x85\xa0\xf6\xff\xff\x50\x8d\x85\x30\xfe\xff\xff\x53\x50\xe8\x13\x03\x00\x00\x83\xc4\x10\x32\xc0\xe9\x37\xff\xff\xff\x83\xa5\x9c\xf6\xff\xff\x00\x83\xa5\x2c\xfe\xff\xff\x00\x6a\x00\xeb\x0f\x33\xc0\x50\x89\x85\x2c\xfe\xff\xff\x89\x85\x9c\xf6\xff\xff\x8d\x85\xa0\xf6\xff\xff\x50\x8d\x85\x30\xfe\xff\xff\x53\x50\xe8\xd4\x02\x00\x00\x83\xc4\x10\x8b\xbd\x84\xf8\xff\xff\x8b\xf7\x8b\x8d\x2c\xfe\xff\xff\x89\xb5\xb4\xf8\xff\xff\x85\xc9\x74\x77\x33\xf6\x33\xff\x8b\x84\xbd\x30\xfe\xff\xff\x6a\x0a\x5a\xf7\xe2\x03\xc6\x89\x84\xbd\x30\xfe\xff\xff\x83\xd2\x00\x47\x8b\xf2\x3b\xf9\x75\xe1\x89\xb5\x9c\xf8\xff\xff\x85\xf6\x8b\xb5\xb4\xf8\xff\xff\x74\x42\x8b\x8d\x2c\xfe\xff\xff\x83\xf9\x73\x73\x11\x8b\xc2\x89\x84\x8d\x30\xfe\xff\xff\xff\x85\x2c\xfe\xff\xff\xeb\x26\x33\xc0\x50\x89\x85\x9c\xf6\xff\xff\x89\x85\x2c\xfe\xff\xff\x8d\x85\xa0\xf6\xff\xff\x50\x8d\x85\x30\xfe\xff\xff\x53\x50\xe8\x47\x02\x00\x00\x83\xc4\x10\x8b\xfe\x8d\x85\x5c\xfc\xff\xff\x50\x8d\x85\x2c\xfe\xff\xff\x50\xe8\xe5\xe9\xff\xff\x59\x59\x6a\x0a\x5a\x3b\xc2\x0f\x85\x91\x00\x00\x00\xff\x85\x94\xf8\xff\xff\x8d\x77\x01\x8b\x85\x5c\xfc\xff\xff\xc6\x07\x31\x89\xb5\xb4\xf8\xff\xff\x85\xc0\x0f\x84\x8b\x00\x00\x00\x33\xff\x8b\xf0\x33\xc9\x8b\x84\x8d\x60\xfc\xff\xff\xf7\xe2\x6a\x0a\x03\xc7\x89\x84\x8d\x60\xfc\xff\xff\x83\xd2\x00\x41\x8b\xfa\x5a\x3b\xce\x75\xe1\x8b\xb5\xb4\xf8\xff\xff\x85\xff\x74\x5c\x8b\x85\x5c\xfc\xff\xff\x83\xf8\x73\x73\x0f\x89\xbc\x85\x60\xfc\xff\xff\xff\x85\x5c\xfc\xff\xff\xeb\x42\x33\xc0\x50\x89\x85\x9c\xf6\xff\xff\x89\x85\x5c\xfc\xff\xff\x8d\x85\xa0\xf6\xff\xff\x50\x8d\x85\x60\xfc\xff\xff\x53\x50\xe8\x96\x01\x00\x00\x83\xc4\x10\xeb\x1a\x85\xc0\x75\x09\x8b\x85\x94\xf8\xff\xff\x48\xeb\x13\x04\x30\x8d\x77\x01\x88\x07\x89\xb5\xb4\xf8\xff\xff\x8b\x85\x94\xf8\xff\xff\x8b\x8d\x80\xf8\xff\xff\x89\x41\x04\x8b\x8d\x88\xf8\xff\xff\x85\xc0\x78\x0a\x81\xf9\xff\xff\xff\x7f\x77\x02\x03\xc8\x8b\x45\x1c\x48\x3b\xc1\x72\x02\x8b\xc1\x03\x85\x84\xf8\xff\xff\x89\x85\x88\xf8\xff\xff\x3b\xf0\x0f\x84\xd3\x00\x00\x00\x8b\x85\x2c\xfe\xff\xff\x85\xc0\x0f\x84\xc5\x00\x00\x00\x33\xff\x8b\xf0\x33\xc9\x8b\x84\x8d\x30\xfe\xff\xff\xba\x00\xca\x9a\x3b\xf7\xe2\x03\xc7\x89\x84\x8d\x30\xfe\xff\xff\x83\xd2\x00\x41\x8b\xfa\x3b\xce\x75\xdf\x8b\xb5\xb4\xf8\xff\xff\x85\xff\x74\x40\x8b\x85\x2c\xfe\xff\xff\x83\xf8\x73\x73\x0f\x89\xbc\x85\x30\xfe\xff\xff\xff\x85\x2c\xfe\xff\xff\xeb\x26\x33\xc0\x50\x89\x85\x9c\xf6\xff\xff\x89\x85\x2c\xfe\xff\xff\x8d\x85\xa0\xf6\xff\xff\x50\x8d\x85\x30\xfe\xff\xff\x53\x50\xe8\xba\x00\x00\x00\x83\xc4\x10\x8d\x85\x5c\xfc\xff\xff\x50\x8d\x85\x2c\xfe\xff\xff\x50\xe8\x5a\xe8\xff\xff\x59\x59\x8b\x8d\x88\xf8\xff\xff\x6a\x08\x5f\x2b\xce\x33\xd2\xf7\xb5\x8c\xf8\xff\xff\x80\xc2\x30\x3b\xcf\x72\x03\x88\x14\x37\x4f\x83\xff\xff\x75\xe8\x83\xf9\x09\x76\x03\x6a\x09\x59\x03\xf1\x89\xb5\xb4\xf8\xff\xff\x3b\xb5\x88\xf8\xff\xff\x0f\x85\x2d\xff\xff\xff\xc6\x06\x00\xeb\x2a\x68\x90\x48\x01\x10\xeb\x13\x68\x88\x48\x01\x10\xeb\x0c\x68\x80\x48\x01\x10\xeb\x05\x68\x78\x48\x01\x10\xff\x75\x1c\x53\xe8\x80\x9a\xff\xff\x83\xc4\x0c\x85\xc0\x75\x27\x80\xbd\x74\xf8\xff\xff\x00\x5f\x5e\x5b\x74\x0d\x8d\x85\x6c\xf8\xff\xff\x50\xe8\x67\x0b\x00\x00\x59\x8b\x4d\xfc\x33\xcd\xe8\xdb\x5e\xff\xff\x8b\xe5\x5d\xc3\x33\xc0\x50\x50\x50\x50\x50\xe8\x46\xa0\xff\xff\xcc\x8b\xff\x55\x8b\xec\x56\x8b\x75\x14\x85\xf6\x75\x04\x33\xc0\xeb\x6d\x8b\x45\x08\x85\xc0\x75\x13\xe8\xd4\xa0\xff\xff\x6a\x16\x5e\x89\x30\xe8\x0e\xa0\xff\xff\x8b\xc6\xeb\x53\x57\x8b\x7d\x10\x85\xff\x74\x14\x39\x75\x0c\x72\x0f\x56\x57\x50\xe8\xf6\x30\x00\x00\x83\xc4\x0c\x33\xc0\xeb\x36\xff\x75\x0c\x6a\x00\x50\xe8\x34\x6e\xff\xff\x83\xc4\x0c\x85\xff\x75\x09\xe8\x93\xa0\xff\xff\x6a\x16\xeb\x0c\x39\x75\x0c\x73\x13\xe8\x85\xa0\xff\xff\x6a\x22\x5e\x89\x30\xe8\xbf\x9f\xff\xff\x8b\xc6\xeb\x03\x6a\x16\x58\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x57\xff\x75\x0c\xe8\x53\xc0\xff\xff\x59\x8b\x4d\x0c\x8b\xf8\x8b\x49\x0c\xf6\xc1\x06\x75\x1f\xe8\x4f\xa0\xff\xff\xc7\x00\x09\x00\x00\x00\x8b\x45\x0c\x6a\x10\x59\x83\xc0\x0c\xf0\x09\x08\x83\xc8\xff\xe9\xd3\x00\x00\x00\x8b\x45\x0c\x8b\x40\x0c\xc1\xe8\x0c\xa8\x01\x74\x0d\xe8\x23\xa0\xff\xff\xc7\x00\x22\x00\x00\x00\xeb\xd2\x8b\x45\x0c\x8b\x40\x0c\xa8\x01\x74\x28\x8b\x45\x0c\x83\x60\x08\x00\x8b\x45\x0c\x8b\x40\x0c\xc1\xe8\x03\xa8\x01\x8b\x45\x0c\x74\xb4\x8b\x48\x04\x89\x08\x8b\x45\x0c\x6a\xfe\x59\x83\xc0\x0c\xf0\x21\x08\x8b\x45\x0c\x53\x6a\x02\x5b\x83\xc0\x0c\xf0\x09\x18\x8b\x45\x0c\x6a\xf7\x59\x83\xc0\x0c\xf0\x21\x08\x8b\x45\x0c\x83\x60\x08\x00\x8b\x45\x0c\x8b\x40\x0c\xa9\xc0\x04\x00\x00\x75\x33\x56\x8b\x75\x0c\x6a\x01\xe8\x75\x77\xff\xff\x59\x3b\xf0\x74\x0e\x8b\x75\x0c\x53\xe8\x67\x77\xff\xff\x59\x3b\xf0\x75\x0b\x57\xe8\x10\x01\x00\x00\x59\x85\xc0\x75\x09\xff\x75\x0c\xe8\xed\x0c\x00\x00\x59\x5e\xff\x75\x0c\x8b\x5d\x08\x53\xe8\x1e\x00\x00\x00\x59\x59\x84\xc0\x75\x11\x8b\x45\x0c\x6a\x10\x59\x83\xc0\x0c\xf0\x09\x08\x83\xc8\xff\xeb\x03\x0f\xb6\xc3\x5b\x5f\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x57\xff\x75\x0c\xe8\x41\xbf\xff\xff\x59\x8b\x4d\x0c\x8b\xd0\x8b\x49\x0c\xf6\xc1\xc0\x0f\x84\x92\x00\x00\x00\x8b\x4d\x0c\x33\xff\x8b\x41\x04\x8b\x31\x2b\xf0\x40\x89\x01\x8b\x45\x0c\x8b\x48\x18\x49\x89\x48\x08\x85\xf6\x7e\x26\x8b\x45\x0c\x56\xff\x70\x04\x52\xe8\x22\xd9\xff\xff\x83\xc4\x0c\x8b\xf8\x8b\x45\x0c\x8b\x48\x04\x8a\x45\x08\x88\x01\x33\xc0\x3b\xfe\x0f\x94\xc0\xeb\x64\x83\xfa\xff\x74\x1b\x83\xfa\xfe\x74\x16\x8b\xc2\x8b\xca\x83\xe0\x3f\xc1\xf9\x06\x6b\xc0\x30\x03\x04\x8d\x08\x7d\x01\x10\xeb\x05\xb8\x38\x71\x01\x10\xf6\x40\x28\x20\x74\xc1\x6a\x02\x57\x57\x52\xe8\x66\x08\x00\x00\x23\xc2\x83\xc4\x10\x83\xf8\xff\x75\xad\x8b\x45\x0c\x6a\x10\x59\x83\xc0\x0c\xf0\x09\x08\xb0\x01\xeb\x15\x6a\x01\x8d\x45\x08\x50\x52\xe8\xae\xd8\xff\xff\x83\xc4\x0c\x48\xf7\xd8\x1b\xc0\x40\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x5d\xe9\x18\xfe\xff\xff\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x83\xf9\xfe\x75\x0d\xe8\x76\x9e\xff\xff\xc7\x00\x09\x00\x00\x00\xeb\x38\x85\xc9\x78\x24\x3b\x0d\x08\x7f\x01\x10\x73\x1c\x8b\xc1\x83\xe1\x3f\xc1\xf8\x06\x6b\xc9\x30\x8b\x04\x85\x08\x7d\x01\x10\x0f\xb6\x44\x08\x28\x83\xe0\x40\x5d\xc3\xe8\x41\x9e\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x7a\x9d\xff\xff\x33\xc0\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x0f\x84\xea\x00\x00\x00\x8b\x46\x0c\x3b\x05\x6c\x77\x01\x10\x74\x07\x50\xe8\xdc\x96\xff\xff\x59\x8b\x46\x10\x3b\x05\x70\x77\x01\x10\x74\x07\x50\xe8\xca\x96\xff\xff\x59\x8b\x46\x14\x3b\x05\x74\x77\x01\x10\x74\x07\x50\xe8\xb8\x96\xff\xff\x59\x8b\x46\x18\x3b\x05\x78\x77\x01\x10\x74\x07\x50\xe8\xa6\x96\xff\xff\x59\x8b\x46\x1c\x3b\x05\x7c\x77\x01\x10\x74\x07\x50\xe8\x94\x96\xff\xff\x59\x8b\x46\x20\x3b\x05\x80\x77\x01\x10\x74\x07\x50\xe8\x82\x96\xff\xff\x59\x8b\x46\x24\x3b\x05\x84\x77\x01\x10\x74\x07\x50\xe8\x70\x96\xff\xff\x59\x8b\x46\x38\x3b\x05\x98\x77\x01\x10\x74\x07\x50\xe8\x5e\x96\xff\xff\x59\x8b\x46\x3c\x3b\x05\x9c\x77\x01\x10\x74\x07\x50\xe8\x4c\x96\xff\xff\x59\x8b\x46\x40\x3b\x05\xa0\x77\x01\x10\x74\x07\x50\xe8\x3a\x96\xff\xff\x59\x8b\x46\x44\x3b\x05\xa4\x77\x01\x10\x74\x07\x50\xe8\x28\x96\xff\xff\x59\x8b\x46\x48\x3b\x05\xa8\x77\x01\x10\x74\x07\x50\xe8\x16\x96\xff\xff\x59\x8b\x46\x4c\x3b\x05\xac\x77\x01\x10\x74\x07\x50\xe8\x04\x96\xff\xff\x59\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x74\x59\x8b\x06\x3b\x05\x60\x77\x01\x10\x74\x07\x50\xe8\xe3\x95\xff\xff\x59\x8b\x46\x04\x3b\x05\x64\x77\x01\x10\x74\x07\x50\xe8\xd1\x95\xff\xff\x59\x8b\x46\x08\x3b\x05\x68\x77\x01\x10\x74\x07\x50\xe8\xbf\x95\xff\xff\x59\x8b\x46\x30\x3b\x05\x90\x77\x01\x10\x74\x07\x50\xe8\xad\x95\xff\xff\x59\x8b\x46\x34\x3b\x05\x94\x77\x01\x10\x74\x07\x50\xe8\x9b\x95\xff\xff\x59\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x0c\x53\x56\x8b\x75\x08\x57\x33\xff\x8d\x04\x86\x8b\xc8\x2b\xce\x83\xc1\x03\xc1\xe9\x02\x3b\xc6\x1b\xdb\xf7\xd3\x23\xd9\x74\x10\xff\x36\xe8\x69\x95\xff\xff\x47\x8d\x76\x04\x59\x3b\xfb\x75\xf0\x5f\x5e\x5b\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x8b\x75\x08\x85\xf6\x0f\x84\xd0\x00\x00\x00\x6a\x07\x56\xe8\xab\xff\xff\xff\x8d\x46\x1c\x6a\x07\x50\xe8\xa0\xff\xff\xff\x8d\x46\x38\x6a\x0c\x50\xe8\x95\xff\xff\xff\x8d\x46\x68\x6a\x0c\x50\xe8\x8a\xff\xff\xff\x8d\x86\x98\x00\x00\x00\x6a\x02\x50\xe8\x7c\xff\xff\xff\xff\xb6\xa0\x00\x00\x00\xe8\x08\x95\xff\xff\xff\xb6\xa4\x00\x00\x00\xe8\xfd\x94\xff\xff\xff\xb6\xa8\x00\x00\x00\xe8\xf2\x94\xff\xff\x8d\x86\xb4\x00\x00\x00\x6a\x07\x50\xe8\x4d\xff\xff\xff\x8d\x86\xd0\x00\x00\x00\x6a\x07\x50\xe8\x3f\xff\xff\xff\x83\xc4\x44\x8d\x86\xec\x00\x00\x00\x6a\x0c\x50\xe8\x2e\xff\xff\xff\x8d\x86\x1c\x01\x00\x00\x6a\x0c\x50\xe8\x20\xff\xff\xff\x8d\x86\x4c\x01\x00\x00\x6a\x02\x50\xe8\x12\xff\xff\xff\xff\xb6\x54\x01\x00\x00\xe8\x9e\x94\xff\xff\xff\xb6\x58\x01\x00\x00\xe8\x93\x94\xff\xff\xff\xb6\x5c\x01\x00\x00\xe8\x88\x94\xff\xff\xff\xb6\x60\x01\x00\x00\xe8\x7d\x94\xff\xff\x83\xc4\x28\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x18\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x53\x56\x57\xff\x75\x08\x8d\x4d\xe8\xe8\x29\x77\xff\xff\x8b\x4d\x1c\x85\xc9\x75\x0b\x8b\x45\xec\x8b\x40\x08\x8b\xc8\x89\x45\x1c\x33\xc0\x33\xff\x39\x45\x20\x57\x57\xff\x75\x14\x0f\x95\xc0\xff\x75\x10\x8d\x04\xc5\x01\x00\x00\x00\x50\x51\xff\x15\xc8\x00\x01\x10\x89\x45\xf8\x85\xc0\x0f\x84\x99\x00\x00\x00\x8d\x1c\x00\x8d\x4b\x08\x3b\xd9\x1b\xc0\x85\xc1\x74\x4a\x8d\x4b\x08\x3b\xd9\x1b\xc0\x23\xc1\x8d\x4b\x08\x3d\x00\x04\x00\x00\x77\x19\x3b\xd9\x1b\xc0\x23\xc1\xe8\x56\x2a\x00\x00\x8b\xf4\x85\xf6\x74\x60\xc7\x06\xcc\xcc\x00\x00\xeb\x19\x3b\xd9\x1b\xc0\x23\xc1\x50\xe8\x0d\x94\xff\xff\x8b\xf0\x59\x85\xf6\x74\x45\xc7\x06\xdd\xdd\x00\x00\x83\xc6\x08\xeb\x02\x8b\xf7\x85\xf6\x74\x34\x53\x57\x56\xe8\x7c\x68\xff\xff\x83\xc4\x0c\xff\x75\xf8\x56\xff\x75\x14\xff\x75\x10\x6a\x01\xff\x75\x1c\xff\x15\xc8\x00\x01\x10\x85\xc0\x74\x10\xff\x75\x18\x50\x56\xff\x75\x0c\xff\x15\x44\x00\x01\x10\x8b\xf8\x56\xe8\xe3\xdc\xff\xff\x59\x80\x7d\xf4\x00\x74\x0a\x8b\x45\xe8\x83\xa0\x50\x03\x00\x00\xfd\x8b\xc7\x8d\x65\xdc\x5f\x5e\x5b\x8b\x4d\xfc\x33\xcd\xe8\x6b\x58\xff\xff\x8b\xe5\x5d\xc3\xe8\xa3\xc1\xff\xff\x33\xc9\x84\xc0\x0f\x94\xc1\x8b\xc1\xc3\x8b\xff\x55\x8b\xec\x83\x7d\x08\x00\x75\x15\xe8\x6f\x9a\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\xa8\x99\xff\xff\x83\xc8\xff\x5d\xc3\xff\x75\x08\x6a\x00\xff\x35\x7c\x80\x01\x10\xff\x15\x2c\x00\x01\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x57\x8b\x7d\x08\x85\xff\x75\x0b\xff\x75\x0c\xe8\x3d\x93\xff\xff\x59\xeb\x24\x56\x8b\x75\x0c\x85\xf6\x75\x09\x57\xe8\xf2\x92\xff\xff\x59\xeb\x10\x83\xfe\xe0\x76\x25\xe8\x19\x9a\xff\xff\xc7\x00\x0c\x00\x00\x00\x33\xc0\x5e\x5f\x5d\xc3\xe8\x7b\xca\xff\xff\x85\xc0\x74\xe6\x56\xe8\x16\xc6\xff\xff\x59\x85\xc0\x74\xdb\x56\x57\x6a\x00\xff\x35\x7c\x80\x01\x10\xff\x15\x28\x00\x01\x10\x85\xc0\x74\xd8\xeb\xd2\x6a\x0c\x68\x08\x5e\x01\x10\xe8\x9c\x61\xff\xff\x83\x65\xe4\x00\x8b\x45\x08\xff\x30\xe8\x15\xd8\xff\xff\x59\x83\x65\xfc\x00\x8b\x45\x0c\x8b\x00\x8b\x30\x8b\xd6\xc1\xfa\x06\x8b\xc6\x83\xe0\x3f\x6b\xc8\x30\x8b\x04\x95\x08\x7d\x01\x10\xf6\x44\x08\x28\x01\x74\x0b\x56\xe8\xe2\x00\x00\x00\x59\x8b\xf0\xeb\x0e\xe8\x92\x99\xff\xff\xc7\x00\x09\x00\x00\x00\x83\xce\xff\x89\x75\xe4\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0d\x00\x00\x00\x8b\xc6\xe8\x7e\x61\xff\xff\xc2\x0c\x00\x8b\x75\xe4\x8b\x45\x10\xff\x30\xe8\xd2\xd7\xff\xff\x59\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\x8b\x45\x08\x8d\x4d\xff\x89\x45\xf8\x89\x45\xf4\x8d\x45\xf8\x50\xff\x75\x0c\x8d\x45\xf4\x50\xe8\x5a\xff\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x56\x8b\x75\x08\x83\xfe\xfe\x75\x15\xe8\x12\x99\xff\xff\x83\x20\x00\xe8\x1d\x99\xff\xff\xc7\x00\x09\x00\x00\x00\xeb\x53\x85\xf6\x78\x37\x3b\x35\x08\x7f\x01\x10\x73\x2f\x8b\xc6\x8b\xd6\x83\xe0\x3f\xc1\xfa\x06\x6b\xc8\x30\x8b\x04\x95\x08\x7d\x01\x10\xf6\x44\x08\x28\x01\x74\x14\x8d\x45\x08\x89\x45\xfc\x8d\x45\xfc\x50\x56\xe8\x7d\xff\xff\xff\x59\x59\xeb\x1b\xe8\xc2\x98\xff\xff\x83\x20\x00\xe8\xcd\x98\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x06\x98\xff\xff\x83\xc8\xff\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x56\x57\x8b\x7d\x08\x57\xe8\xcd\xd7\xff\xff\x59\x83\xf8\xff\x75\x04\x33\xf6\xeb\x4e\xa1\x08\x7d\x01\x10\x83\xff\x01\x75\x09\xf6\x80\x88\x00\x00\x00\x01\x75\x0b\x83\xff\x02\x75\x1c\xf6\x40\x58\x01\x74\x16\x6a\x02\xe8\x9e\xd7\xff\xff\x6a\x01\x8b\xf0\xe8\x95\xd7\xff\xff\x59\x59\x3b\xc6\x74\xc8\x57\xe8\x89\xd7\xff\xff\x59\x50\xff\x15\x24\x00\x01\x10\x85\xc0\x75\xb6\xff\x15\xfc\x00\x01\x10\x8b\xf0\x57\xe8\xde\xd6\xff\xff\x59\x8b\xcf\x83\xe7\x3f\xc1\xf9\x06\x6b\xd7\x30\x8b\x0c\x8d\x08\x7d\x01\x10\xc6\x44\x11\x28\x00\x85\xf6\x74\x0c\x56\xe8\xf4\x97\xff\xff\x59\x83\xc8\xff\xeb\x02\x33\xc0\x5f\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x33\xc9\x89\x08\x8b\x45\x08\x89\x48\x04\x8b\x45\x08\x89\x48\x08\x8b\x45\x08\x83\x48\x10\xff\x8b\x45\x08\x89\x48\x14\x8b\x45\x08\x89\x48\x18\x8b\x45\x08\x89\x48\x1c\x8b\x45\x08\x83\xc0\x0c\x87\x08\x5d\xc3\x6a\x1c\x68\x28\x5e\x01\x10\xe8\x9c\x5f\xff\xff\x8b\x7d\x08\x83\xff\xfe\x75\x18\xe8\xb7\x97\xff\xff\x83\x20\x00\xe8\xc2\x97\xff\xff\xc7\x00\x09\x00\x00\x00\xe9\xcc\x00\x00\x00\x85\xff\x0f\x88\xac\x00\x00\x00\x3b\x3d\x08\x7f\x01\x10\x0f\x83\xa0\x00\x00\x00\x8b\xcf\xc1\xf9\x06\x89\x4d\xe4\x8b\xc7\x83\xe0\x3f\x6b\xd0\x30\x89\x55\xe0\x8b\x04\x8d\x08\x7d\x01\x10\x0f\xb6\x44\x10\x28\x83\xe0\x01\x74\x7c\x57\xe8\xc5\xd5\xff\xff\x59\x83\xce\xff\x89\x75\xd4\x8b\xde\x89\x5d\xd8\x83\x65\xfc\x00\x8b\x45\xe4\x8b\x04\x85\x08\x7d\x01\x10\x8b\x4d\xe0\xf6\x44\x08\x28\x01\x75\x15\xe8\x50\x97\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x32\x97\xff\xff\x83\x20\x00\xeb\x1c\xff\x75\x14\xff\x75\x10\xff\x75\x0c\x57\xe8\x53\x00\x00\x00\x83\xc4\x10\x8b\xf0\x89\x75\xd4\x8b\xda\x89\x5d\xd8\xc7\x45\xfc\xfe\xff\xff\xff\xe8\x0d\x00\x00\x00\x8b\xd3\xeb\x2e\x8b\x7d\x08\x8b\x5d\xd8\x8b\x75\xd4\x57\xe8\x74\xd5\xff\xff\x59\xc3\xe8\xeb\x96\xff\xff\x83\x20\x00\xe8\xf6\x96\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x2f\x96\xff\xff\x83\xce\xff\x8b\xd6\x8b\xc6\xe8\xea\x5e\xff\xff\xc3\x8b\xff\x55\x8b\xec\x51\x51\x56\x8b\x75\x08\x57\x56\xe8\xef\xd5\xff\xff\x83\xcf\xff\x59\x3b\xc7\x75\x11\xe8\xbf\x96\xff\xff\xc7\x00\x09\x00\x00\x00\x8b\xc7\x8b\xd7\xeb\x4d\xff\x75\x14\x8d\x4d\xf8\x51\xff\x75\x10\xff\x75\x0c\x50\xff\x15\x20\x00\x01\x10\x85\xc0\x75\x0f\xff\x15\xfc\x00\x01\x10\x50\xe8\x59\x96\xff\xff\x59\xeb\xd3\x8b\x45\xf8\x8b\x55\xfc\x23\xc2\x3b\xc7\x74\xc7\x8b\x45\xf8\x8b\xce\x83\xe6\x3f\xc1\xf9\x06\x6b\xf6\x30\x8b\x0c\x8d\x08\x7d\x01\x10\x80\x64\x31\x28\xfd\x5f\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\x67\xfe\xff\xff\x83\xc4\x10\x5d\xc3\x8b\xff\x55\x8b\xec\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\x51\xff\xff\xff\x83\xc4\x10\x5d\xc3\x8b\xff\x55\x8b\xec\x51\xa1\xb0\x77\x01\x10\x83\xf8\xfe\x75\x0a\xe8\xd4\x03\x00\x00\xa1\xb0\x77\x01\x10\x83\xf8\xff\x75\x07\xb8\xff\xff\x00\x00\xeb\x1b\x6a\x00\x8d\x4d\xfc\x51\x6a\x01\x8d\x4d\x08\x51\x50\xff\x15\x1c\x00\x01\x10\x85\xc0\x74\xe2\x66\x8b\x45\x08\x8b\xe5\x5d\xc3\xa1\xb4\x80\x01\x10\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x33\xc0\x38\x01\x74\x0c\x3b\x45\x0c\x74\x07\x40\x80\x3c\x08\x00\x75\xf4\x5d\xc3\x8b\xff\x55\x8b\xec\x56\xe8\x50\x06\x00\x00\x8b\x75\x08\x89\x06\xe8\x89\x06\x00\x00\x89\x46\x04\x33\xc0\x5e\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x83\x65\xf8\x00\x83\x65\xfc\x00\x56\x8b\x75\x08\xff\x36\xe8\x0f\x07\x00\x00\xff\x76\x04\xe8\x87\x07\x00\x00\x8d\x45\xf8\x50\xe8\xb8\xff\xff\xff\x8b\x06\x83\xc4\x0c\x3b\x45\xf8\x75\x0c\x8b\x46\x04\x3b\x45\xfc\x75\x04\x33\xc0\xeb\x03\x33\xc0\x40\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x83\x65\xf8\x00\x8d\x45\xf8\x83\x65\xfc\x00\x50\xe8\x82\xff\xff\xff\x59\x85\xc0\x74\x05\x33\xc0\x40\xeb\x29\x8b\x4d\x08\x8b\x55\xf8\x8b\x45\xfc\x89\x41\x04\x8d\x45\xf8\x89\x11\x83\xca\x1f\x50\x89\x55\xf8\xe8\x78\xff\xff\xff\x59\x85\xc0\x75\xd9\xe8\x97\x07\x00\x00\x33\xc0\x8b\xe5\x5d\xc3\xcc\xcc\xcc\x83\x3d\xa8\x84\x01\x10\x00\x0f\x84\x82\x00\x00\x00\x83\xec\x08\x0f\xae\x5c\x24\x04\x8b\x44\x24\x04\x25\x80\x7f\x00\x00\x3d\x80\x1f\x00\x00\x75\x0f\xd9\x3c\x24\x66\x8b\x04\x24\x66\x83\xe0\x7f\x66\x83\xf8\x7f\x8d\x64\x24\x08\x75\x55\xe9\x59\x08\x00\x00\x90\x83\x3d\xa8\x84\x01\x10\x00\x74\x32\x83\xec\x08\x0f\xae\x5c\x24\x04\x8b\x44\x24\x04\x25\x80\x7f\x00\x00\x3d\x80\x1f\x00\x00\x75\x0f\xd9\x3c\x24\x66\x8b\x04\x24\x66\x83\xe0\x7f\x66\x83\xf8\x7f\x8d\x64\x24\x08\x75\x05\xe9\x05\x08\x00\x00\x83\xec\x0c\xdd\x14\x24\xe8\x12\x0f\x00\x00\xe8\x0d\x00\x00\x00\x83\xc4\x0c\xc3\x8d\x54\x24\x04\xe8\xbd\x0e\x00\x00\x52\x9b\xd9\x3c\x24\x74\x4c\x8b\x44\x24\x0c\x66\x81\x3c\x24\x7f\x02\x74\x06\xd9\x2d\xb8\x4a\x01\x10\xa9\x00\x00\xf0\x7f\x74\x5e\xa9\x00\x00\x00\x80\x75\x41\xd9\xec\xd9\xc9\xd9\xf1\x83\x3d\xb8\x80\x01\x10\x00\x0f\x85\xdc\x0e\x00\x00\x8d\x0d\xa0\x48\x01\x10\xba\x1b\x00\x00\x00\xe9\xd9\x0e\x00\x00\xa9\x00\x00\x00\x80\x75\x17\xeb\xd4\xa9\xff\xff\x0f\x00\x75\x1d\x83\x7c\x24\x08\x00\x75\x16\x25\x00\x00\x00\x80\x74\xc5\xdd\xd8\xdb\x2d\x70\x4a\x01\x10\xb8\x01\x00\x00\x00\xeb\x22\xe8\x28\x0e\x00\x00\xeb\x1b\xa9\xff\xff\x0f\x00\x75\xc5\x83\x7c\x24\x08\x00\x75\xbe\xdd\xd8\xdb\x2d\x1a\x4a\x01\x10\xb8\x02\x00\x00\x00\x83\x3d\xb8\x80\x01\x10\x00\x0f\x85\x70\x0e\x00\x00\x8d\x0d\xa0\x48\x01\x10\xba\x1b\x00\x00\x00\xe8\x69\x0f\x00\x00\x5a\xc3\x83\x3d\xa8\x84\x01\x10\x00\x0f\x84\xae\x11\x00\x00\x83\xec\x08\x0f\xae\x5c\x24\x04\x8b\x44\x24\x04\x25\x80\x7f\x00\x00\x3d\x80\x1f\x00\x00\x75\x0f\xd9\x3c\x24\x66\x8b\x04\x24\x66\x83\xe0\x7f\x66\x83\xf8\x7f\x8d\x64\x24\x08\x0f\x85\x7d\x11\x00\x00\xeb\x00\xf3\x0f\x7e\x44\x24\x04\x66\x0f\x28\x15\xc0\x48\x01\x10\x66\x0f\x28\xc8\x66\x0f\x28\xf8\x66\x0f\x73\xd0\x34\x66\x0f\x7e\xc0\x66\x0f\x54\x05\xe0\x48\x01\x10\x66\x0f\xfa\xd0\x66\x0f\xd3\xca\xa9\x00\x08\x00\x00\x74\x4c\x3d\xff\x0b\x00\x00\x7c\x7d\x66\x0f\xf3\xca\x3d\x32\x0c\x00\x00\x7f\x0b\x66\x0f\xd6\x4c\x24\x04\xdd\x44\x24\x04\xc3\x66\x0f\x2e\xff\x7b\x24\xba\xec\x03\x00\x00\x83\xec\x10\x89\x54\x24\x0c\x8b\xd4\x83\xc2\x14\x89\x54\x24\x08\x89\x54\x24\x04\x89\x14\x24\xe8\xe9\x0e\x00\x00\x83\xc4\x10\xdd\x44\x24\x04\xc3\xf3\x0f\x7e\x44\x24\x04\x66\x0f\xf3\xca\x66\x0f\x28\xd8\x66\x0f\xc2\xc1\x06\x3d\xff\x03\x00\x00\x7c\x25\x3d\x32\x04\x00\x00\x7f\xb0\x66\x0f\x54\x05\xb0\x48\x01\x10\xf2\x0f\x58\xc8\x66\x0f\xd6\x4c\x24\x04\xdd\x44\x24\x04\xc3\xdd\x05\xf0\x48\x01\x10\xc3\x66\x0f\xc2\x1d\xd0\x48\x01\x10\x06\x66\x0f\x54\x1d\xb0\x48\x01\x10\x66\x0f\xd6\x5c\x24\x04\xdd\x44\x24\x04\xc3\x8b\xff\x55\x8b\xec\xff\x05\xf4\x7b\x01\x10\x53\x56\x8b\x75\x08\xbb\x00\x10\x00\x00\x53\xe8\x89\x8b\xff\xff\x6a\x00\x89\x46\x04\xe8\x45\x8b\xff\xff\x83\x7e\x04\x00\x8d\x46\x0c\x59\x59\x74\x0b\x6a\x40\x59\xf0\x09\x08\x89\x5e\x18\xeb\x15\xb9\x00\x04\x00\x00\xf0\x09\x08\x8d\x46\x14\xc7\x46\x18\x02\x00\x00\x00\x89\x46\x04\x8b\x46\x04\x83\x66\x08\x00\x89\x06\x5e\x5b\x5d\xc3\x33\xc0\x50\x50\x6a\x03\x50\x6a\x03\x68\x00\x00\x00\x40\x68\xf8\x48\x01\x10\xff\x15\x18\x00\x01\x10\xa3\xb0\x77\x01\x10\xc3\xa1\xb0\x77\x01\x10\x83\xf8\xff\x74\x0c\x83\xf8\xfe\x74\x07\x50\xff\x15\x24\x00\x01\x10\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x33\xc9\xf7\xc2\x80\x7e\x00\x00\x74\x67\x84\xd2\x79\x03\x6a\x10\x59\x57\xbf\x00\x02\x00\x00\x85\xd7\x74\x03\x83\xc9\x08\xf7\xc2\x00\x04\x00\x00\x74\x03\x83\xc9\x04\xf7\xc2\x00\x08\x00\x00\x74\x03\x83\xc9\x02\xf7\xc2\x00\x10\x00\x00\x74\x03\x83\xc9\x01\x56\xbe\x00\x60\x00\x00\x8b\xc2\x23\xc6\x3b\xc6\x5e\x75\x08\x81\xc9\x00\x03\x00\x00\xeb\x1a\xf7\xc2\x00\x40\x00\x00\x74\x08\x81\xc9\x00\x01\x00\x00\xeb\x0a\xf7\xc2\x00\x20\x00\x00\x74\x02\x0b\xcf\x5f\x8b\xc1\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x33\xc9\xf7\xc2\x3d\x0c\x00\x00\x74\x5d\xf6\xc2\x01\x74\x03\x6a\x10\x59\xf6\xc2\x04\x74\x03\x83\xc9\x08\xf6\xc2\x08\x74\x03\x83\xc9\x04\xf6\xc2\x10\x74\x03\x83\xc9\x02\xf6\xc2\x20\x74\x03\x83\xc9\x01\x56\xbe\x00\x0c\x00\x00\x8b\xc2\x23\xc6\x3b\xc6\x5e\x75\x08\x81\xc9\x00\x03\x00\x00\xeb\x1e\xf7\xc2\x00\x08\x00\x00\x74\x08\x81\xc9\x00\x01\x00\x00\xeb\x0e\xf7\xc2\x00\x04\x00\x00\x74\x06\x81\xc9\x00\x02\x00\x00\x8b\xc1\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x33\xc9\xf7\xc2\x1f\x03\x00\x00\x74\x5b\xf6\xc2\x10\x74\x01\x41\xf6\xc2\x08\x74\x03\x83\xc9\x04\xf6\xc2\x04\x74\x03\x83\xc9\x08\xf6\xc2\x02\x74\x03\x83\xc9\x10\xf6\xc2\x01\x74\x03\x83\xc9\x20\x56\xbe\x00\x03\x00\x00\x8b\xc2\x23\xc6\x3b\xc6\x5e\x75\x08\x81\xc9\x00\x0c\x00\x00\xeb\x1e\xf7\xc2\x00\x02\x00\x00\x74\x08\x81\xc9\x00\x04\x00\x00\xeb\x0e\xf7\xc2\x00\x01\x00\x00\x74\x06\x81\xc9\x00\x08\x00\x00\x8b\xc1\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x33\xc9\xf7\xc2\x1f\x03\x00\x00\x74\x6a\xf6\xc2\x10\x74\x05\xb9\x80\x00\x00\x00\x57\xbf\x00\x02\x00\x00\xf6\xc2\x08\x74\x02\x0b\xcf\xf6\xc2\x04\x74\x06\x81\xc9\x00\x04\x00\x00\xf6\xc2\x02\x74\x06\x81\xc9\x00\x08\x00\x00\xf6\xc2\x01\x74\x06\x81\xc9\x00\x10\x00\x00\x56\xbe\x00\x03\x00\x00\x8b\xc2\x23\xc6\x3b\xc6\x5e\x75\x08\x81\xc9\x00\x60\x00\x00\xeb\x1a\x85\xd7\x74\x08\x81\xc9\x00\x20\x00\x00\xeb\x0e\xf7\xc2\x00\x01\x00\x00\x74\x06\x81\xc9\x00\x40\x00\x00\x5f\x8b\xc1\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x33\xc9\xf6\xc2\x1f\x74\x4e\x56\xbe\x10\x00\x00\x10\x8b\xc2\x23\xc6\x3b\xc6\x75\x01\x41\xbe\x08\x00\x00\x08\x8b\xc2\x23\xc6\x3b\xc6\x75\x03\x83\xc9\x04\xbe\x04\x00\x00\x04\x8b\xc2\x23\xc6\x3b\xc6\x75\x03\x83\xc9\x08\xbe\x02\x00\x00\x02\x8b\xc2\x23\xc6\x3b\xc6\x5e\x75\x03\x83\xc9\x10\xb8\x01\x00\x00\x01\x23\xd0\x3b\xd0\x75\x03\x83\xc9\x20\x8b\xc1\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x08\x33\xc9\xf6\xc2\x1f\x74\x4e\x56\xbe\x10\x00\x10\x00\x8b\xc2\x23\xc6\x3b\xc6\x75\x01\x41\xbe\x08\x00\x08\x00\x8b\xc2\x23\xc6\x3b\xc6\x75\x03\x83\xc9\x04\xbe\x04\x00\x04\x00\x8b\xc2\x23\xc6\x3b\xc6\x75\x03\x83\xc9\x08\xbe\x02\x00\x02\x00\x8b\xc2\x23\xc6\x3b\xc6\x5e\x75\x03\x83\xc9\x10\xb8\x01\x00\x01\x00\x23\xd0\x3b\xd0\x75\x03\x83\xc9\x20\x8b\xc1\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x33\xc0\x21\x45\xf8\x66\x89\x45\xfc\xd9\x7d\xfc\x83\x3d\x2c\x7b\x01\x10\x01\x7c\x04\x0f\xae\x5d\xf8\x0f\xb7\x45\xfc\x56\x50\xe8\xaf\xfd\xff\xff\xff\x75\xf8\x8b\xf0\xe8\x28\xfd\xff\xff\x59\x0b\xc6\x59\x25\x1f\x03\x00\x00\x5e\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x33\xc0\x33\xc9\x66\x89\x45\xfc\x89\x4d\xf8\xdd\x7d\xfc\x83\x3d\x2c\x7b\x01\x10\x01\x7c\x04\x0f\xae\x5d\xf8\x0f\xb7\x55\xfc\x8b\xc1\xf6\xc2\x3d\x74\x32\xf6\xc2\x01\x74\x05\xb8\x10\x00\x10\x00\xf6\xc2\x04\x74\x05\x0d\x08\x00\x08\x00\xf6\xc2\x08\x74\x05\x0d\x04\x00\x04\x00\xf6\xc2\x10\x74\x05\x0d\x02\x00\x02\x00\xf6\xc2\x20\x74\x05\x0d\x01\x00\x01\x00\x8b\x55\xf8\xf6\xc2\x3d\x74\x36\xf6\xc2\x01\x74\x05\xb9\x10\x00\x00\x10\xf6\xc2\x04\x74\x06\x81\xc9\x08\x00\x00\x08\xf6\xc2\x08\x74\x06\x81\xc9\x04\x00\x00\x04\xf6\xc2\x10\x74\x06\x81\xc9\x02\x00\x00\x02\xf6\xc2\x20\x74\x06\x81\xc9\x01\x00\x00\x01\x0b\xc1\x25\x1f\x00\x1f\x1f\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x20\x53\x56\x57\x33\xff\x89\x7d\xe0\x89\x7d\xe4\x89\x7d\xe8\x89\x7d\xec\x89\x7d\xf0\x89\x7d\xf4\x89\x7d\xf8\xd9\x75\xe0\xbb\x1f\x03\x00\x00\x53\xe8\x32\xfd\xff\xff\xff\x75\x08\x8b\xf0\xf7\xd6\x23\x75\xe0\xe8\x23\xfd\xff\xff\x59\x0b\xf0\x59\x89\x75\xe0\xd9\x65\xe0\x83\x3d\x2c\x7b\x01\x10\x01\x7c\x27\x89\x7d\xfc\x0f\xae\x5d\xfc\x53\xe8\x74\xfd\xff\xff\xff\x75\x08\x8b\xf0\xf7\xd6\x23\x75\xfc\xe8\x65\xfd\xff\xff\x59\x0b\xf0\x59\x89\x75\xfc\x0f\xae\x55\xfc\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x20\x53\x56\x57\x33\xff\x89\x7d\xe0\x89\x7d\xe4\x89\x7d\xe8\x89\x7d\xec\x89\x7d\xf0\x89\x7d\xf4\x89\x7d\xf8\xd9\x75\xe0\xbb\x1f\x00\x1f\x1f\x53\xe8\x04\xfe\xff\xff\xff\x75\x08\x8b\xf0\xf7\xd6\x23\x75\xe4\xe8\xf5\xfd\xff\xff\x59\x0b\xf0\x59\x89\x75\xe4\xd9\x65\xe0\x83\x3d\x2c\x7b\x01\x10\x01\x7c\x27\x89\x7d\xfc\x0f\xae\x5d\xfc\x53\xe8\x74\xfd\xff\xff\xff\x75\x08\x8b\xf0\xf7\xd6\x23\x75\xfc\xe8\x65\xfd\xff\xff\x59\x0b\xf0\x59\x89\x75\xfc\x0f\xae\x55\xfc\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x83\xec\x0c\xdd\x7d\xfc\xdb\xe2\x83\x3d\x2c\x7b\x01\x10\x01\x0f\x8c\x83\x00\x00\x00\x66\x8b\x45\xfc\x33\xc9\x8b\xd1\x57\xbf\x00\x00\x08\x00\xa8\x3f\x74\x29\xa8\x01\x74\x03\x6a\x10\x5a\xa8\x04\x74\x03\x83\xca\x08\xa8\x08\x74\x03\x83\xca\x04\xa8\x10\x74\x03\x83\xca\x02\xa8\x20\x74\x03\x83\xca\x01\xa8\x02\x74\x02\x0b\xd7\x0f\xae\x5d\xf8\x8b\x45\xf8\x83\xe0\xc0\x89\x45\xf4\x0f\xae\x55\xf4\x8b\x45\xf8\xa8\x3f\x74\x29\xa8\x01\x74\x03\x6a\x10\x59\xa8\x04\x74\x03\x83\xc9\x08\xa8\x08\x74\x03\x83\xc9\x04\xa8\x10\x74\x03\x83\xc9\x02\xa8\x20\x74\x03\x83\xc9\x01\xa8\x02\x74\x02\x0b\xcf\x0b\xca\x8b\xc1\x5f\xeb\x3d\x66\x8b\x4d\xfc\x33\xc0\xf6\xc1\x3f\x74\x32\xf6\xc1\x01\x74\x03\x6a\x10\x58\xf6\xc1\x04\x74\x03\x83\xc8\x08\xf6\xc1\x08\x74\x03\x83\xc8\x04\xf6\xc1\x10\x74\x03\x83\xc8\x02\xf6\xc1\x20\x74\x03\x83\xc8\x01\xf6\xc1\x02\x74\x05\x0d\x00\x00\x08\x00\x8b\xe5\x5d\xc3\x6a\x0a\xe8\xed\x17\x00\x00\xa3\xa8\x84\x01\x10\x33\xc0\xc3\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x83\xec\x08\x83\xe4\xf0\xdd\x1c\x24\xf3\x0f\x7e\x04\x24\xe8\x08\x00\x00\x00\xc9\xc3\x66\x0f\x12\x44\x24\x04\xba\x00\x00\x00\x00\x66\x0f\x28\xe8\x66\x0f\x14\xc0\x66\x0f\x73\xd5\x34\x66\x0f\xc5\xcd\x00\x66\x0f\x28\x0d\x10\x49\x01\x10\x66\x0f\x28\x15\x20\x49\x01\x10\x66\x0f\x28\x1d\x80\x49\x01\x10\x66\x0f\x28\x25\x30\x49\x01\x10\x66\x0f\x28\x35\x40\x49\x01\x10\x66\x0f\x54\xc1\x66\x0f\x56\xc3\x66\x0f\x58\xe0\x66\x0f\xc5\xc4\x00\x25\xf0\x07\x00\x00\x66\x0f\x28\xa0\x50\x4f\x01\x10\x66\x0f\x28\xb8\x40\x4b\x01\x10\x66\x0f\x54\xf0\x66\x0f\x5c\xc6\x66\x0f\x59\xf4\x66\x0f\x5c\xf2\xf2\x0f\x58\xfe\x66\x0f\x59\xc4\x66\x0f\x28\xe0\x66\x0f\x58\xc6\x81\xe1\xff\x0f\x00\x00\x83\xe9\x01\x81\xf9\xfd\x07\x00\x00\x0f\x87\xbe\x00\x00\x00\x81\xe9\xfe\x03\x00\x00\x03\xca\xf2\x0f\x2a\xf1\x66\x0f\x14\xf6\xc1\xe1\x0a\x03\xc1\xb9\x10\x00\x00\x00\xba\x00\x00\x00\x00\x83\xf8\x00\x0f\x44\xd1\x66\x0f\x28\x0d\xd0\x49\x01\x10\x66\x0f\x28\xd8\x66\x0f\x28\x15\xe0\x49\x01\x10\x66\x0f\x59\xc8\x66\x0f\x59\xdb\x66\x0f\x58\xca\x66\x0f\x28\x15\xf0\x49\x01\x10\xf2\x0f\x59\xdb\x66\x0f\x28\x2d\x50\x49\x01\x10\x66\x0f\x59\xf5\x66\x0f\x28\xaa\x60\x49\x01\x10\x66\x0f\x54\xe5\x66\x0f\x58\xfe\x66\x0f\x58\xfc\x66\x0f\x59\xc8\xf2\x0f\x59\xd8\x66\x0f\x58\xca\x66\x0f\x28\x15\x00\x4a\x01\x10\x66\x0f\x59\xd0\x66\x0f\x28\xf7\x66\x0f\x15\xf6\x66\x0f\x59\xcb\x83\xec\x10\x66\x0f\x28\xc1\x66\x0f\x58\xca\x66\x0f\x15\xc0\xf2\x0f\x58\xc1\xf2\x0f\x58\xc6\xf2\x0f\x58\xc7\x66\x0f\x13\x44\x24\x04\xdd\x44\x24\x04\x83\xc4\x10\xc3\x66\x0f\x12\x44\x24\x04\x66\x0f\x28\x0d\x90\x49\x01\x10\xf2\x0f\xc2\xc8\x00\x66\x0f\xc5\xc1\x00\x83\xf8\x00\x77\x48\x83\xf9\xff\x74\x5e\x81\xf9\xfe\x07\x00\x00\x77\x6c\x66\x0f\x12\x44\x24\x04\x66\x0f\x28\x0d\x10\x49\x01\x10\x66\x0f\x28\x15\x80\x49\x01\x10\x66\x0f\x54\xc1\x66\x0f\x56\xc2\xf2\x0f\xc2\xd0\x00\x66\x0f\xc5\xc2\x00\x83\xf8\x00\x74\x07\xdd\x05\xb8\x49\x01\x10\xc3\xba\xe9\x03\x00\x00\xeb\x4f\x66\x0f\x12\x15\x80\x49\x01\x10\xf2\x0f\x5e\xd0\x66\x0f\x12\x0d\xb0\x49\x01\x10\xba\x08\x00\x00\x00\xeb\x34\x66\x0f\x12\x0d\xa0\x49\x01\x10\xf2\x0f\x59\xc1\xba\xcc\xff\xff\xff\xe9\x17\xfe\xff\xff\x83\xc1\x01\x81\xe1\xff\x07\x00\x00\x81\xf9\xff\x07\x00\x00\x73\x3a\x66\x0f\x57\xc9\xf2\x0f\x5e\xc9\xba\x09\x00\x00\x00\x83\xec\x1c\x66\x0f\x13\x4c\x24\x10\x89\x54\x24\x0c\x8b\xd4\x83\xc2\x10\x89\x54\x24\x08\x83\xc2\x10\x89\x54\x24\x04\x89\x14\x24\xe8\x24\x06\x00\x00\xdd\x44\x24\x10\x83\xc4\x1c\xc3\x66\x0f\x12\x54\x24\x04\x66\x0f\x12\x44\x24\x04\x66\x0f\x7e\xd0\x66\x0f\x73\xd2\x20\x66\x0f\x7e\xd1\x81\xe1\xff\xff\x0f\x00\x0b\xc1\x83\xf8\x00\x74\xa0\xba\xe9\x03\x00\x00\xeb\xa6\x8d\xa4\x24\x00\x00\x00\x00\xeb\x03\xcc\xcc\xcc\xc6\x85\x70\xff\xff\xff\xfe\x0a\xed\x75\x3b\xd9\xc9\xd9\xf1\xeb\x0d\xc6\x85\x70\xff\xff\xff\xfe\x32\xed\xd9\xea\xde\xc9\xe8\x2b\x01\x00\x00\xd9\xe8\xde\xc1\xf6\x85\x61\xff\xff\xff\x01\x74\x04\xd9\xe8\xde\xf1\xf6\xc2\x40\x75\x02\xd9\xfd\x0a\xed\x74\x02\xd9\xe0\xe9\xb2\x02\x00\x00\xe8\x46\x01\x00\x00\x0b\xc0\x74\x14\x32\xed\x83\xf8\x02\x74\x02\xf6\xd5\xd9\xc9\xd9\xe1\xeb\xaf\xe9\xb5\x02\x00\x00\xe9\x4b\x03\x00\x00\xdd\xd8\xdd\xd8\xdb\x2d\x10\x4a\x01\x10\xc6\x85\x70\xff\xff\xff\x02\xc3\xd9\xed\xd9\xc9\xd9\xe4\x9b\xdd\xbd\x60\xff\xff\xff\x9b\xf6\x85\x61\xff\xff\xff\x41\x75\xd2\xd9\xf1\xc3\xc6\x85\x70\xff\xff\xff\x02\xdd\xd8\xdb\x2d\x1a\x4a\x01\x10\xc3\x0a\xc9\x75\x53\xc3\xd9\xec\xeb\x02\xd9\xed\xd9\xc9\x0a\xc9\x75\xae\xd9\xf1\xc3\xe9\x5b\x02\x00\x00\xe8\xcf\x00\x00\x00\xdd\xd8\xdd\xd8\x0a\xc9\x75\x0e\xd9\xee\x83\xf8\x01\x75\x06\x0a\xed\x74\x02\xd9\xe0\xc3\xc6\x85\x70\xff\xff\xff\x02\xdb\x2d\x10\x4a\x01\x10\x83\xf8\x01\x75\xed\x0a\xed\x74\xe9\xd9\xe0\xeb\xe5\xdd\xd8\xe9\x0d\x02\x00\x00\xdd\xd8\xe9\xb5\x02\x00\x00\x58\xd9\xe4\x9b\xdd\xbd\x60\xff\xff\xff\x9b\xf6\x85\x61\xff\xff\xff\x01\x75\x0f\xdd\xd8\xdb\x2d\x10\x4a\x01\x10\x0a\xed\x74\x02\xd9\xe0\xc3\xc6\x85\x70\xff\xff\xff\x04\xe9\xd7\x01\x00\x00\xdd\xd8\xdd\xd8\xdb\x2d\x10\x4a\x01\x10\xc6\x85\x70\xff\xff\xff\x03\xc3\x0a\xc9\x75\xaf\xdd\xd8\xdb\x2d\x10\x4a\x01\x10\xc3\xd9\xc0\xd9\xe1\xdb\x2d\x2e\x4a\x01\x10\xde\xd9\x9b\xdd\xbd\x60\xff\xff\xff\x9b\xf6\x85\x61\xff\xff\xff\x41\x75\x95\xd9\xc0\xd9\xfc\xd9\xe4\x9b\xdd\xbd\x60\xff\xff\xff\x9b\x8a\x95\x61\xff\xff\xff\xd9\xc9\xd8\xe1\xd9\xe4\x9b\xdd\xbd\x60\xff\xff\xff\xd9\xe1\xd9\xf0\xc3\xd9\xc0\xd9\xfc\xd8\xd9\x9b\xdf\xe0\x9e\x75\x1a\xd9\xc0\xdc\x0d\x42\x4a\x01\x10\xd9\xc0\xd9\xfc\xde\xd9\x9b\xdf\xe0\x9e\x74\x0d\xb8\x01\x00\x00\x00\xc3\xb8\x00\x00\x00\x00\xeb\xf8\xb8\x02\x00\x00\x00\xeb\xf1\x56\x83\xec\x74\x8b\xf4\x56\x83\xec\x08\xdd\x1c\x24\x83\xec\x08\xdd\x1c\x24\x9b\xdd\x76\x08\xe8\x56\x08\x00\x00\x83\xc4\x14\xdd\x66\x08\xdd\x06\x83\xc4\x74\x5e\x85\xc0\x74\x05\xe9\xd0\x01\x00\x00\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x80\x7a\x0e\x05\x75\x11\x66\x8b\x9d\x5c\xff\xff\xff\x80\xcf\x02\x80\xe7\xfe\xb3\x3f\xeb\x04\x66\xbb\x3f\x13\x66\x89\x9d\x5e\xff\xff\xff\xd9\xad\x5e\xff\xff\xff\xbb\x9e\x4a\x01\x10\xd9\xe5\x89\x95\x6c\xff\xff\xff\x9b\xdd\xbd\x60\xff\xff\xff\xc6\x85\x70\xff\xff\xff\x00\x9b\x8a\x8d\x61\xff\xff\xff\xd0\xe1\xd0\xf9\xd0\xc1\x8a\xc1\x24\x0f\xd7\x0f\xbe\xc0\x81\xe1\x04\x04\x00\x00\x8b\xda\x03\xd8\x83\xc3\x10\xff\x23\x80\x7a\x0e\x05\x75\x11\x66\x8b\x9d\x5c\xff\xff\xff\x80\xcf\x02\x80\xe7\xfe\xb3\x3f\xeb\x04\x66\xbb\x3f\x13\x66\x89\x9d\x5e\xff\xff\xff\xd9\xad\x5e\xff\xff\xff\xbb\x9e\x4a\x01\x10\xd9\xe5\x89\x95\x6c\xff\xff\xff\x9b\xdd\xbd\x60\xff\xff\xff\xc6\x85\x70\xff\xff\xff\x00\xd9\xc9\x8a\x8d\x61\xff\xff\xff\xd9\xe5\x9b\xdd\xbd\x60\xff\xff\xff\xd9\xc9\x8a\xad\x61\xff\xff\xff\xd0\xe5\xd0\xfd\xd0\xc5\x8a\xc5\x24\x0f\xd7\x8a\xe0\xd0\xe1\xd0\xf9\xd0\xc1\x8a\xc1\x24\x0f\xd7\xd0\xe4\xd0\xe4\x0a\xc4\x0f\xbe\xc0\x81\xe1\x04\x04\x00\x00\x8b\xda\x03\xd8\x83\xc3\x10\xff\x23\xe8\xce\x00\x00\x00\xd9\xc9\xdd\xd8\xc3\xe8\xc4\x00\x00\x00\xeb\xf6\xdd\xd8\xdd\xd8\xd9\xee\xc3\xdd\xd8\xdd\xd8\xd9\xee\x84\xed\x74\x02\xd9\xe0\xc3\xdd\xd8\xdd\xd8\xd9\xe8\xc3\xdb\xbd\x62\xff\xff\xff\xdb\xad\x62\xff\xff\xff\xf6\x85\x69\xff\xff\xff\x40\x74\x08\xc6\x85\x70\xff\xff\xff\x00\xc3\xc6\x85\x70\xff\xff\xff\x00\xdc\x05\x8e\x4a\x01\x10\xc3\xd9\xc9\xdb\xbd\x62\xff\xff\xff\xdb\xad\x62\xff\xff\xff\xf6\x85\x69\xff\xff\xff\x40\x74\x09\xc6\x85\x70\xff\xff\xff\x00\xeb\x07\xc6\x85\x70\xff\xff\xff\x00\xde\xc1\xc3\xdb\xbd\x62\xff\xff\xff\xdb\xad\x62\xff\xff\xff\xf6\x85\x69\xff\xff\xff\x40\x74\x20\xd9\xc9\xdb\xbd\x62\xff\xff\xff\xdb\xad\x62\xff\xff\xff\xf6\x85\x69\xff\xff\xff\x40\x74\x09\xc6\x85\x70\xff\xff\xff\x00\xeb\x07\xc6\x85\x70\xff\xff\xff\x01\xde\xc1\xc3\xdd\xd8\xdd\xd8\xdb\x2d\x70\x4a\x01\x10\x80\xbd\x70\xff\xff\xff\x00\x7f\x07\xc6\x85\x70\xff\xff\xff\x01\x0a\xc9\xc3\xdd\xd8\xdd\xd8\xdb\x2d\x84\x4a\x01\x10\x0a\xed\x74\x02\xd9\xe0\x0a\xc9\x74\x08\xdd\x05\x96\x4a\x01\x10\xde\xc9\xc3\x0a\xc9\x74\x02\xd9\xe0\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xd9\xc0\xd9\xfc\xdc\xe1\xd9\xc9\xd9\xe0\xd9\xf0\xd9\xe8\xde\xc1\xd9\xfd\xdd\xd9\xc3\x8b\x54\x24\x04\x81\xe2\x00\x03\x00\x00\x83\xca\x7f\x66\x89\x54\x24\x06\xd9\x6c\x24\x06\xc3\xa9\x00\x00\x08\x00\x74\x06\xb8\x00\x00\x00\x00\xc3\xdc\x05\xb0\x4a\x01\x10\xb8\x00\x00\x00\x00\xc3\x8b\x42\x04\x25\x00\x00\xf0\x7f\x3d\x00\x00\xf0\x7f\x74\x03\xdd\x02\xc3\x8b\x42\x04\x83\xec\x0a\x0d\x00\x00\xff\x7f\x89\x44\x24\x06\x8b\x42\x04\x8b\x0a\x0f\xa4\xc8\x0b\xc1\xe1\x0b\x89\x44\x24\x04\x89\x0c\x24\xdb\x2c\x24\x83\xc4\x0a\xa9\x00\x00\x00\x00\x8b\x42\x04\xc3\x8b\x44\x24\x08\x25\x00\x00\xf0\x7f\x3d\x00\x00\xf0\x7f\x74\x01\xc3\x8b\x44\x24\x08\xc3\x66\x81\x3c\x24\x7f\x02\x74\x03\xd9\x2c\x24\x5a\xc3\x66\x8b\x04\x24\x66\x3d\x7f\x02\x74\x1e\x66\x83\xe0\x20\x74\x15\x9b\xdf\xe0\x66\x83\xe0\x20\x74\x0c\xb8\x08\x00\x00\x00\xe8\xd9\x00\x00\x00\x5a\xc3\xd9\x2c\x24\x5a\xc3\x83\xec\x08\xdd\x14\x24\x8b\x44\x24\x04\x83\xc4\x08\x25\x00\x00\xf0\x7f\xeb\x14\x83\xec\x08\xdd\x14\x24\x8b\x44\x24\x04\x83\xc4\x08\x25\x00\x00\xf0\x7f\x74\x3d\x3d\x00\x00\xf0\x7f\x74\x5f\x66\x8b\x04\x24\x66\x3d\x7f\x02\x74\x2a\x66\x83\xe0\x20\x75\x21\x9b\xdf\xe0\x66\x83\xe0\x20\x74\x18\xb8\x08\x00\x00\x00\x83\xfa\x1d\x74\x07\xe8\x7b\x00\x00\x00\x5a\xc3\xe8\x5d\x00\x00\x00\x5a\xc3\xd9\x2c\x24\x5a\xc3\xdd\x05\xdc\x4a\x01\x10\xd9\xc9\xd9\xfd\xdd\xd9\xd9\xc0\xd9\xe1\xdc\x1d\xcc\x4a\x01\x10\x9b\xdf\xe0\x9e\xb8\x04\x00\x00\x00\x73\xc7\xdc\x0d\xec\x4a\x01\x10\xeb\xbf\xdd\x05\xd4\x4a\x01\x10\xd9\xc9\xd9\xfd\xdd\xd9\xd9\xc0\xd9\xe1\xdc\x1d\xc4\x4a\x01\x10\x9b\xdf\xe0\x9e\xb8\x03\x00\x00\x00\x76\x9e\xdc\x0d\xe4\x4a\x01\x10\xeb\x96\xcc\xcc\xcc\xcc\x55\x8b\xec\x83\xc4\xe0\x89\x45\xe0\x8b\x45\x18\x89\x45\xf0\x8b\x45\x1c\x89\x45\xf4\xeb\x09\x55\x8b\xec\x83\xc4\xe0\x89\x45\xe0\xdd\x5d\xf8\x89\x4d\xe4\x8b\x45\x10\x8b\x4d\x14\x89\x45\xe8\x89\x4d\xec\x8d\x45\x08\x8d\x4d\xe0\x50\x51\x52\xe8\x92\x05\x00\x00\x83\xc4\x0c\xdd\x45\xf8\x66\x81\x7d\x08\x7f\x02\x74\x03\xd9\x6d\x08\xc9\xc3\x8b\xff\x55\x8b\xec\x83\xec\x24\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x83\x3d\xbc\x80\x01\x10\x00\x56\x57\x74\x10\xff\x35\xa4\x84\x01\x10\xff\x15\x14\x00\x01\x10\x8b\xf8\xeb\x05\xbf\x65\x8a\x00\x10\x8b\x45\x14\x83\xf8\x1a\x0f\x8f\x21\x01\x00\x00\x0f\x84\x0f\x01\x00\x00\x83\xf8\x0e\x0f\x8f\xa7\x00\x00\x00\x0f\x84\x8e\x00\x00\x00\x6a\x02\x59\x2b\xc1\x74\x78\x83\xe8\x01\x74\x6a\x83\xe8\x05\x74\x56\x83\xe8\x01\x0f\x85\x9b\x01\x00\x00\xc7\x45\xe0\xf8\x4a\x01\x10\x8b\x45\x08\x8b\xcf\x8b\x75\x10\xc7\x45\xdc\x01\x00\x00\x00\xdd\x00\x8b\x45\x0c\xdd\x5d\xe4\xdd\x00\x8d\x45\xdc\xdd\x5d\xec\xdd\x06\x50\xdd\x5d\xf4\xff\x15\x64\x01\x01\x10\xff\xd7\x59\x85\xc0\x0f\x85\x59\x01\x00\x00\xe8\x69\x83\xff\xff\xc7\x00\x21\x00\x00\x00\xe9\x49\x01\x00\x00\x89\x4d\xdc\xc7\x45\xe0\xf8\x4a\x01\x10\xe9\x04\x01\x00\x00\xc7\x45\xe0\xf4\x4a\x01\x10\xeb\xa2\x89\x4d\xdc\xc7\x45\xe0\xf4\x4a\x01\x10\xe9\xec\x00\x00\x00\xc7\x45\xdc\x03\x00\x00\x00\xc7\x45\xe0\x00\x4b\x01\x10\xe9\xd9\x00\x00\x00\x83\xe8\x0f\x74\x51\x83\xe8\x09\x74\x43\x83\xe8\x01\x0f\x85\x01\x01\x00\x00\xc7\x45\xe0\x04\x4b\x01\x10\x8b\x45\x08\x8b\xcf\x8b\x75\x10\xc7\x45\xdc\x04\x00\x00\x00\xdd\x00\x8b\x45\x0c\xdd\x5d\xe4\xdd\x00\x8d\x45\xdc\xdd\x5d\xec\xdd\x06\x50\xdd\x5d\xf4\xff\x15\x64\x01\x01\x10\xff\xd7\x59\xe9\xc2\x00\x00\x00\xc7\x45\xdc\x03\x00\x00\x00\xeb\x7c\xc7\x45\xe0\x00\x4b\x01\x10\xeb\xbb\xd9\xe8\x8b\x45\x10\xdd\x18\xe9\xa9\x00\x00\x00\x83\xe8\x1b\x74\x5b\x83\xe8\x01\x74\x4a\x83\xe8\x15\x74\x39\x83\xe8\x09\x74\x28\x83\xe8\x03\x74\x17\x2d\xab\x03\x00\x00\x74\x09\x83\xe8\x01\x0f\x85\x80\x00\x00\x00\x8b\x45\x08\xdd\x00\xeb\xc6\xc7\x45\xe0\x08\x4b\x01\x10\xe9\xd9\xfe\xff\xff\xc7\x45\xe0\x10\x4b\x01\x10\xe9\xcd\xfe\xff\xff\xc7\x45\xe0\x18\x4b\x01\x10\xe9\xc1\xfe\xff\xff\xc7\x45\xe0\x04\x4b\x01\x10\xe9\xb5\xfe\xff\xff\xc7\x45\xdc\x02\x00\x00\x00\xc7\x45\xe0\x04\x4b\x01\x10\x8b\x45\x08\x8b\xcf\x8b\x75\x10\xdd\x00\x8b\x45\x0c\xdd\x5d\xe4\xdd\x00\x8d\x45\xdc\xdd\x5d\xec\xdd\x06\x50\xdd\x5d\xf4\xff\x15\x64\x01\x01\x10\xff\xd7\x59\x85\xc0\x75\x0b\xe8\x1b\x82\xff\xff\xc7\x00\x22\x00\x00\x00\xdd\x45\xf4\xdd\x1e\x8b\x4d\xfc\x5f\x33\xcd\x5e\xe8\xdd\x3f\xff\xff\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x53\x56\xbe\xff\xff\x00\x00\x56\x68\x3f\x1b\x00\x00\xe8\x20\x01\x00\x00\xdd\x45\x08\x8b\xd8\x59\x59\x0f\xb7\x4d\x0e\xb8\xf0\x7f\x00\x00\x23\xc8\x51\x51\xdd\x1c\x24\x66\x3b\xc8\x75\x37\xe8\x18\x0c\x00\x00\x48\x59\x59\x83\xf8\x02\x77\x0e\x56\x53\xe8\xf0\x00\x00\x00\xdd\x45\x08\x59\x59\xeb\x63\xdd\x45\x08\xdd\x05\x20\x4b\x01\x10\x53\x83\xec\x10\xd8\xc1\xdd\x5c\x24\x08\xdd\x1c\x24\x6a\x0c\x6a\x08\xeb\x3f\xe8\x01\x04\x00\x00\xdd\x55\xf8\xdd\x45\x08\x83\xc4\x08\xdd\xe1\xdf\xe0\xf6\xc4\x44\x7a\x12\x56\xdd\xd9\x53\xdd\xd8\xe8\xab\x00\x00\x00\xdd\x45\xf8\x59\x59\xeb\x1e\xf6\xc3\x20\x75\xe9\x53\x83\xec\x10\xd9\xc9\xdd\x5c\x24\x08\xdd\x1c\x24\x6a\x0c\x6a\x10\xe8\x0c\x04\x00\x00\x83\xc4\x1c\x5e\x5b\x8b\xe5\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x57\x56\x53\x8b\x4d\x10\x0b\xc9\x74\x4d\x8b\x75\x08\x8b\x7d\x0c\xb7\x41\xb3\x5a\xb6\x20\x8d\x49\x00\x8a\x26\x0a\xe4\x8a\x07\x74\x27\x0a\xc0\x74\x23\x83\xc6\x01\x83\xc7\x01\x3a\xe7\x72\x06\x3a\xe3\x77\x02\x02\xe6\x3a\xc7\x72\x06\x3a\xc3\x77\x02\x02\xc6\x3a\xe0\x75\x0b\x83\xe9\x01\x75\xd1\x33\xc9\x3a\xe0\x74\x09\xb9\xff\xff\xff\xff\x72\x02\xf7\xd9\x8b\xc1\x5b\x5e\x5f\xc9\xc3\x8b\xff\x55\x8b\xec\x51\xdd\x7d\xfc\xdb\xe2\x0f\xbf\x45\xfc\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x9b\xd9\x7d\xfc\x8b\x4d\x0c\x8b\x45\x08\xf7\xd1\x66\x23\x4d\xfc\x23\x45\x0c\x66\x0b\xc8\x66\x89\x4d\xf8\xd9\x6d\xf8\x0f\xbf\x45\xfc\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x4d\x08\x83\xec\x0c\xf6\xc1\x01\x74\x0a\xdb\x2d\x28\x4b\x01\x10\xdb\x5d\xfc\x9b\xf6\xc1\x08\x74\x10\x9b\xdf\xe0\xdb\x2d\x28\x4b\x01\x10\xdd\x5d\xf4\x9b\x9b\xdf\xe0\xf6\xc1\x10\x74\x0a\xdb\x2d\x34\x4b\x01\x10\xdd\x5d\xf4\x9b\xf6\xc1\x04\x74\x09\xd9\xee\xd9\xe8\xde\xf1\xdd\xd8\x9b\xf6\xc1\x20\x74\x06\xd9\xeb\xdd\x5d\xf4\x9b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x9b\xdd\x7d\xfc\x0f\xbf\x45\xfc\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\xdd\x45\x08\x51\x51\xdd\x1c\x24\xe8\xca\x0a\x00\x00\x59\x59\xa8\x90\x75\x4a\xdd\x45\x08\x51\x51\xdd\x1c\x24\xe8\x79\x02\x00\x00\xdd\x45\x08\xdd\xe1\xdf\xe0\x59\x59\xdd\xd9\xf6\xc4\x44\x7a\x2b\xdc\x0d\x60\x53\x01\x10\x51\x51\xdd\x55\xf8\xdd\x1c\x24\xe8\x56\x02\x00\x00\xdd\x45\xf8\xda\xe9\xdf\xe0\x59\x59\xf6\xc4\x44\x7a\x05\x6a\x02\x58\xeb\x09\x33\xc0\x40\xeb\x04\xdd\xd8\x33\xc0\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xdd\x45\x08\xb9\x00\x00\xf0\x7f\xd9\xe1\xb8\x00\x00\xf0\xff\x39\x4d\x14\x75\x3b\x83\x7d\x10\x00\x75\x75\xd9\xe8\xd8\xd1\xdf\xe0\xf6\xc4\x05\x7a\x0f\xdd\xd9\xdd\xd8\xdd\x05\xf0\x54\x01\x10\xe9\xe9\x00\x00\x00\xd8\xd1\xdf\xe0\xdd\xd9\xf6\xc4\x41\x8b\x45\x18\x0f\x85\xda\x00\x00\x00\xdd\xd8\xd9\xee\xe9\xd1\x00\x00\x00\x39\x45\x14\x75\x3b\x83\x7d\x10\x00\x75\x35\xd9\xe8\xd8\xd1\xdf\xe0\xf6\xc4\x05\x7a\x0b\xdd\xd9\xdd\xd8\xd9\xee\xe9\xad\x00\x00\x00\xd8\xd1\xdf\xe0\xdd\xd9\xf6\xc4\x41\x8b\x45\x18\x0f\x85\x9e\x00\x00\x00\xdd\xd8\xdd\x05\xf0\x54\x01\x10\xe9\x91\x00\x00\x00\xdd\xd8\x39\x4d\x0c\x75\x2e\x83\x7d\x08\x00\x0f\x85\x82\x00\x00\x00\xd9\xee\xdd\x45\x10\xd8\xd1\xdf\xe0\xf6\xc4\x41\x0f\x84\x73\xff\xff\xff\xd8\xd9\xdf\xe0\xf6\xc4\x05\x8b\x45\x18\x7b\x62\xdd\xd8\xd9\xe8\xeb\x5c\x39\x45\x0c\x75\x59\x83\x7d\x08\x00\x75\x53\xdd\x45\x10\x51\x51\xdd\x1c\x24\xe8\xb5\xfe\xff\xff\xd9\xee\xdd\x45\x10\x59\x59\xd8\xd1\x8b\xc8\xdf\xe0\xf6\xc4\x41\x75\x13\xdd\xd9\xdd\xd8\xdd\x05\xf0\x54\x01\x10\x83\xf9\x01\x75\x20\xd9\xe0\xeb\x1c\xd8\xd9\xdf\xe0\xf6\xc4\x05\x7a\x0f\x83\xf9\x01\x75\x0e\xdd\xd8\xdd\x05\x00\x55\x01\x10\xeb\x04\xdd\xd8\xd9\xe8\x8b\x45\x18\xdd\x18\x33\xc0\x5d\xc3\x8b\xff\x53\x8b\xdc\x51\x51\x83\xe4\xf0\x83\xc4\x04\x55\x8b\x6b\x04\x89\x6c\x24\x04\x8b\xec\x81\xec\x88\x00\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x8b\x43\x10\x56\x8b\x73\x0c\x57\x0f\xb7\x08\x89\x8d\x7c\xff\xff\xff\x8b\x06\x83\xe8\x01\x74\x29\x83\xe8\x01\x74\x20\x83\xe8\x01\x74\x17\x83\xe8\x01\x74\x0e\x83\xe8\x01\x74\x15\x83\xe8\x03\x75\x72\x6a\x10\xeb\x0e\x6a\x12\xeb\x0a\x6a\x11\xeb\x06\x6a\x04\xeb\x02\x6a\x08\x5f\x51\x8d\x46\x18\x50\x57\xe8\xad\x01\x00\x00\x83\xc4\x0c\x85\xc0\x75\x47\x8b\x4b\x08\x83\xf9\x10\x74\x10\x83\xf9\x16\x74\x0b\x83\xf9\x1d\x74\x06\x83\x65\xc0\xfe\xeb\x12\x8b\x45\xc0\xdd\x46\x10\x83\xe0\xe3\x83\xc8\x03\xdd\x5d\xb0\x89\x45\xc0\x8d\x46\x18\x50\x8d\x46\x08\x50\x51\x57\x8d\x85\x7c\xff\xff\xff\x50\x8d\x45\x80\x50\xe8\x42\x03\x00\x00\x83\xc4\x18\x8b\x8d\x7c\xff\xff\xff\x68\xff\xff\x00\x00\x51\xe8\xfd\xfc\xff\xff\x83\x3e\x08\x59\x59\x74\x14\xe8\xb5\xad\xff\xff\x84\xc0\x74\x0b\x56\xe8\xd8\xad\xff\xff\x59\x85\xc0\x75\x08\xff\x36\xe8\x20\x06\x00\x00\x59\x8b\x4d\xfc\x5f\x33\xcd\x5e\xe8\x6e\x3b\xff\xff\x8b\xe5\x5d\x8b\xe3\x5b\xc3\x8b\xff\x55\x8b\xec\x51\x51\xdd\x45\x08\xd9\xfc\xdd\x5d\xf8\xdd\x45\xf8\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\xa8\x20\x74\x04\x6a\x05\xeb\x17\xa8\x08\x74\x05\x33\xc0\x40\x5d\xc3\xa8\x04\x74\x04\x6a\x02\xeb\x06\xa8\x01\x74\x05\x6a\x03\x58\x5d\xc3\x0f\xb6\xc0\x83\xe0\x02\x03\xc0\x5d\xc3\x8b\xff\x53\x8b\xdc\x51\x51\x83\xe4\xf0\x83\xc4\x04\x55\x8b\x6b\x04\x89\x6c\x24\x04\x8b\xec\x81\xec\x88\x00\x00\x00\xa1\x04\x70\x01\x10\x33\xc5\x89\x45\xfc\x56\x8b\x73\x20\x8d\x43\x18\x57\x56\x50\xff\x73\x08\xe8\x95\x00\x00\x00\x83\xc4\x0c\x85\xc0\x75\x26\x83\x65\xc0\xfe\x50\x8d\x43\x18\x50\x8d\x43\x10\x50\xff\x73\x0c\x8d\x43\x20\xff\x73\x08\x50\x8d\x45\x80\x50\xe8\x71\x02\x00\x00\x8b\x73\x20\x83\xc4\x1c\xff\x73\x08\xe8\x5e\xff\xff\xff\x59\x8b\xf8\xe8\xcb\xac\xff\xff\x84\xc0\x74\x29\x85\xff\x74\x25\xdd\x43\x18\x56\x83\xec\x18\xdd\x5c\x24\x10\xd9\xee\xdd\x5c\x24\x08\xdd\x43\x10\xdd\x1c\x24\xff\x73\x0c\x57\xe8\x53\x05\x00\x00\x83\xc4\x24\xeb\x18\x57\xe8\x19\x05\x00\x00\xc7\x04\x24\xff\xff\x00\x00\x56\xe8\xc7\xfb\xff\xff\xdd\x43\x18\x59\x59\x8b\x4d\xfc\x5f\x33\xcd\x5e\xe8\x56\x3a\xff\xff\x8b\xe5\x5d\x8b\xe3\x5b\xc3\x8b\xff\x55\x8b\xec\x83\xec\x10\x53\x8b\x5d\x08\x56\x8b\xf3\x83\xe6\x1f\xf6\xc3\x08\x74\x16\xf6\x45\x10\x01\x74\x10\x6a\x01\xe8\xb7\xfb\xff\xff\x59\x83\xe6\xf7\xe9\x90\x01\x00\x00\x8b\xc3\x23\x45\x10\xa8\x04\x74\x10\x6a\x04\xe8\x9e\xfb\xff\xff\x59\x83\xe6\xfb\xe9\x77\x01\x00\x00\xf6\xc3\x01\x0f\x84\x9a\x00\x00\x00\xf6\x45\x10\x08\x0f\x84\x90\x00\x00\x00\x6a\x08\xe8\x7b\xfb\xff\xff\x8b\x45\x10\x59\xb9\x00\x0c\x00\x00\x23\xc1\x74\x54\x3d\x00\x04\x00\x00\x74\x37\x3d\x00\x08\x00\x00\x74\x1a\x3b\xc1\x75\x62\x8b\x4d\x0c\xd9\xee\xdc\x19\xdf\xe0\xdd\x05\xf8\x54\x01\x10\xf6\xc4\x05\x7b\x4c\xeb\x48\x8b\x4d\x0c\xd9\xee\xdc\x19\xdf\xe0\xf6\xc4\x05\x7b\x2c\xdd\x05\xf8\x54\x01\x10\xeb\x32\x8b\x4d\x0c\xd9\xee\xdc\x19\xdf\xe0\xf6\xc4\x05\x7a\x1e\xdd\x05\xf8\x54\x01\x10\xeb\x1e\x8b\x4d\x0c\xd9\xee\xdc\x19\xdf\xe0\xf6\xc4\x05\x7a\x08\xdd\x05\xf0\x54\x01\x10\xeb\x08\xdd\x05\xf0\x54\x01\x10\xd9\xe0\xdd\x19\x83\xe6\xfe\xe9\xd4\x00\x00\x00\xf6\xc3\x02\x0f\x84\xcb\x00\x00\x00\xf6\x45\x10\x10\x0f\x84\xc1\x00\x00\x00\x57\x33\xff\xf6\xc3\x10\x74\x01\x47\x8b\x4d\x0c\xdd\x01\xd9\xee\xda\xe9\xdf\xe0\xf6\xc4\x44\x0f\x8b\x91\x00\x00\x00\xdd\x01\x8d\x45\xfc\x50\x51\x51\xdd\x1c\x24\xe8\x9c\x04\x00\x00\x8b\x45\xfc\x83\xc4\x0c\x05\x00\xfa\xff\xff\x89\x45\xfc\xdd\x55\xf0\xd9\xee\x3d\xce\xfb\xff\xff\x7d\x07\x33\xff\xde\xc9\x47\xeb\x59\xde\xd9\x33\xd2\xdf\xe0\xf6\xc4\x41\x75\x01\x42\x8b\x45\xf6\xb9\x03\xfc\xff\xff\x83\xe0\x0f\x83\xc8\x10\x66\x89\x45\xf6\x8b\x45\xfc\x3b\xc1\x7d\x2b\x2b\xc8\x8b\x45\xf0\xf6\x45\xf0\x01\x74\x05\x85\xff\x75\x01\x47\xd1\xe8\xf6\x45\xf4\x01\x89\x45\xf0\x74\x08\x0d\x00\x00\x00\x80\x89\x45\xf0\xd1\x6d\xf4\x83\xe9\x01\x75\xda\xdd\x45\xf0\x85\xd2\x74\x02\xd9\xe0\x8b\x45\x0c\xdd\x18\xeb\x03\x33\xff\x47\x85\xff\x5f\x74\x08\x6a\x10\xe8\x22\xfa\xff\xff\x59\x83\xe6\xfd\xf6\xc3\x10\x74\x11\xf6\x45\x10\x20\x74\x0b\x6a\x20\xe8\x0c\xfa\xff\xff\x59\x83\xe6\xef\x33\xc0\x85\xf6\x5e\x0f\x94\xc0\x5b\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x6a\x00\xff\x75\x1c\xff\x75\x18\xff\x75\x14\xff\x75\x10\xff\x75\x0c\xff\x75\x08\xe8\x05\x00\x00\x00\x83\xc4\x1c\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x33\xc9\x53\x33\xdb\x43\x89\x48\x04\x8b\x45\x08\x57\xbf\x0d\x00\x00\xc0\x89\x48\x08\x8b\x45\x08\x89\x48\x0c\x8b\x4d\x10\xf6\xc1\x10\x74\x0b\x8b\x45\x08\xbf\x8f\x00\x00\xc0\x09\x58\x04\xf6\xc1\x02\x74\x0c\x8b\x45\x08\xbf\x93\x00\x00\xc0\x83\x48\x04\x02\xf6\xc1\x01\x74\x0c\x8b\x45\x08\xbf\x91\x00\x00\xc0\x83\x48\x04\x04\xf6\xc1\x04\x74\x0c\x8b\x45\x08\xbf\x8e\x00\x00\xc0\x83\x48\x04\x08\xf6\xc1\x08\x74\x0c\x8b\x45\x08\xbf\x90\x00\x00\xc0\x83\x48\x04\x10\x8b\x4d\x08\x56\x8b\x75\x0c\x8b\x06\xc1\xe0\x04\xf7\xd0\x33\x41\x08\x83\xe0\x10\x31\x41\x08\x8b\x4d\x08\x8b\x06\x03\xc0\xf7\xd0\x33\x41\x08\x83\xe0\x08\x31\x41\x08\x8b\x4d\x08\x8b\x06\xd1\xe8\xf7\xd0\x33\x41\x08\x83\xe0\x04\x31\x41\x08\x8b\x4d\x08\x8b\x06\xc1\xe8\x03\xf7\xd0\x33\x41\x08\x83\xe0\x02\x31\x41\x08\x8b\x06\x8b\x4d\x08\xc1\xe8\x05\xf7\xd0\x33\x41\x08\x23\xc3\x31\x41\x08\xe8\x54\xf9\xff\xff\x8b\xd0\xf6\xc2\x01\x74\x07\x8b\x4d\x08\x83\x49\x0c\x10\xf6\xc2\x04\x74\x07\x8b\x45\x08\x83\x48\x0c\x08\xf6\xc2\x08\x74\x07\x8b\x45\x08\x83\x48\x0c\x04\xf6\xc2\x10\x74\x07\x8b\x45\x08\x83\x48\x0c\x02\xf6\xc2\x20\x74\x06\x8b\x45\x08\x09\x58\x0c\x8b\x06\xb9\x00\x0c\x00\x00\x23\xc1\x74\x35\x3d\x00\x04\x00\x00\x74\x22\x3d\x00\x08\x00\x00\x74\x0c\x3b\xc1\x75\x29\x8b\x45\x08\x83\x08\x03\xeb\x21\x8b\x4d\x08\x8b\x01\x83\xe0\xfe\x83\xc8\x02\x89\x01\xeb\x12\x8b\x4d\x08\x8b\x01\x83\xe0\xfd\x0b\xc3\xeb\xf0\x8b\x45\x08\x83\x20\xfc\x8b\x06\xb9\x00\x03\x00\x00\x23\xc1\x74\x20\x3d\x00\x02\x00\x00\x74\x0c\x3b\xc1\x75\x22\x8b\x45\x08\x83\x20\xe3\xeb\x1a\x8b\x4d\x08\x8b\x01\x83\xe0\xe7\x83\xc8\x04\xeb\x0b\x8b\x4d\x08\x8b\x01\x83\xe0\xeb\x83\xc8\x08\x89\x01\x8b\x45\x08\x8b\x4d\x14\xc1\xe1\x05\x33\x08\x81\xe1\xe0\xff\x01\x00\x31\x08\x8b\x45\x08\x09\x58\x20\x83\x7d\x20\x00\x74\x2c\x8b\x45\x08\x83\x60\x20\xe1\x8b\x45\x18\xd9\x00\x8b\x45\x08\xd9\x58\x10\x8b\x45\x08\x09\x58\x60\x8b\x45\x08\x8b\x5d\x1c\x83\x60\x60\xe1\x8b\x45\x08\xd9\x03\xd9\x58\x50\xeb\x3a\x8b\x4d\x08\x8b\x41\x20\x83\xe0\xe3\x83\xc8\x02\x89\x41\x20\x8b\x45\x18\xdd\x00\x8b\x45\x08\xdd\x58\x10\x8b\x45\x08\x09\x58\x60\x8b\x4d\x08\x8b\x5d\x1c\x8b\x41\x60\x83\xe0\xe3\x83\xc8\x02\x89\x41\x60\x8b\x45\x08\xdd\x03\xdd\x58\x50\xe8\x75\xf7\xff\xff\x8d\x45\x08\x50\x6a\x01\x6a\x00\x57\xff\x15\x10\x00\x01\x10\x8b\x4d\x08\xf6\x41\x08\x10\x74\x03\x83\x26\xfe\xf6\x41\x08\x08\x74\x03\x83\x26\xfb\xf6\x41\x08\x04\x74\x03\x83\x26\xf7\xf6\x41\x08\x02\x74\x03\x83\x26\xef\xf6\x41\x08\x01\x74\x03\x83\x26\xdf\x8b\x01\xba\xff\xf3\xff\xff\x83\xe0\x03\x83\xe8\x00\x74\x35\x83\xe8\x01\x74\x22\x83\xe8\x01\x74\x0d\x83\xe8\x01\x75\x28\x81\x0e\x00\x0c\x00\x00\xeb\x20\x8b\x06\x25\xff\xfb\xff\xff\x0d\x00\x08\x00\x00\x89\x06\xeb\x10\x8b\x06\x25\xff\xf7\xff\xff\x0d\x00\x04\x00\x00\xeb\xee\x21\x16\x8b\x01\xc1\xe8\x02\x83\xe0\x07\x83\xe8\x00\x74\x19\x83\xe8\x01\x74\x09\x83\xe8\x01\x75\x1a\x21\x16\xeb\x16\x8b\x06\x23\xc2\x0d\x00\x02\x00\x00\xeb\x09\x8b\x06\x23\xc2\x0d\x00\x03\x00\x00\x89\x06\x83\x7d\x20\x00\x5e\x74\x07\xd9\x41\x50\xd9\x1b\xeb\x05\xdd\x41\x50\xdd\x1b\x5f\x5b\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x45\x08\x83\xf8\x01\x74\x15\x83\xc0\xfe\x83\xf8\x01\x77\x18\xe8\x68\x77\xff\xff\xc7\x00\x22\x00\x00\x00\x5d\xc3\xe8\x5b\x77\xff\xff\xc7\x00\x21\x00\x00\x00\x5d\xc3\x8b\xff\x55\x8b\xec\x8b\x55\x0c\x83\xec\x20\x33\xc9\x8b\xc1\x39\x14\xc5\xf8\x53\x01\x10\x74\x08\x40\x83\xf8\x1d\x7c\xf1\xeb\x07\x8b\x0c\xc5\xfc\x53\x01\x10\x89\x4d\xe4\x85\xc9\x74\x55\x8b\x45\x10\x89\x45\xe8\x8b\x45\x14\x89\x45\xec\x8b\x45\x18\x89\x45\xf0\x8b\x45\x1c\x56\x8b\x75\x08\x89\x45\xf4\x8b\x45\x20\x68\xff\xff\x00\x00\xff\x75\x28\x89\x45\xf8\x8b\x45\x24\x89\x75\xe0\x89\x45\xfc\xe8\x26\xf6\xff\xff\x8d\x45\xe0\x50\xe8\x0e\xa7\xff\xff\x83\xc4\x0c\x85\xc0\x75\x07\x56\xe8\x55\xff\xff\xff\x59\xdd\x45\xf8\x5e\xeb\x1b\x68\xff\xff\x00\x00\xff\x75\x28\xe8\xfc\xf5\xff\xff\xff\x75\x08\xe8\x39\xff\xff\xff\xdd\x45\x20\x83\xc4\x0c\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\xdd\x45\x08\xd9\xee\xdd\xe1\xdf\xe0\x57\xf6\xc4\x44\x7a\x09\xdd\xd9\x33\xff\xe9\xaf\x00\x00\x00\x56\x66\x8b\x75\x0e\x0f\xb7\xc6\xa9\xf0\x7f\x00\x00\x75\x7c\x8b\x4d\x0c\x8b\x55\x08\xf7\xc1\xff\xff\x0f\x00\x75\x04\x85\xd2\x74\x6a\xde\xd9\xbf\x03\xfc\xff\xff\xdf\xe0\xf6\xc4\x41\x75\x05\x33\xc0\x40\xeb\x02\x33\xc0\xf6\x45\x0e\x10\x75\x1f\x03\xc9\x89\x4d\x0c\x85\xd2\x79\x06\x83\xc9\x01\x89\x4d\x0c\x03\xd2\x4f\xf6\x45\x0e\x10\x74\xe8\x66\x8b\x75\x0e\x89\x55\x08\xb9\xef\xff\x00\x00\x66\x23\xf1\x66\x89\x75\x0e\x85\xc0\x74\x0c\xb8\x00\x80\x00\x00\x66\x0b\xf0\x66\x89\x75\x0e\xdd\x45\x08\x6a\x00\x51\x51\xdd\x1c\x24\xe8\x31\x00\x00\x00\x83\xc4\x0c\xeb\x23\x6a\x00\x51\xdd\xd8\x51\xdd\x1c\x24\xe8\x1e\x00\x00\x00\x0f\xb7\xfe\x83\xc4\x0c\xc1\xef\x04\x81\xe7\xff\x07\x00\x00\x81\xef\xfe\x03\x00\x00\x5e\x8b\x45\x10\x89\x38\x5f\x5d\xc3\x8b\xff\x55\x8b\xec\x51\x51\x8b\x4d\x10\x0f\xb7\x45\x0e\xdd\x45\x08\x25\x0f\x80\x00\x00\xdd\x5d\xf8\x8d\x89\xfe\x03\x00\x00\xc1\xe1\x04\x0b\xc8\x66\x89\x4d\xfe\xdd\x45\xf8\x8b\xe5\x5d\xc3\x8b\xff\x55\x8b\xec\x81\x7d\x0c\x00\x00\xf0\x7f\x8b\x45\x08\x75\x07\x85\xc0\x75\x15\x40\x5d\xc3\x81\x7d\x0c\x00\x00\xf0\xff\x75\x09\x85\xc0\x75\x05\x6a\x02\x58\x5d\xc3\x66\x8b\x4d\x0e\xba\xf8\x7f\x00\x00\x66\x23\xca\x66\x3b\xca\x75\x04\x6a\x03\xeb\xe8\xba\xf0\x7f\x00\x00\x66\x3b\xca\x75\x11\xf7\x45\x0c\xff\xff\x07\x00\x75\x04\x85\xc0\x74\x04\x6a\x04\xeb\xcd\x33\xc0\x5d\xc3\x8b\xff\x55\x8b\xec\x66\x8b\x4d\x0e\xba\xf0\x7f\x00\x00\x66\x8b\xc1\x66\x23\xc2\x66\x3b\xc2\x75\x33\xdd\x45\x08\x51\x51\xdd\x1c\x24\xe8\x7c\xff\xff\xff\x59\x59\x83\xe8\x01\x74\x18\x83\xe8\x01\x74\x0e\x83\xe8\x01\x74\x05\x33\xc0\x40\x5d\xc3\x6a\x02\xeb\x02\x6a\x04\x58\x5d\xc3\xb8\x00\x02\x00\x00\x5d\xc3\x0f\xb7\xc9\x81\xe1\x00\x80\x00\x00\x66\x85\xc0\x75\x1e\xf7\x45\x0c\xff\xff\x0f\x00\x75\x06\x83\x7d\x08\x00\x74\x0f\xf7\xd9\x1b\xc9\x83\xe1\x90\x8d\x81\x80\x00\x00\x00\x5d\xc3\xdd\x45\x08\xd9\xee\xda\xe9\xdf\xe0\xf6\xc4\x44\x7a\x0c\xf7\xd9\x1b\xc9\x83\xe1\xe0\x8d\x41\x40\x5d\xc3\xf7\xd9\x1b\xc9\x81\xe1\x08\xff\xff\xff\x8d\x81\x00\x01\x00\x00\x5d\xc3\xcc\xff\x25\x64\x00\x01\x10\xff\x25\xac\x00\x01\x10\xff\x25\x00\x00\x01\x10\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x8b\x45\x08\x33\xd2\x53\x56\x57\x8b\x48\x3c\x03\xc8\x0f\xb7\x41\x14\x0f\xb7\x59\x06\x83\xc0\x18\x03\xc1\x85\xdb\x74\x1b\x8b\x7d\x0c\x8b\x70\x0c\x3b\xfe\x72\x09\x8b\x48\x08\x03\xce\x3b\xf9\x72\x0a\x42\x83\xc0\x28\x3b\xd3\x72\xe8\x33\xc0\x5f\x5e\x5b\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x6a\xfe\x68\x48\x5e\x01\x10\x68\xe0\x25\x00\x10\x64\xa1\x00\x00\x00\x00\x50\x83\xec\x08\x53\x56\x57\xa1\x04\x70\x01\x10\x31\x45\xf8\x33\xc5\x50\x8d\x45\xf0\x64\xa3\x00\x00\x00\x00\x89\x65\xe8\xc7\x45\xfc\x00\x00\x00\x00\x68\x00\x00\x00\x10\xe8\x7c\x00\x00\x00\x83\xc4\x04\x85\xc0\x74\x54\x8b\x45\x08\x2d\x00\x00\x00\x10\x50\x68\x00\x00\x00\x10\xe8\x52\xff\xff\xff\x83\xc4\x08\x85\xc0\x74\x3a\x8b\x40\x24\xc1\xe8\x1f\xf7\xd0\x83\xe0\x01\xc7\x45\xfc\xfe\xff\xff\xff\x8b\x4d\xf0\x64\x89\x0d\x00\x00\x00\x00\x59\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x45\xec\x8b\x00\x33\xc9\x81\x38\x05\x00\x00\xc0\x0f\x94\xc1\x8b\xc1\xc3\x8b\x65\xe8\xc7\x45\xfc\xfe\xff\xff\xff\x33\xc0\x8b\x4d\xf0\x64\x89\x0d\x00\x00\x00\x00\x59\x5f\x5e\x5b\x8b\xe5\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x8b\x45\x08\xb9\x4d\x5a\x00\x00\x66\x39\x08\x74\x04\x33\xc0\x5d\xc3\x8b\x48\x3c\x03\xc8\x33\xc0\x81\x39\x50\x45\x00\x00\x75\x0c\xba\x0b\x01\x00\x00\x66\x39\x51\x18\x0f\x94\xc0\x5d\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x56\x8b\x44\x24\x14\x0b\xc0\x75\x28\x8b\x4c\x24\x10\x8b\x44\x24\x0c\x33\xd2\xf7\xf1\x8b\xd8\x8b\x44\x24\x08\xf7\xf1\x8b\xf0\x8b\xc3\xf7\x64\x24\x10\x8b\xc8\x8b\xc6\xf7\x64\x24\x10\x03\xd1\xeb\x47\x8b\xc8\x8b\x5c\x24\x10\x8b\x54\x24\x0c\x8b\x44\x24\x08\xd1\xe9\xd1\xdb\xd1\xea\xd1\xd8\x0b\xc9\x75\xf4\xf7\xf3\x8b\xf0\xf7\x64\x24\x14\x8b\xc8\x8b\x44\x24\x10\xf7\xe6\x03\xd1\x72\x0e\x3b\x54\x24\x0c\x77\x08\x72\x0f\x3b\x44\x24\x08\x76\x09\x4e\x2b\x44\x24\x10\x1b\x54\x24\x14\x33\xdb\x2b\x44\x24\x08\x1b\x54\x24\x0c\xf7\xda\xf7\xd8\x83\xda\x00\x8b\xca\x8b\xd3\x8b\xd9\x8b\xc8\x8b\xc6\x5e\xc2\x10\x00\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x68\xe0\x25\x00\x10\x64\xff\x35\x00\x00\x00\x00\x8b\x44\x24\x10\x89\x6c\x24\x10\x8d\x6c\x24\x10\x2b\xe0\x53\x56\x57\xa1\x04\x70\x01\x10\x31\x45\xfc\x33\xc5\x89\x45\xe4\x50\x89\x65\xe8\xff\x75\xf8\x8b\x45\xfc\xc7\x45\xfc\xfe\xff\xff\xff\x89\x45\xf8\x8d\x45\xf0\x64\xa3\x00\x00\x00\x00\xf2\xc3\x8b\x4d\xe4\x33\xcd\xf2\xe8\x20\x30\xff\xff\xf2\xe9\x4c\x3a\xff\xff\xcc\xcc\xcc\xcc\xcc\xcc\x8b\x44\x24\x08\x8b\x4c\x24\x10\x0b\xc8\x8b\x4c\x24\x0c\x75\x09\x8b\x44\x24\x04\xf7\xe1\xc2\x10\x00\x53\xf7\xe1\x8b\xd8\x8b\x44\x24\x08\xf7\x64\x24\x14\x03\xd8\x8b\x44\x24\x08\xf7\xe1\x03\xd3\x5b\xc2\x10\x00\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x57\x56\x55\x33\xff\x33\xed\x8b\x44\x24\x14\x0b\xc0\x7d\x15\x47\x45\x8b\x54\x24\x10\xf7\xd8\xf7\xda\x83\xd8\x00\x89\x44\x24\x14\x89\x54\x24\x10\x8b\x44\x24\x1c\x0b\xc0\x7d\x14\x47\x8b\x54\x24\x18\xf7\xd8\xf7\xda\x83\xd8\x00\x89\x44\x24\x1c\x89\x54\x24\x18\x0b\xc0\x75\x28\x8b\x4c\x24\x18\x8b\x44\x24\x14\x33\xd2\xf7\xf1\x8b\xd8\x8b\x44\x24\x10\xf7\xf1\x8b\xf0\x8b\xc3\xf7\x64\x24\x18\x8b\xc8\x8b\xc6\xf7\x64\x24\x18\x03\xd1\xeb\x47\x8b\xd8\x8b\x4c\x24\x18\x8b\x54\x24\x14\x8b\x44\x24\x10\xd1\xeb\xd1\xd9\xd1\xea\xd1\xd8\x0b\xdb\x75\xf4\xf7\xf1\x8b\xf0\xf7\x64\x24\x1c\x8b\xc8\x8b\x44\x24\x18\xf7\xe6\x03\xd1\x72\x0e\x3b\x54\x24\x14\x77\x08\x72\x0f\x3b\x44\x24\x10\x76\x09\x4e\x2b\x44\x24\x18\x1b\x54\x24\x1c\x33\xdb\x2b\x44\x24\x10\x1b\x54\x24\x14\x4d\x79\x07\xf7\xda\xf7\xd8\x83\xda\x00\x8b\xca\x8b\xd3\x8b\xd9\x8b\xc8\x8b\xc6\x4f\x75\x07\xf7\xda\xf7\xd8\x83\xda\x00\x5d\x5e\x5f\xc2\x10\x00\xcc\x80\xf9\x40\x73\x15\x80\xf9\x20\x73\x06\x0f\xad\xd0\xd3\xea\xc3\x8b\xc2\x33\xd2\x80\xe1\x1f\xd3\xe8\xc3\x33\xc0\x33\xd2\xc3\xcc\x51\x8d\x4c\x24\x04\x2b\xc8\x1b\xc0\xf7\xd0\x23\xc8\x8b\xc4\x25\x00\xf0\xff\xff\x3b\xc8\xf2\x72\x0b\x8b\xc1\x59\x94\x8b\x00\x89\x04\x24\xf2\xc3\x2d\x00\x10\x00\x00\x85\x00\xeb\xe7\xcc\xcc\xcc\x51\x8d\x4c\x24\x08\x2b\xc8\x83\xe1\x0f\x03\xc1\x1b\xc9\x0b\xc1\x59\xe9\xba\xff\xff\xff\x51\x8d\x4c\x24\x08\x2b\xc8\x83\xe1\x07\x03\xc1\x1b\xc9\x0b\xc1\x59\xe9\xa4\xff\xff\xff\xcc\xcc\xcc\xcc\x80\xf9\x40\x73\x15\x80\xf9\x20\x73\x06\x0f\xa5\xc2\xd3\xe0\xc3\x8b\xd0\x33\xc0\x80\xe1\x1f\xd3\xe2\xc3\x33\xc0\x33\xd2\xc3\xcc\x83\x3d\x2c\x7b\x01\x10\x00\x74\x37\x55\x8b\xec\x83\xec\x08\x83\xe4\xf8\xdd\x1c\x24\xf2\x0f\x2c\x04\x24\xc9\xc3\x83\x3d\x2c\x7b\x01\x10\x00\x74\x1b\x83\xec\x04\xd9\x3c\x24\x58\x66\x83\xe0\x7f\x66\x83\xf8\x7f\x74\xd3\x8d\xa4\x24\x00\x00\x00\x00\x8d\x49\x00\x55\x8b\xec\x83\xec\x20\x83\xe4\xf0\xd9\xc0\xd9\x54\x24\x18\xdf\x7c\x24\x10\xdf\x6c\x24\x10\x8b\x54\x24\x18\x8b\x44\x24\x10\x85\xc0\x74\x3c\xde\xe9\x85\xd2\x79\x1e\xd9\x1c\x24\x8b\x0c\x24\x81\xf1\x00\x00\x00\x80\x81\xc1\xff\xff\xff\x7f\x83\xd0\x00\x8b\x54\x24\x14\x83\xd2\x00\xeb\x2c\xd9\x1c\x24\x8b\x0c\x24\x81\xc1\xff\xff\xff\x7f\x83\xd8\x00\x8b\x54\x24\x14\x83\xda\x00\xeb\x14\x8b\x54\x24\x14\xf7\xc2\xff\xff\xff\x7f\x75\xb8\xd9\x5c\x24\x18\xd9\x5c\x24\x18\xc9\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x57\x56\x8b\x74\x24\x10\x8b\x4c\x24\x14\x8b\x7c\x24\x0c\x8b\xc1\x8b\xd1\x03\xc6\x3b\xfe\x76\x08\x3b\xf8\x0f\x82\x94\x02\x00\x00\x83\xf9\x20\x0f\x82\xd2\x04\x00\x00\x81\xf9\x80\x00\x00\x00\x73\x13\x0f\xba\x25\x10\x70\x01\x10\x01\x0f\x82\x8e\x04\x00\x00\xe9\xe3\x01\x00\x00\x0f\xba\x25\x30\x7b\x01\x10\x01\x73\x09\xf3\xa4\x8b\x44\x24\x0c\x5e\x5f\xc3\x8b\xc7\x33\xc6\xa9\x0f\x00\x00\x00\x75\x0e\x0f\xba\x25\x10\x70\x01\x10\x01\x0f\x82\xe0\x03\x00\x00\x0f\xba\x25\x30\x7b\x01\x10\x00\x0f\x83\xa9\x01\x00\x00\xf7\xc7\x03\x00\x00\x00\x0f\x85\x9d\x01\x00\x00\xf7\xc6\x03\x00\x00\x00\x0f\x85\xac\x01\x00\x00\x0f\xba\xe7\x02\x73\x0d\x8b\x06\x83\xe9\x04\x8d\x76\x04\x89\x07\x8d\x7f\x04\x0f\xba\xe7\x03\x73\x11\xf3\x0f\x7e\x0e\x83\xe9\x08\x8d\x76\x08\x66\x0f\xd6\x0f\x8d\x7f\x08\xf7\xc6\x07\x00\x00\x00\x74\x65\x0f\xba\xe6\x03\x0f\x83\xb4\x00\x00\x00\x66\x0f\x6f\x4e\xf4\x8d\x76\xf4\x8b\xff\x66\x0f\x6f\x5e\x10\x83\xe9\x30\x66\x0f\x6f\x46\x20\x66\x0f\x6f\x6e\x30\x8d\x76\x30\x83\xf9\x30\x66\x0f\x6f\xd3\x66\x0f\x3a\x0f\xd9\x0c\x66\x0f\x7f\x1f\x66\x0f\x6f\xe0\x66\x0f\x3a\x0f\xc2\x0c\x66\x0f\x7f\x47\x10\x66\x0f\x6f\xcd\x66\x0f\x3a\x0f\xec\x0c\x66\x0f\x7f\x6f\x20\x8d\x7f\x30\x7d\xb7\x8d\x76\x0c\xe9\xaf\x00\x00\x00\x66\x0f\x6f\x4e\xf8\x8d\x76\xf8\x8d\x49\x00\x66\x0f\x6f\x5e\x10\x83\xe9\x30\x66\x0f\x6f\x46\x20\x66\x0f\x6f\x6e\x30\x8d\x76\x30\x83\xf9\x30\x66\x0f\x6f\xd3\x66\x0f\x3a\x0f\xd9\x08\x66\x0f\x7f\x1f\x66\x0f\x6f\xe0\x66\x0f\x3a\x0f\xc2\x08\x66\x0f\x7f\x47\x10\x66\x0f\x6f\xcd\x66\x0f\x3a\x0f\xec\x08\x66\x0f\x7f\x6f\x20\x8d\x7f\x30\x7d\xb7\x8d\x76\x08\xeb\x56\x66\x0f\x6f\x4e\xfc\x8d\x76\xfc\x8b\xff\x66\x0f\x6f\x5e\x10\x83\xe9\x30\x66\x0f\x6f\x46\x20\x66\x0f\x6f\x6e\x30\x8d\x76\x30\x83\xf9\x30\x66\x0f\x6f\xd3\x66\x0f\x3a\x0f\xd9\x04\x66\x0f\x7f\x1f\x66\x0f\x6f\xe0\x66\x0f\x3a\x0f\xc2\x04\x66\x0f\x7f\x47\x10\x66\x0f\x6f\xcd\x66\x0f\x3a\x0f\xec\x04\x66\x0f\x7f\x6f\x20\x8d\x7f\x30\x7d\xb7\x8d\x76\x04\x83\xf9\x10\x7c\x13\xf3\x0f\x6f\x0e\x83\xe9\x10\x8d\x76\x10\x66\x0f\x7f\x0f\x8d\x7f\x10\xeb\xe8\x0f\xba\xe1\x02\x73\x0d\x8b\x06\x83\xe9\x04\x8d\x76\x04\x89\x07\x8d\x7f\x04\x0f\xba\xe1\x03\x73\x11\xf3\x0f\x7e\x0e\x83\xe9\x08\x8d\x76\x08\x66\x0f\xd6\x0f\x8d\x7f\x08\x8b\x04\x8d\xe4\xec\x00\x10\xff\xe0\xf7\xc7\x03\x00\x00\x00\x74\x13\x8a\x06\x88\x07\x49\x83\xc6\x01\x83\xc7\x01\xf7\xc7\x03\x00\x00\x00\x75\xed\x8b\xd1\x83\xf9\x20\x0f\x82\xae\x02\x00\x00\xc1\xe9\x02\xf3\xa5\x83\xe2\x03\xff\x24\x95\xe4\xec\x00\x10\xff\x24\x8d\xf4\xec\x00\x10\x90\xf4\xec\x00\x10\xfc\xec\x00\x10\x08\xed\x00\x10\x1c\xed\x00\x10\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8a\x06\x88\x07\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8a\x06\x88\x07\x8a\x46\x01\x88\x47\x01\x8b\x44\x24\x0c\x5e\x5f\xc3\x8d\x49\x00\x8a\x06\x88\x07\x8a\x46\x01\x88\x47\x01\x8a\x46\x02\x88\x47\x02\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8d\x34\x31\x8d\x3c\x39\x83\xf9\x20\x0f\x82\x51\x01\x00\x00\x0f\xba\x25\x10\x70\x01\x10\x01\x0f\x82\x94\x00\x00\x00\xf7\xc7\x03\x00\x00\x00\x74\x14\x8b\xd7\x83\xe2\x03\x2b\xca\x8a\x46\xff\x88\x47\xff\x4e\x4f\x83\xea\x01\x75\xf3\x83\xf9\x20\x0f\x82\x1e\x01\x00\x00\x8b\xd1\xc1\xe9\x02\x83\xe2\x03\x83\xee\x04\x83\xef\x04\xfd\xf3\xa5\xfc\xff\x24\x95\x90\xed\x00\x10\x90\xa0\xed\x00\x10\xa8\xed\x00\x10\xb8\xed\x00\x10\xcc\xed\x00\x10\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8a\x46\x03\x88\x47\x03\x8b\x44\x24\x0c\x5e\x5f\xc3\x8d\x49\x00\x8a\x46\x03\x88\x47\x03\x8a\x46\x02\x88\x47\x02\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8a\x46\x03\x88\x47\x03\x8a\x46\x02\x88\x47\x02\x8a\x46\x01\x88\x47\x01\x8b\x44\x24\x0c\x5e\x5f\xc3\xf7\xc7\x0f\x00\x00\x00\x74\x0f\x49\x4e\x4f\x8a\x06\x88\x07\xf7\xc7\x0f\x00\x00\x00\x75\xf1\x81\xf9\x80\x00\x00\x00\x72\x68\x81\xee\x80\x00\x00\x00\x81\xef\x80\x00\x00\x00\xf3\x0f\x6f\x06\xf3\x0f\x6f\x4e\x10\xf3\x0f\x6f\x56\x20\xf3\x0f\x6f\x5e\x30\xf3\x0f\x6f\x66\x40\xf3\x0f\x6f\x6e\x50\xf3\x0f\x6f\x76\x60\xf3\x0f\x6f\x7e\x70\xf3\x0f\x7f\x07\xf3\x0f\x7f\x4f\x10\xf3\x0f\x7f\x57\x20\xf3\x0f\x7f\x5f\x30\xf3\x0f\x7f\x67\x40\xf3\x0f\x7f\x6f\x50\xf3\x0f\x7f\x77\x60\xf3\x0f\x7f\x7f\x70\x81\xe9\x80\x00\x00\x00\xf7\xc1\x80\xff\xff\xff\x75\x90\x83\xf9\x20\x72\x23\x83\xee\x20\x83\xef\x20\xf3\x0f\x6f\x06\xf3\x0f\x6f\x4e\x10\xf3\x0f\x7f\x07\xf3\x0f\x7f\x4f\x10\x83\xe9\x20\xf7\xc1\xe0\xff\xff\xff\x75\xdd\xf7\xc1\xfc\xff\xff\xff\x74\x15\x83\xef\x04\x83\xee\x04\x8b\x06\x89\x07\x83\xe9\x04\xf7\xc1\xfc\xff\xff\xff\x75\xeb\x85\xc9\x74\x0f\x83\xef\x01\x83\xee\x01\x8a\x06\x88\x07\x83\xe9\x01\x75\xf1\x8b\x44\x24\x0c\x5e\x5f\xc3\xeb\x03\xcc\xcc\xcc\x8b\xc6\x83\xe0\x0f\x85\xc0\x0f\x85\xe3\x00\x00\x00\x8b\xd1\x83\xe1\x7f\xc1\xea\x07\x74\x66\x8d\xa4\x24\x00\x00\x00\x00\x8b\xff\x66\x0f\x6f\x06\x66\x0f\x6f\x4e\x10\x66\x0f\x6f\x56\x20\x66\x0f\x6f\x5e\x30\x66\x0f\x7f\x07\x66\x0f\x7f\x4f\x10\x66\x0f\x7f\x57\x20\x66\x0f\x7f\x5f\x30\x66\x0f\x6f\x66\x40\x66\x0f\x6f\x6e\x50\x66\x0f\x6f\x76\x60\x66\x0f\x6f\x7e\x70\x66\x0f\x7f\x67\x40\x66\x0f\x7f\x6f\x50\x66\x0f\x7f\x77\x60\x66\x0f\x7f\x7f\x70\x8d\xb6\x80\x00\x00\x00\x8d\xbf\x80\x00\x00\x00\x4a\x75\xa3\x85\xc9\x74\x5f\x8b\xd1\xc1\xea\x05\x85\xd2\x74\x21\x8d\x9b\x00\x00\x00\x00\xf3\x0f\x6f\x06\xf3\x0f\x6f\x4e\x10\xf3\x0f\x7f\x07\xf3\x0f\x7f\x4f\x10\x8d\x76\x20\x8d\x7f\x20\x4a\x75\xe5\x83\xe1\x1f\x74\x30\x8b\xc1\xc1\xe9\x02\x74\x0f\x8b\x16\x89\x17\x83\xc7\x04\x83\xc6\x04\x83\xe9\x01\x75\xf1\x8b\xc8\x83\xe1\x03\x74\x13\x8a\x06\x88\x07\x46\x47\x49\x75\xf7\x8d\xa4\x24\x00\x00\x00\x00\x8d\x49\x00\x8b\x44\x24\x0c\x5e\x5f\xc3\x8d\xa4\x24\x00\x00\x00\x00\x8b\xff\xba\x10\x00\x00\x00\x2b\xd0\x2b\xca\x51\x8b\xc2\x8b\xc8\x83\xe1\x03\x74\x09\x8a\x16\x88\x17\x46\x47\x49\x75\xf7\xc1\xe8\x02\x74\x0d\x8b\x16\x89\x17\x8d\x76\x04\x8d\x7f\x04\x48\x75\xf3\x59\xe9\xe9\xfe\xff\xff\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x57\x56\x8b\x74\x24\x10\x8b\x4c\x24\x14\x8b\x7c\x24\x0c\x8b\xc1\x8b\xd1\x03\xc6\x3b\xfe\x76\x08\x3b\xf8\x0f\x82\x94\x02\x00\x00\x83\xf9\x20\x0f\x82\xd2\x04\x00\x00\x81\xf9\x80\x00\x00\x00\x73\x13\x0f\xba\x25\x10\x70\x01\x10\x01\x0f\x82\x8e\x04\x00\x00\xe9\xe3\x01\x00\x00\x0f\xba\x25\x30\x7b\x01\x10\x01\x73\x09\xf3\xa4\x8b\x44\x24\x0c\x5e\x5f\xc3\x8b\xc7\x33\xc6\xa9\x0f\x00\x00\x00\x75\x0e\x0f\xba\x25\x10\x70\x01\x10\x01\x0f\x82\xe0\x03\x00\x00\x0f\xba\x25\x30\x7b\x01\x10\x00\x0f\x83\xa9\x01\x00\x00\xf7\xc7\x03\x00\x00\x00\x0f\x85\x9d\x01\x00\x00\xf7\xc6\x03\x00\x00\x00\x0f\x85\xac\x01\x00\x00\x0f\xba\xe7\x02\x73\x0d\x8b\x06\x83\xe9\x04\x8d\x76\x04\x89\x07\x8d\x7f\x04\x0f\xba\xe7\x03\x73\x11\xf3\x0f\x7e\x0e\x83\xe9\x08\x8d\x76\x08\x66\x0f\xd6\x0f\x8d\x7f\x08\xf7\xc6\x07\x00\x00\x00\x74\x65\x0f\xba\xe6\x03\x0f\x83\xb4\x00\x00\x00\x66\x0f\x6f\x4e\xf4\x8d\x76\xf4\x8b\xff\x66\x0f\x6f\x5e\x10\x83\xe9\x30\x66\x0f\x6f\x46\x20\x66\x0f\x6f\x6e\x30\x8d\x76\x30\x83\xf9\x30\x66\x0f\x6f\xd3\x66\x0f\x3a\x0f\xd9\x0c\x66\x0f\x7f\x1f\x66\x0f\x6f\xe0\x66\x0f\x3a\x0f\xc2\x0c\x66\x0f\x7f\x47\x10\x66\x0f\x6f\xcd\x66\x0f\x3a\x0f\xec\x0c\x66\x0f\x7f\x6f\x20\x8d\x7f\x30\x7d\xb7\x8d\x76\x0c\xe9\xaf\x00\x00\x00\x66\x0f\x6f\x4e\xf8\x8d\x76\xf8\x8d\x49\x00\x66\x0f\x6f\x5e\x10\x83\xe9\x30\x66\x0f\x6f\x46\x20\x66\x0f\x6f\x6e\x30\x8d\x76\x30\x83\xf9\x30\x66\x0f\x6f\xd3\x66\x0f\x3a\x0f\xd9\x08\x66\x0f\x7f\x1f\x66\x0f\x6f\xe0\x66\x0f\x3a\x0f\xc2\x08\x66\x0f\x7f\x47\x10\x66\x0f\x6f\xcd\x66\x0f\x3a\x0f\xec\x08\x66\x0f\x7f\x6f\x20\x8d\x7f\x30\x7d\xb7\x8d\x76\x08\xeb\x56\x66\x0f\x6f\x4e\xfc\x8d\x76\xfc\x8b\xff\x66\x0f\x6f\x5e\x10\x83\xe9\x30\x66\x0f\x6f\x46\x20\x66\x0f\x6f\x6e\x30\x8d\x76\x30\x83\xf9\x30\x66\x0f\x6f\xd3\x66\x0f\x3a\x0f\xd9\x04\x66\x0f\x7f\x1f\x66\x0f\x6f\xe0\x66\x0f\x3a\x0f\xc2\x04\x66\x0f\x7f\x47\x10\x66\x0f\x6f\xcd\x66\x0f\x3a\x0f\xec\x04\x66\x0f\x7f\x6f\x20\x8d\x7f\x30\x7d\xb7\x8d\x76\x04\x83\xf9\x10\x7c\x13\xf3\x0f\x6f\x0e\x83\xe9\x10\x8d\x76\x10\x66\x0f\x7f\x0f\x8d\x7f\x10\xeb\xe8\x0f\xba\xe1\x02\x73\x0d\x8b\x06\x83\xe9\x04\x8d\x76\x04\x89\x07\x8d\x7f\x04\x0f\xba\xe1\x03\x73\x11\xf3\x0f\x7e\x0e\x83\xe9\x08\x8d\x76\x08\x66\x0f\xd6\x0f\x8d\x7f\x08\x8b\x04\x8d\x64\xf2\x00\x10\xff\xe0\xf7\xc7\x03\x00\x00\x00\x74\x13\x8a\x06\x88\x07\x49\x83\xc6\x01\x83\xc7\x01\xf7\xc7\x03\x00\x00\x00\x75\xed\x8b\xd1\x83\xf9\x20\x0f\x82\xae\x02\x00\x00\xc1\xe9\x02\xf3\xa5\x83\xe2\x03\xff\x24\x95\x64\xf2\x00\x10\xff\x24\x8d\x74\xf2\x00\x10\x90\x74\xf2\x00\x10\x7c\xf2\x00\x10\x88\xf2\x00\x10\x9c\xf2\x00\x10\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8a\x06\x88\x07\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8a\x06\x88\x07\x8a\x46\x01\x88\x47\x01\x8b\x44\x24\x0c\x5e\x5f\xc3\x8d\x49\x00\x8a\x06\x88\x07\x8a\x46\x01\x88\x47\x01\x8a\x46\x02\x88\x47\x02\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8d\x34\x31\x8d\x3c\x39\x83\xf9\x20\x0f\x82\x51\x01\x00\x00\x0f\xba\x25\x10\x70\x01\x10\x01\x0f\x82\x94\x00\x00\x00\xf7\xc7\x03\x00\x00\x00\x74\x14\x8b\xd7\x83\xe2\x03\x2b\xca\x8a\x46\xff\x88\x47\xff\x4e\x4f\x83\xea\x01\x75\xf3\x83\xf9\x20\x0f\x82\x1e\x01\x00\x00\x8b\xd1\xc1\xe9\x02\x83\xe2\x03\x83\xee\x04\x83\xef\x04\xfd\xf3\xa5\xfc\xff\x24\x95\x10\xf3\x00\x10\x90\x20\xf3\x00\x10\x28\xf3\x00\x10\x38\xf3\x00\x10\x4c\xf3\x00\x10\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8a\x46\x03\x88\x47\x03\x8b\x44\x24\x0c\x5e\x5f\xc3\x8d\x49\x00\x8a\x46\x03\x88\x47\x03\x8a\x46\x02\x88\x47\x02\x8b\x44\x24\x0c\x5e\x5f\xc3\x90\x8a\x46\x03\x88\x47\x03\x8a\x46\x02\x88\x47\x02\x8a\x46\x01\x88\x47\x01\x8b\x44\x24\x0c\x5e\x5f\xc3\xf7\xc7\x0f\x00\x00\x00\x74\x0f\x49\x4e\x4f\x8a\x06\x88\x07\xf7\xc7\x0f\x00\x00\x00\x75\xf1\x81\xf9\x80\x00\x00\x00\x72\x68\x81\xee\x80\x00\x00\x00\x81\xef\x80\x00\x00\x00\xf3\x0f\x6f\x06\xf3\x0f\x6f\x4e\x10\xf3\x0f\x6f\x56\x20\xf3\x0f\x6f\x5e\x30\xf3\x0f\x6f\x66\x40\xf3\x0f\x6f\x6e\x50\xf3\x0f\x6f\x76\x60\xf3\x0f\x6f\x7e\x70\xf3\x0f\x7f\x07\xf3\x0f\x7f\x4f\x10\xf3\x0f\x7f\x57\x20\xf3\x0f\x7f\x5f\x30\xf3\x0f\x7f\x67\x40\xf3\x0f\x7f\x6f\x50\xf3\x0f\x7f\x77\x60\xf3\x0f\x7f\x7f\x70\x81\xe9\x80\x00\x00\x00\xf7\xc1\x80\xff\xff\xff\x75\x90\x83\xf9\x20\x72\x23\x83\xee\x20\x83\xef\x20\xf3\x0f\x6f\x06\xf3\x0f\x6f\x4e\x10\xf3\x0f\x7f\x07\xf3\x0f\x7f\x4f\x10\x83\xe9\x20\xf7\xc1\xe0\xff\xff\xff\x75\xdd\xf7\xc1\xfc\xff\xff\xff\x74\x15\x83\xef\x04\x83\xee\x04\x8b\x06\x89\x07\x83\xe9\x04\xf7\xc1\xfc\xff\xff\xff\x75\xeb\x85\xc9\x74\x0f\x83\xef\x01\x83\xee\x01\x8a\x06\x88\x07\x83\xe9\x01\x75\xf1\x8b\x44\x24\x0c\x5e\x5f\xc3\xeb\x03\xcc\xcc\xcc\x8b\xc6\x83\xe0\x0f\x85\xc0\x0f\x85\xe3\x00\x00\x00\x8b\xd1\x83\xe1\x7f\xc1\xea\x07\x74\x66\x8d\xa4\x24\x00\x00\x00\x00\x8b\xff\x66\x0f\x6f\x06\x66\x0f\x6f\x4e\x10\x66\x0f\x6f\x56\x20\x66\x0f\x6f\x5e\x30\x66\x0f\x7f\x07\x66\x0f\x7f\x4f\x10\x66\x0f\x7f\x57\x20\x66\x0f\x7f\x5f\x30\x66\x0f\x6f\x66\x40\x66\x0f\x6f\x6e\x50\x66\x0f\x6f\x76\x60\x66\x0f\x6f\x7e\x70\x66\x0f\x7f\x67\x40\x66\x0f\x7f\x6f\x50\x66\x0f\x7f\x77\x60\x66\x0f\x7f\x7f\x70\x8d\xb6\x80\x00\x00\x00\x8d\xbf\x80\x00\x00\x00\x4a\x75\xa3\x85\xc9\x74\x5f\x8b\xd1\xc1\xea\x05\x85\xd2\x74\x21\x8d\x9b\x00\x00\x00\x00\xf3\x0f\x6f\x06\xf3\x0f\x6f\x4e\x10\xf3\x0f\x7f\x07\xf3\x0f\x7f\x4f\x10\x8d\x76\x20\x8d\x7f\x20\x4a\x75\xe5\x83\xe1\x1f\x74\x30\x8b\xc1\xc1\xe9\x02\x74\x0f\x8b\x16\x89\x17\x83\xc7\x04\x83\xc6\x04\x83\xe9\x01\x75\xf1\x8b\xc8\x83\xe1\x03\x74\x13\x8a\x06\x88\x07\x46\x47\x49\x75\xf7\x8d\xa4\x24\x00\x00\x00\x00\x8d\x49\x00\x8b\x44\x24\x0c\x5e\x5f\xc3\x8d\xa4\x24\x00\x00\x00\x00\x8b\xff\xba\x10\x00\x00\x00\x2b\xd0\x2b\xca\x51\x8b\xc2\x8b\xc8\x83\xe1\x03\x74\x09\x8a\x16\x88\x17\x46\x47\x49\x75\xf7\xc1\xe8\x02\x74\x0d\x8b\x16\x89\x17\x8d\x76\x04\x8d\x7f\x04\x48\x75\xf3\x59\xe9\xe9\xfe\xff\xff\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x55\x8b\xec\x57\x83\x3d\x2c\x7b\x01\x10\x01\x0f\x82\xfd\x00\x00\x00\x8b\x7d\x08\x77\x77\x0f\xb6\x55\x0c\x8b\xc2\xc1\xe2\x08\x0b\xd0\x66\x0f\x6e\xda\xf2\x0f\x70\xdb\x00\x0f\x16\xdb\xb9\x0f\x00\x00\x00\x23\xcf\x83\xc8\xff\xd3\xe0\x2b\xf9\x33\xd2\xf3\x0f\x6f\x0f\x66\x0f\xef\xd2\x66\x0f\x74\xd1\x66\x0f\x74\xcb\x66\x0f\xd7\xca\x23\xc8\x75\x18\x66\x0f\xd7\xc9\x23\xc8\x0f\xbd\xc1\x03\xc7\x85\xc9\x0f\x45\xd0\x83\xc8\xff\x83\xc7\x10\xeb\xd0\x53\x66\x0f\xd7\xd9\x23\xd8\xd1\xe1\x33\xc0\x2b\xc1\x23\xc8\x49\x23\xcb\x5b\x0f\xbd\xc1\x03\xc7\x85\xc9\x0f\x44\xc2\x5f\xc9\xc3\x0f\xb6\x55\x0c\x85\xd2\x74\x39\x33\xc0\xf7\xc7\x0f\x00\x00\x00\x74\x15\x0f\xb6\x0f\x3b\xca\x0f\x44\xc7\x85\xc9\x74\x20\x47\xf7\xc7\x0f\x00\x00\x00\x75\xeb\x66\x0f\x6e\xc2\x83\xc7\x10\x66\x0f\x3a\x63\x47\xf0\x40\x8d\x4c\x0f\xf0\x0f\x42\xc1\x75\xed\x5f\xc9\xc3\xb8\xf0\xff\xff\xff\x23\xc7\x66\x0f\xef\xc0\x66\x0f\x74\x00\xb9\x0f\x00\x00\x00\x23\xcf\xba\xff\xff\xff\xff\xd3\xe2\x66\x0f\xd7\xf8\x23\xfa\x75\x14\x66\x0f\xef\xc0\x66\x0f\x74\x40\x10\x83\xc0\x10\x66\x0f\xd7\xf8\x85\xff\x74\xec\x0f\xbc\xd7\x03\xc2\xeb\xbd\x8b\x7d\x08\x33\xc0\x83\xc9\xff\xf2\xae\x83\xc1\x01\xf7\xd9\x83\xef\x01\x8a\x45\x0c\xfd\xf2\xae\x83\xc7\x01\x38\x07\x74\x04\x33\xc0\xeb\x02\x8b\xc7\xfc\x5f\xc9\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x83\x3d\x2c\x7b\x01\x10\x01\x72\x5f\x0f\xb6\x44\x24\x08\x8b\xd0\xc1\xe0\x08\x0b\xd0\x66\x0f\x6e\xda\xf2\x0f\x70\xdb\x00\x0f\x16\xdb\x8b\x54\x24\x04\xb9\x0f\x00\x00\x00\x83\xc8\xff\x23\xca\xd3\xe0\x2b\xd1\xf3\x0f\x6f\x0a\x66\x0f\xef\xd2\x66\x0f\x74\xd1\x66\x0f\x74\xcb\x66\x0f\xeb\xd1\x66\x0f\xd7\xca\x23\xc8\x75\x08\x83\xc8\xff\x83\xc2\x10\xeb\xdc\x0f\xbc\xc1\x03\xc2\x66\x0f\x7e\xda\x33\xc9\x3a\x10\x0f\x45\xc1\xc3\x33\xc0\x8a\x44\x24\x08\x53\x8b\xd8\xc1\xe0\x08\x8b\x54\x24\x08\xf7\xc2\x03\x00\x00\x00\x74\x15\x8a\x0a\x83\xc2\x01\x3a\xcb\x74\x59\x84\xc9\x74\x51\xf7\xc2\x03\x00\x00\x00\x75\xeb\x0b\xd8\x57\x8b\xc3\xc1\xe3\x10\x56\x0b\xd8\x8b\x0a\xbf\xff\xfe\xfe\x7e\x8b\xc1\x8b\xf7\x33\xcb\x03\xf0\x03\xf9\x83\xf1\xff\x83\xf0\xff\x33\xcf\x33\xc6\x83\xc2\x04\x81\xe1\x00\x01\x01\x81\x75\x21\x25\x00\x01\x01\x81\x74\xd3\x25\x00\x01\x01\x01\x75\x08\x81\xe6\x00\x00\x00\x80\x75\xc4\x5e\x5f\x5b\x33\xc0\xc3\x8d\x42\xff\x5b\xc3\x8b\x42\xfc\x3a\xc3\x74\x36\x84\xc0\x74\xea\x3a\xe3\x74\x27\x84\xe4\x74\xe2\xc1\xe8\x10\x3a\xc3\x74\x15\x84\xc0\x74\xd7\x3a\xe3\x74\x06\x84\xe4\x74\xcf\xeb\x91\x5e\x5f\x8d\x42\xff\x5b\xc3\x8d\x42\xfe\x5e\x5f\x5b\xc3\x8d\x42\xfd\x5e\x5f\x5b\xc3\x8d\x42\xfc\x5e\x5f\x5b\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x67\x01\x00\x00\x00\x00\x00\xfe\x60\x01\x00\xec\x60\x01\x00\xf2\x66\x01\x00\xe2\x66\x01\x00\xd4\x66\x01\x00\xc4\x66\x01\x00\xb0\x66\x01\x00\xa2\x66\x01\x00\x94\x66\x01\x00\x88\x66\x01\x00\x78\x66\x01\x00\x66\x66\x01\x00\x56\x66\x01\x00\x4a\x66\x01\x00\x36\x66\x01\x00\x24\x66\x01\x00\x12\x66\x01\x00\x00\x66\x01\x00\xee\x65\x01\x00\xb8\x62\x01\x00\xd4\x62\x01\x00\xf2\x62\x01\x00\x06\x63\x01\x00\x1a\x63\x01\x00\x36\x63\x01\x00\x50\x63\x01\x00\x66\x63\x01\x00\x7c\x63\x01\x00\x96\x63\x01\x00\xac\x63\x01\x00\xc0\x63\x01\x00\xd2\x63\x01\x00\xe8\x63\x01\x00\x00\x64\x01\x00\x28\x64\x01\x00\x34\x64\x01\x00\x42\x64\x01\x00\x50\x64\x01\x00\x5a\x64\x01\x00\x68\x64\x01\x00\x7a\x64\x01\x00\x8c\x64\x01\x00\x98\x64\x01\x00\xa8\x64\x01\x00\xc0\x64\x01\x00\xd8\x64\x01\x00\xf0\x64\x01\x00\xfe\x64\x01\x00\x14\x65\x01\x00\x2a\x65\x01\x00\x40\x65\x01\x00\x4c\x65\x01\x00\x58\x65\x01\x00\x68\x65\x01\x00\x78\x65\x01\x00\x86\x65\x01\x00\x90\x65\x01\x00\xa2\x65\x01\x00\xae\x65\x01\x00\xba\x65\x01\x00\xd4\x65\x01\x00\xdc\x60\x01\x00\x00\x00\x00\x00\x98\x62\x01\x00\x00\x00\x00\x00\x7a\x62\x01\x00\x66\x62\x01\x00\x52\x62\x01\x00\x44\x62\x01\x00\x30\x62\x01\x00\x1c\x62\x01\x00\x0e\x62\x01\x00\x00\x62\x01\x00\xee\x61\x01\x00\xd0\x61\x01\x00\xbe\x61\x01\x00\xaa\x61\x01\x00\x9c\x61\x01\x00\x90\x61\x01\x00\x7e\x61\x01\x00\x6c\x61\x01\x00\x58\x61\x01\x00\x46\x61\x01\x00\x30\x61\x01\x00\x20\x61\x01\x00\xde\x61\x01\x00\x00\x00\x00\x00\x08\x24\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x31\x00\x10\xad\xbf\x00\x10\x9c\xcd\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x89\x7b\x00\x10\x19\xc8\x00\x10\x0f\x32\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x77\x01\x10\x28\x78\x01\x10\x18\x70\x01\x10\x00\x00\x00\x00\x4d\x61\x69\x6e\x20\x49\x6e\x76\x6f\x6b\x65\x64\x2e\x00\x00\x00\x4d\x61\x69\x6e\x20\x52\x65\x74\x75\x72\x6e\x65\x64\x2e\x00\x00\xe4\x01\x01\x10\xf8\x01\x01\x10\x34\x02\x01\x10\x70\x02\x01\x10\x61\x00\x64\x00\x76\x00\x61\x00\x70\x00\x69\x00\x33\x00\x32\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x66\x00\x69\x00\x62\x00\x65\x00\x72\x00\x73\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x31\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x73\x00\x79\x00\x6e\x00\x63\x00\x68\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x32\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x6b\x00\x65\x00\x72\x00\x6e\x00\x65\x00\x6c\x00\x33\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x45\x76\x65\x6e\x74\x52\x65\x67\x69\x73\x74\x65\x72\x00\x00\x00\x00\x00\x00\x00\x45\x76\x65\x6e\x74\x53\x65\x74\x49\x6e\x66\x6f\x72\x6d\x61\x74\x69\x6f\x6e\x00\x00\x00\x00\x00\x45\x76\x65\x6e\x74\x55\x6e\x72\x65\x67\x69\x73\x74\x65\x72\x00\x00\x00\x00\x00\x45\x76\x65\x6e\x74\x57\x72\x69\x74\x65\x54\x72\x61\x6e\x73\x66\x65\x72\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x46\x6c\x73\x41\x6c\x6c\x6f\x63\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x46\x6c\x73\x46\x72\x65\x65\x00\x01\x00\x00\x00\x03\x00\x00\x00\x46\x6c\x73\x47\x65\x74\x56\x61\x6c\x75\x65\x00\x01\x00\x00\x00\x03\x00\x00\x00\x46\x6c\x73\x53\x65\x74\x56\x61\x6c\x75\x65\x00\x02\x00\x00\x00\x03\x00\x00\x00\x49\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x45\x78\x00\x00\x00\x00\x00\xe0\x04\x01\x10\xec\x04\x01\x10\xf4\x04\x01\x10\x00\x05\x01\x10\x0c\x05\x01\x10\x18\x05\x01\x10\x24\x05\x01\x10\x34\x05\x01\x10\x40\x05\x01\x10\x48\x05\x01\x10\x50\x05\x01\x10\x5c\x05\x01\x10\x68\x05\x01\x10\xb0\x01\x01\x10\x74\x05\x01\x10\x7c\x05\x01\x10\x84\x05\x01\x10\x88\x05\x01\x10\x8c\x05\x01\x10\x90\x05\x01\x10\x94\x05\x01\x10\x98\x05\x01\x10\x9c\x05\x01\x10\xa0\x05\x01\x10\xac\x05\x01\x10\xb0\x05\x01\x10\xb4\x05\x01\x10\xb8\x05\x01\x10\xbc\x05\x01\x10\xc0\x05\x01\x10\xc4\x05\x01\x10\xc8\x05\x01\x10\xcc\x05\x01\x10\xd0\x05\x01\x10\xd4\x05\x01\x10\xd8\x05\x01\x10\xdc\x05\x01\x10\xe0\x05\x01\x10\xe4\x05\x01\x10\xe8\x05\x01\x10\xec\x05\x01\x10\xf0\x05\x01\x10\xf4\x05\x01\x10\xf8\x05\x01\x10\xfc\x05\x01\x10\x00\x06\x01\x10\x04\x06\x01\x10\x08\x06\x01\x10\x0c\x06\x01\x10\x10\x06\x01\x10\x14\x06\x01\x10\x18\x06\x01\x10\x1c\x06\x01\x10\x20\x06\x01\x10\x24\x06\x01\x10\x28\x06\x01\x10\x34\x06\x01\x10\x40\x06\x01\x10\x48\x06\x01\x10\x54\x06\x01\x10\x6c\x06\x01\x10\x78\x06\x01\x10\x8c\x06\x01\x10\xac\x06\x01\x10\xcc\x06\x01\x10\xec\x06\x01\x10\x0c\x07\x01\x10\x2c\x07\x01\x10\x50\x07\x01\x10\x6c\x07\x01\x10\x90\x07\x01\x10\xb0\x07\x01\x10\xd8\x07\x01\x10\xf4\x07\x01\x10\x04\x08\x01\x10\x08\x08\x01\x10\x10\x08\x01\x10\x20\x08\x01\x10\x44\x08\x01\x10\x4c\x08\x01\x10\x58\x08\x01\x10\x68\x08\x01\x10\x84\x08\x01\x10\xa4\x08\x01\x10\xcc\x08\x01\x10\xf4\x08\x01\x10\x1c\x09\x01\x10\x48\x09\x01\x10\x64\x09\x01\x10\x88\x09\x01\x10\xac\x09\x01\x10\xd8\x09\x01\x10\x04\x0a\x01\x10\x20\x0a\x01\x10\xb0\x01\x01\x10\x30\x0a\x01\x10\x44\x0a\x01\x10\x60\x0a\x01\x10\x74\x0a\x01\x10\x94\x0a\x01\x10\x5f\x5f\x62\x61\x73\x65\x64\x28\x00\x00\x00\x00\x5f\x5f\x63\x64\x65\x63\x6c\x00\x5f\x5f\x70\x61\x73\x63\x61\x6c\x00\x00\x00\x00\x5f\x5f\x73\x74\x64\x63\x61\x6c\x6c\x00\x00\x00\x5f\x5f\x74\x68\x69\x73\x63\x61\x6c\x6c\x00\x00\x5f\x5f\x66\x61\x73\x74\x63\x61\x6c\x6c\x00\x00\x5f\x5f\x76\x65\x63\x74\x6f\x72\x63\x61\x6c\x6c\x00\x00\x00\x00\x5f\x5f\x63\x6c\x72\x63\x61\x6c\x6c\x00\x00\x00\x5f\x5f\x65\x61\x62\x69\x00\x00\x5f\x5f\x70\x74\x72\x36\x34\x00\x5f\x5f\x72\x65\x73\x74\x72\x69\x63\x74\x00\x00\x5f\x5f\x75\x6e\x61\x6c\x69\x67\x6e\x65\x64\x00\x72\x65\x73\x74\x72\x69\x63\x74\x28\x00\x00\x00\x20\x6e\x65\x77\x00\x00\x00\x00\x20\x64\x65\x6c\x65\x74\x65\x00\x3d\x00\x00\x00\x3e\x3e\x00\x00\x3c\x3c\x00\x00\x21\x00\x00\x00\x3d\x3d\x00\x00\x21\x3d\x00\x00\x5b\x5d\x00\x00\x6f\x70\x65\x72\x61\x74\x6f\x72\x00\x00\x00\x00\x2d\x3e\x00\x00\x2a\x00\x00\x00\x2b\x2b\x00\x00\x2d\x2d\x00\x00\x2d\x00\x00\x00\x2b\x00\x00\x00\x26\x00\x00\x00\x2d\x3e\x2a\x00\x2f\x00\x00\x00\x25\x00\x00\x00\x3c\x00\x00\x00\x3c\x3d\x00\x00\x3e\x00\x00\x00\x3e\x3d\x00\x00\x2c\x00\x00\x00\x28\x29\x00\x00\x7e\x00\x00\x00\x5e\x00\x00\x00\x7c\x00\x00\x00\x26\x26\x00\x00\x7c\x7c\x00\x00\x2a\x3d\x00\x00\x2b\x3d\x00\x00\x2d\x3d\x00\x00\x2f\x3d\x00\x00\x25\x3d\x00\x00\x3e\x3e\x3d\x00\x3c\x3c\x3d\x00\x26\x3d\x00\x00\x7c\x3d\x00\x00\x5e\x3d\x00\x00\x60\x76\x66\x74\x61\x62\x6c\x65\x27\x00\x00\x00\x60\x76\x62\x74\x61\x62\x6c\x65\x27\x00\x00\x00\x60\x76\x63\x61\x6c\x6c\x27\x00\x60\x74\x79\x70\x65\x6f\x66\x27\x00\x00\x00\x00\x60\x6c\x6f\x63\x61\x6c\x20\x73\x74\x61\x74\x69\x63\x20\x67\x75\x61\x72\x64\x27\x00\x00\x00\x00\x60\x73\x74\x72\x69\x6e\x67\x27\x00\x00\x00\x00\x60\x76\x62\x61\x73\x65\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x27\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x64\x65\x6c\x65\x74\x69\x6e\x67\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x64\x65\x66\x61\x75\x6c\x74\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x00\x00\x60\x73\x63\x61\x6c\x61\x72\x20\x64\x65\x6c\x65\x74\x69\x6e\x67\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x76\x62\x61\x73\x65\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x60\x76\x69\x72\x74\x75\x61\x6c\x20\x64\x69\x73\x70\x6c\x61\x63\x65\x6d\x65\x6e\x74\x20\x6d\x61\x70\x27\x00\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x76\x62\x61\x73\x65\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x60\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x00\x60\x75\x64\x74\x20\x72\x65\x74\x75\x72\x6e\x69\x6e\x67\x27\x00\x60\x45\x48\x00\x60\x52\x54\x54\x49\x00\x00\x00\x60\x6c\x6f\x63\x61\x6c\x20\x76\x66\x74\x61\x62\x6c\x65\x27\x00\x60\x6c\x6f\x63\x61\x6c\x20\x76\x66\x74\x61\x62\x6c\x65\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x20\x6e\x65\x77\x5b\x5d\x00\x00\x20\x64\x65\x6c\x65\x74\x65\x5b\x5d\x00\x00\x00\x60\x6f\x6d\x6e\x69\x20\x63\x61\x6c\x6c\x73\x69\x67\x27\x00\x00\x60\x70\x6c\x61\x63\x65\x6d\x65\x6e\x74\x20\x64\x65\x6c\x65\x74\x65\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x00\x60\x70\x6c\x61\x63\x65\x6d\x65\x6e\x74\x20\x64\x65\x6c\x65\x74\x65\x5b\x5d\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x00\x00\x00\x60\x6d\x61\x6e\x61\x67\x65\x64\x20\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x60\x6d\x61\x6e\x61\x67\x65\x64\x20\x76\x65\x63\x74\x6f\x72\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x76\x62\x61\x73\x65\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x60\x64\x79\x6e\x61\x6d\x69\x63\x20\x69\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x72\x20\x66\x6f\x72\x20\x27\x00\x00\x60\x64\x79\x6e\x61\x6d\x69\x63\x20\x61\x74\x65\x78\x69\x74\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x66\x6f\x72\x20\x27\x00\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x76\x62\x61\x73\x65\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x6d\x61\x6e\x61\x67\x65\x64\x20\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x60\x6c\x6f\x63\x61\x6c\x20\x73\x74\x61\x74\x69\x63\x20\x74\x68\x72\x65\x61\x64\x20\x67\x75\x61\x72\x64\x27\x00\x6f\x70\x65\x72\x61\x74\x6f\x72\x20\x22\x22\x20\x00\x00\x00\x00\x20\x54\x79\x70\x65\x20\x44\x65\x73\x63\x72\x69\x70\x74\x6f\x72\x27\x00\x00\x00\x20\x42\x61\x73\x65\x20\x43\x6c\x61\x73\x73\x20\x44\x65\x73\x63\x72\x69\x70\x74\x6f\x72\x20\x61\x74\x20\x28\x00\x20\x42\x61\x73\x65\x20\x43\x6c\x61\x73\x73\x20\x41\x72\x72\x61\x79\x27\x00\x00\x20\x43\x6c\x61\x73\x73\x20\x48\x69\x65\x72\x61\x72\x63\x68\x79\x20\x44\x65\x73\x63\x72\x69\x70\x74\x6f\x72\x27\x00\x00\x00\x00\x20\x43\x6f\x6d\x70\x6c\x65\x74\x65\x20\x4f\x62\x6a\x65\x63\x74\x20\x4c\x6f\x63\x61\x74\x6f\x72\x27\x00\x00\x00\x06\x00\x00\x06\x00\x01\x00\x00\x10\x00\x03\x06\x00\x06\x02\x10\x04\x45\x45\x45\x05\x05\x05\x05\x05\x35\x30\x00\x50\x00\x00\x00\x00\x28\x20\x38\x50\x58\x07\x08\x00\x37\x30\x30\x57\x50\x07\x00\x00\x20\x20\x08\x07\x00\x00\x00\x08\x60\x68\x60\x60\x60\x60\x00\x00\x78\x70\x78\x78\x78\x78\x08\x07\x08\x07\x00\x07\x00\x08\x08\x08\x00\x00\x08\x07\x08\x00\x07\x08\x00\x07\x00\x28\x6e\x75\x6c\x6c\x29\x00\x00\x28\x00\x6e\x00\x75\x00\x6c\x00\x6c\x00\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\xc0\x0b\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\xc0\x04\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\xc0\x04\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x92\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\xb4\x02\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\xb5\x02\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00\x09\x00\x00\x00\x6d\x00\x73\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x65\x00\x2e\x00\x64\x00\x6c\x00\x6c\x00\x00\x00\x43\x6f\x72\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x00\x00\x00\x00\x00\x91\x51\x00\x10\x00\x00\x00\x00\xc5\x51\x00\x10\x00\x00\x00\x00\x06\x5e\x00\x10\xb3\x5e\x00\x10\x6c\x85\x00\x10\x6c\x85\x00\x10\xdb\x7b\x00\x10\x33\x7c\x00\x10\x38\x85\x00\x10\x49\x85\x00\x10\x00\x00\x00\x00\x02\x52\x00\x10\x77\x6f\x00\x10\xa3\x6f\x00\x10\xc1\x62\x00\x10\x17\x63\x00\x10\x53\x85\x00\x10\x6c\x85\x00\x10\x55\x81\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x85\x00\x10\x00\x00\x00\x00\x0b\x52\x00\x10\x6c\x85\x00\x10\xbd\x51\x00\x10\xa3\x51\x00\x10\x6c\x85\x00\x10\x01\x00\x00\x00\x16\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x18\x00\x00\x00\x05\x00\x00\x00\x0d\x00\x00\x00\x06\x00\x00\x00\x09\x00\x00\x00\x07\x00\x00\x00\x0c\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x09\x00\x00\x00\x0c\x00\x00\x00\x0a\x00\x00\x00\x07\x00\x00\x00\x0b\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x16\x00\x00\x00\x0d\x00\x00\x00\x16\x00\x00\x00\x0f\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x0d\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x21\x00\x00\x00\x0d\x00\x00\x00\x35\x00\x00\x00\x02\x00\x00\x00\x41\x00\x00\x00\x0d\x00\x00\x00\x43\x00\x00\x00\x02\x00\x00\x00\x50\x00\x00\x00\x11\x00\x00\x00\x52\x00\x00\x00\x0d\x00\x00\x00\x53\x00\x00\x00\x0d\x00\x00\x00\x57\x00\x00\x00\x16\x00\x00\x00\x59\x00\x00\x00\x0b\x00\x00\x00\x6c\x00\x00\x00\x0d\x00\x00\x00\x6d\x00\x00\x00\x20\x00\x00\x00\x70\x00\x00\x00\x1c\x00\x00\x00\x72\x00\x00\x00\x09\x00\x00\x00\x06\x00\x00\x00\x16\x00\x00\x00\x80\x00\x00\x00\x0a\x00\x00\x00\x81\x00\x00\x00\x0a\x00\x00\x00\x82\x00\x00\x00\x09\x00\x00\x00\x83\x00\x00\x00\x16\x00\x00\x00\x84\x00\x00\x00\x0d\x00\x00\x00\x91\x00\x00\x00\x29\x00\x00\x00\x9e\x00\x00\x00\x0d\x00\x00\x00\xa1\x00\x00\x00\x02\x00\x00\x00\xa4\x00\x00\x00\x0b\x00\x00\x00\xa7\x00\x00\x00\x0d\x00\x00\x00\xb7\x00\x00\x00\x11\x00\x00\x00\xce\x00\x00\x00\x02\x00\x00\x00\xd7\x00\x00\x00\x0b\x00\x00\x00\x18\x07\x00\x00\x0c\x00\x00\x00\x20\x0e\x01\x10\x68\x0e\x01\x10\xf8\x01\x01\x10\xa8\x0e\x01\x10\xe0\x0e\x01\x10\x28\x0f\x01\x10\x88\x0f\x01\x10\xd4\x0f\x01\x10\x34\x02\x01\x10\x10\x10\x01\x10\x50\x10\x01\x10\x8c\x10\x01\x10\xc8\x10\x01\x10\x18\x11\x01\x10\x70\x11\x01\x10\xc8\x11\x01\x10\x10\x12\x01\x10\xe4\x01\x01\x10\x70\x02\x01\x10\x60\x12\x01\x10\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x61\x00\x70\x00\x70\x00\x6d\x00\x6f\x00\x64\x00\x65\x00\x6c\x00\x2d\x00\x72\x00\x75\x00\x6e\x00\x74\x00\x69\x00\x6d\x00\x65\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x31\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x64\x00\x61\x00\x74\x00\x65\x00\x74\x00\x69\x00\x6d\x00\x65\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x31\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x66\x00\x69\x00\x6c\x00\x65\x00\x2d\x00\x6c\x00\x32\x00\x2d\x00\x31\x00\x2d\x00\x31\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x69\x00\x7a\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x32\x00\x2d\x00\x31\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x69\x00\x7a\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x62\x00\x73\x00\x6f\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x32\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x70\x00\x72\x00\x6f\x00\x63\x00\x65\x00\x73\x00\x73\x00\x74\x00\x68\x00\x72\x00\x65\x00\x61\x00\x64\x00\x73\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x32\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x73\x00\x74\x00\x72\x00\x69\x00\x6e\x00\x67\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x73\x00\x79\x00\x73\x00\x69\x00\x6e\x00\x66\x00\x6f\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x32\x00\x2d\x00\x31\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x72\x00\x74\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x78\x00\x73\x00\x74\x00\x61\x00\x74\x00\x65\x00\x2d\x00\x6c\x00\x32\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x72\x00\x74\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x6e\x00\x74\x00\x75\x00\x73\x00\x65\x00\x72\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x73\x00\x65\x00\x63\x00\x75\x00\x72\x00\x69\x00\x74\x00\x79\x00\x2d\x00\x73\x00\x79\x00\x73\x00\x74\x00\x65\x00\x6d\x00\x66\x00\x75\x00\x6e\x00\x63\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x65\x00\x78\x00\x74\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x6b\x00\x65\x00\x72\x00\x6e\x00\x65\x00\x6c\x00\x33\x00\x32\x00\x2d\x00\x70\x00\x61\x00\x63\x00\x6b\x00\x61\x00\x67\x00\x65\x00\x2d\x00\x63\x00\x75\x00\x72\x00\x72\x00\x65\x00\x6e\x00\x74\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x65\x00\x78\x00\x74\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x6e\x00\x74\x00\x75\x00\x73\x00\x65\x00\x72\x00\x2d\x00\x64\x00\x69\x00\x61\x00\x6c\x00\x6f\x00\x67\x00\x62\x00\x6f\x00\x78\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x65\x00\x78\x00\x74\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x6e\x00\x74\x00\x75\x00\x73\x00\x65\x00\x72\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x74\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x75\x00\x73\x00\x65\x00\x72\x00\x33\x00\x32\x00\x00\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x47\x65\x74\x43\x75\x72\x72\x65\x6e\x74\x50\x61\x63\x6b\x61\x67\x65\x49\x64\x00\x08\x00\x00\x00\x12\x00\x00\x00\x04\x00\x00\x00\x12\x00\x00\x00\x4c\x43\x4d\x61\x70\x53\x74\x72\x69\x6e\x67\x45\x78\x00\x00\x00\x04\x00\x00\x00\x12\x00\x00\x00\x4c\x6f\x63\x61\x6c\x65\x4e\x61\x6d\x65\x54\x6f\x4c\x43\x49\x44\x00\x00\x00\x00\x49\x4e\x46\x00\x69\x6e\x66\x00\x4e\x41\x4e\x00\x6e\x61\x6e\x00\x4e\x41\x4e\x28\x53\x4e\x41\x4e\x29\x00\x00\x00\x6e\x61\x6e\x28\x73\x6e\x61\x6e\x29\x00\x00\x00\x4e\x41\x4e\x28\x49\x4e\x44\x29\x00\x00\x00\x00\x6e\x61\x6e\x28\x69\x6e\x64\x29\x00\x00\x00\x00\x65\x2b\x30\x30\x30\x00\x00\x00\x53\x75\x6e\x00\x4d\x6f\x6e\x00\x54\x75\x65\x00\x57\x65\x64\x00\x54\x68\x75\x00\x46\x72\x69\x00\x53\x61\x74\x00\x53\x75\x6e\x64\x61\x79\x00\x00\x4d\x6f\x6e\x64\x61\x79\x00\x00\x54\x75\x65\x73\x64\x61\x79\x00\x57\x65\x64\x6e\x65\x73\x64\x61\x79\x00\x00\x00\x54\x68\x75\x72\x73\x64\x61\x79\x00\x00\x00\x00\x46\x72\x69\x64\x61\x79\x00\x00\x53\x61\x74\x75\x72\x64\x61\x79\x00\x00\x00\x00\x4a\x61\x6e\x00\x46\x65\x62\x00\x4d\x61\x72\x00\x41\x70\x72\x00\x4d\x61\x79\x00\x4a\x75\x6e\x00\x4a\x75\x6c\x00\x41\x75\x67\x00\x53\x65\x70\x00\x4f\x63\x74\x00\x4e\x6f\x76\x00\x44\x65\x63\x00\x4a\x61\x6e\x75\x61\x72\x79\x00\x46\x65\x62\x72\x75\x61\x72\x79\x00\x00\x00\x00\x4d\x61\x72\x63\x68\x00\x00\x00\x41\x70\x72\x69\x6c\x00\x00\x00\x4a\x75\x6e\x65\x00\x00\x00\x00\x4a\x75\x6c\x79\x00\x00\x00\x00\x41\x75\x67\x75\x73\x74\x00\x00\x53\x65\x70\x74\x65\x6d\x62\x65\x72\x00\x00\x00\x4f\x63\x74\x6f\x62\x65\x72\x00\x4e\x6f\x76\x65\x6d\x62\x65\x72\x00\x00\x00\x00\x44\x65\x63\x65\x6d\x62\x65\x72\x00\x00\x00\x00\x41\x4d\x00\x00\x50\x4d\x00\x00\x4d\x4d\x2f\x64\x64\x2f\x79\x79\x00\x00\x00\x00\x64\x64\x64\x64\x2c\x20\x4d\x4d\x4d\x4d\x20\x64\x64\x2c\x20\x79\x79\x79\x79\x00\x48\x48\x3a\x6d\x6d\x3a\x73\x73\x00\x00\x00\x00\x53\x00\x75\x00\x6e\x00\x00\x00\x4d\x00\x6f\x00\x6e\x00\x00\x00\x54\x00\x75\x00\x65\x00\x00\x00\x57\x00\x65\x00\x64\x00\x00\x00\x54\x00\x68\x00\x75\x00\x00\x00\x46\x00\x72\x00\x69\x00\x00\x00\x53\x00\x61\x00\x74\x00\x00\x00\x53\x00\x75\x00\x6e\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x4d\x00\x6f\x00\x6e\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x54\x00\x75\x00\x65\x00\x73\x00\x64\x00\x61\x00\x79\x00\x00\x00\x57\x00\x65\x00\x64\x00\x6e\x00\x65\x00\x73\x00\x64\x00\x61\x00\x79\x00\x00\x00\x54\x00\x68\x00\x75\x00\x72\x00\x73\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x46\x00\x72\x00\x69\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x53\x00\x61\x00\x74\x00\x75\x00\x72\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x4a\x00\x61\x00\x6e\x00\x00\x00\x46\x00\x65\x00\x62\x00\x00\x00\x4d\x00\x61\x00\x72\x00\x00\x00\x41\x00\x70\x00\x72\x00\x00\x00\x4d\x00\x61\x00\x79\x00\x00\x00\x4a\x00\x75\x00\x6e\x00\x00\x00\x4a\x00\x75\x00\x6c\x00\x00\x00\x41\x00\x75\x00\x67\x00\x00\x00\x53\x00\x65\x00\x70\x00\x00\x00\x4f\x00\x63\x00\x74\x00\x00\x00\x4e\x00\x6f\x00\x76\x00\x00\x00\x44\x00\x65\x00\x63\x00\x00\x00\x4a\x00\x61\x00\x6e\x00\x75\x00\x61\x00\x72\x00\x79\x00\x00\x00\x46\x00\x65\x00\x62\x00\x72\x00\x75\x00\x61\x00\x72\x00\x79\x00\x00\x00\x00\x00\x4d\x00\x61\x00\x72\x00\x63\x00\x68\x00\x00\x00\x41\x00\x70\x00\x72\x00\x69\x00\x6c\x00\x00\x00\x4a\x00\x75\x00\x6e\x00\x65\x00\x00\x00\x00\x00\x4a\x00\x75\x00\x6c\x00\x79\x00\x00\x00\x00\x00\x41\x00\x75\x00\x67\x00\x75\x00\x73\x00\x74\x00\x00\x00\x00\x00\x53\x00\x65\x00\x70\x00\x74\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00\x00\x00\x4f\x00\x63\x00\x74\x00\x6f\x00\x62\x00\x65\x00\x72\x00\x00\x00\x4e\x00\x6f\x00\x76\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00\x00\x00\x00\x00\x44\x00\x65\x00\x63\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00\x00\x00\x00\x00\x41\x00\x4d\x00\x00\x00\x00\x00\x50\x00\x4d\x00\x00\x00\x00\x00\x4d\x00\x4d\x00\x2f\x00\x64\x00\x64\x00\x2f\x00\x79\x00\x79\x00\x00\x00\x00\x00\x64\x00\x64\x00\x64\x00\x64\x00\x2c\x00\x20\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x20\x00\x64\x00\x64\x00\x2c\x00\x20\x00\x79\x00\x79\x00\x79\x00\x79\x00\x00\x00\x48\x00\x48\x00\x3a\x00\x6d\x00\x6d\x00\x3a\x00\x73\x00\x73\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x55\x00\x53\x00\x00\x00\x00\x00\x00\x00\x30\x13\x01\x10\x34\x13\x01\x10\x38\x13\x01\x10\x3c\x13\x01\x10\x40\x13\x01\x10\x44\x13\x01\x10\x48\x13\x01\x10\x4c\x13\x01\x10\x54\x13\x01\x10\x5c\x13\x01\x10\x64\x13\x01\x10\x70\x13\x01\x10\x7c\x13\x01\x10\x84\x13\x01\x10\x90\x13\x01\x10\x94\x13\x01\x10\x98\x13\x01\x10\x9c\x13\x01\x10\xa0\x13\x01\x10\xa4\x13\x01\x10\xa8\x13\x01\x10\xac\x13\x01\x10\xb0\x13\x01\x10\xb4\x13\x01\x10\xb8\x13\x01\x10\xbc\x13\x01\x10\xc0\x13\x01\x10\xc8\x13\x01\x10\xd4\x13\x01\x10\xdc\x13\x01\x10\xa0\x13\x01\x10\xe4\x13\x01\x10\xec\x13\x01\x10\xf4\x13\x01\x10\xfc\x13\x01\x10\x08\x14\x01\x10\x10\x14\x01\x10\x1c\x14\x01\x10\x28\x14\x01\x10\x2c\x14\x01\x10\x30\x14\x01\x10\x3c\x14\x01\x10\x50\x14\x01\x10\x01\x00\x00\x00\x00\x00\x00\x00\x5c\x14\x01\x10\x64\x14\x01\x10\x6c\x14\x01\x10\x74\x14\x01\x10\x7c\x14\x01\x10\x84\x14\x01\x10\x8c\x14\x01\x10\x94\x14\x01\x10\xa4\x14\x01\x10\xb4\x14\x01\x10\xc4\x14\x01\x10\xd8\x14\x01\x10\xec\x14\x01\x10\xfc\x14\x01\x10\x10\x15\x01\x10\x18\x15\x01\x10\x20\x15\x01\x10\x28\x15\x01\x10\x30\x15\x01\x10\x38\x15\x01\x10\x40\x15\x01\x10\x48\x15\x01\x10\x50\x15\x01\x10\x58\x15\x01\x10\x60\x15\x01\x10\x68\x15\x01\x10\x70\x15\x01\x10\x80\x15\x01\x10\x94\x15\x01\x10\xa0\x15\x01\x10\x30\x15\x01\x10\xac\x15\x01\x10\xb8\x15\x01\x10\xc4\x15\x01\x10\xd4\x15\x01\x10\xe8\x15\x01\x10\xf8\x15\x01\x10\x0c\x16\x01\x10\x20\x16\x01\x10\x28\x16\x01\x10\x30\x16\x01\x10\x44\x16\x01\x10\x6c\x16\x01\x10\x80\x16\x01\x10\x04\x18\x01\x10\x10\x18\x01\x10\x1c\x18\x01\x10\x28\x18\x01\x10\x6a\x00\x61\x00\x2d\x00\x4a\x00\x50\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x43\x00\x4e\x00\x00\x00\x6b\x00\x6f\x00\x2d\x00\x4b\x00\x52\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x54\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x48\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x10\x00\x10\x00\x10\x00\x10\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x01\x00\x00\x00\x58\x25\x01\x10\x02\x00\x00\x00\x60\x25\x01\x10\x03\x00\x00\x00\x68\x25\x01\x10\x04\x00\x00\x00\x70\x25\x01\x10\x05\x00\x00\x00\x80\x25\x01\x10\x06\x00\x00\x00\x88\x25\x01\x10\x07\x00\x00\x00\x90\x25\x01\x10\x08\x00\x00\x00\x98\x25\x01\x10\x09\x00\x00\x00\xa0\x25\x01\x10\x0a\x00\x00\x00\xa8\x25\x01\x10\x0b\x00\x00\x00\xb0\x25\x01\x10\x0c\x00\x00\x00\xb8\x25\x01\x10\x0d\x00\x00\x00\xc0\x25\x01\x10\x0e\x00\x00\x00\xc8\x25\x01\x10\x0f\x00\x00\x00\xd0\x25\x01\x10\x10\x00\x00\x00\xd8\x25\x01\x10\x11\x00\x00\x00\xe0\x25\x01\x10\x12\x00\x00\x00\xe8\x25\x01\x10\x13\x00\x00\x00\xf0\x25\x01\x10\x14\x00\x00\x00\xf8\x25\x01\x10\x15\x00\x00\x00\x00\x26\x01\x10\x16\x00\x00\x00\x08\x26\x01\x10\x18\x00\x00\x00\x10\x26\x01\x10\x19\x00\x00\x00\x18\x26\x01\x10\x1a\x00\x00\x00\x20\x26\x01\x10\x1b\x00\x00\x00\x28\x26\x01\x10\x1c\x00\x00\x00\x30\x26\x01\x10\x1d\x00\x00\x00\x38\x26\x01\x10\x1e\x00\x00\x00\x40\x26\x01\x10\x1f\x00\x00\x00\x48\x26\x01\x10\x20\x00\x00\x00\x50\x26\x01\x10\x21\x00\x00\x00\x58\x26\x01\x10\x22\x00\x00\x00\x60\x26\x01\x10\x23\x00\x00\x00\x68\x26\x01\x10\x24\x00\x00\x00\x70\x26\x01\x10\x25\x00\x00\x00\x78\x26\x01\x10\x26\x00\x00\x00\x80\x26\x01\x10\x27\x00\x00\x00\x88\x26\x01\x10\x29\x00\x00\x00\x90\x26\x01\x10\x2a\x00\x00\x00\x98\x26\x01\x10\x2b\x00\x00\x00\xa0\x26\x01\x10\x2c\x00\x00\x00\xa8\x26\x01\x10\x2d\x00\x00\x00\xb0\x26\x01\x10\x2f\x00\x00\x00\xb8\x26\x01\x10\x36\x00\x00\x00\xc0\x26\x01\x10\x37\x00\x00\x00\xc8\x26\x01\x10\x38\x00\x00\x00\xd0\x26\x01\x10\x39\x00\x00\x00\xd8\x26\x01\x10\x3e\x00\x00\x00\xe0\x26\x01\x10\x3f\x00\x00\x00\xe8\x26\x01\x10\x40\x00\x00\x00\xf0\x26\x01\x10\x41\x00\x00\x00\xf8\x26\x01\x10\x43\x00\x00\x00\x00\x27\x01\x10\x44\x00\x00\x00\x08\x27\x01\x10\x46\x00\x00\x00\x10\x27\x01\x10\x47\x00\x00\x00\x18\x27\x01\x10\x49\x00\x00\x00\x20\x27\x01\x10\x4a\x00\x00\x00\x28\x27\x01\x10\x4b\x00\x00\x00\x30\x27\x01\x10\x4e\x00\x00\x00\x38\x27\x01\x10\x4f\x00\x00\x00\x40\x27\x01\x10\x50\x00\x00\x00\x48\x27\x01\x10\x56\x00\x00\x00\x50\x27\x01\x10\x57\x00\x00\x00\x58\x27\x01\x10\x5a\x00\x00\x00\x60\x27\x01\x10\x65\x00\x00\x00\x68\x27\x01\x10\x7f\x00\x00\x00\x50\x55\x01\x10\x01\x04\x00\x00\x70\x27\x01\x10\x02\x04\x00\x00\x7c\x27\x01\x10\x03\x04\x00\x00\x88\x27\x01\x10\x04\x04\x00\x00\x28\x18\x01\x10\x05\x04\x00\x00\x94\x27\x01\x10\x06\x04\x00\x00\xa0\x27\x01\x10\x07\x04\x00\x00\xac\x27\x01\x10\x08\x04\x00\x00\xb8\x27\x01\x10\x09\x04\x00\x00\x80\x16\x01\x10\x0b\x04\x00\x00\xc4\x27\x01\x10\x0c\x04\x00\x00\xd0\x27\x01\x10\x0d\x04\x00\x00\xdc\x27\x01\x10\x0e\x04\x00\x00\xe8\x27\x01\x10\x0f\x04\x00\x00\xf4\x27\x01\x10\x10\x04\x00\x00\x00\x28\x01\x10\x11\x04\x00\x00\x04\x18\x01\x10\x12\x04\x00\x00\x1c\x18\x01\x10\x13\x04\x00\x00\x0c\x28\x01\x10\x14\x04\x00\x00\x18\x28\x01\x10\x15\x04\x00\x00\x24\x28\x01\x10\x16\x04\x00\x00\x30\x28\x01\x10\x18\x04\x00\x00\x3c\x28\x01\x10\x19\x04\x00\x00\x48\x28\x01\x10\x1a\x04\x00\x00\x54\x28\x01\x10\x1b\x04\x00\x00\x60\x28\x01\x10\x1c\x04\x00\x00\x6c\x28\x01\x10\x1d\x04\x00\x00\x78\x28\x01\x10\x1e\x04\x00\x00\x84\x28\x01\x10\x1f\x04\x00\x00\x90\x28\x01\x10\x20\x04\x00\x00\x9c\x28\x01\x10\x21\x04\x00\x00\xa8\x28\x01\x10\x22\x04\x00\x00\xb4\x28\x01\x10\x23\x04\x00\x00\xc0\x28\x01\x10\x24\x04\x00\x00\xcc\x28\x01\x10\x25\x04\x00\x00\xd8\x28\x01\x10\x26\x04\x00\x00\xe4\x28\x01\x10\x27\x04\x00\x00\xf0\x28\x01\x10\x29\x04\x00\x00\xfc\x28\x01\x10\x2a\x04\x00\x00\x08\x29\x01\x10\x2b\x04\x00\x00\x14\x29\x01\x10\x2c\x04\x00\x00\x20\x29\x01\x10\x2d\x04\x00\x00\x38\x29\x01\x10\x2f\x04\x00\x00\x44\x29\x01\x10\x32\x04\x00\x00\x50\x29\x01\x10\x34\x04\x00\x00\x5c\x29\x01\x10\x35\x04\x00\x00\x68\x29\x01\x10\x36\x04\x00\x00\x74\x29\x01\x10\x37\x04\x00\x00\x80\x29\x01\x10\x38\x04\x00\x00\x8c\x29\x01\x10\x39\x04\x00\x00\x98\x29\x01\x10\x3a\x04\x00\x00\xa4\x29\x01\x10\x3b\x04\x00\x00\xb0\x29\x01\x10\x3e\x04\x00\x00\xbc\x29\x01\x10\x3f\x04\x00\x00\xc8\x29\x01\x10\x40\x04\x00\x00\xd4\x29\x01\x10\x41\x04\x00\x00\xe0\x29\x01\x10\x43\x04\x00\x00\xec\x29\x01\x10\x44\x04\x00\x00\x04\x2a\x01\x10\x45\x04\x00\x00\x10\x2a\x01\x10\x46\x04\x00\x00\x1c\x2a\x01\x10\x47\x04\x00\x00\x28\x2a\x01\x10\x49\x04\x00\x00\x34\x2a\x01\x10\x4a\x04\x00\x00\x40\x2a\x01\x10\x4b\x04\x00\x00\x4c\x2a\x01\x10\x4c\x04\x00\x00\x58\x2a\x01\x10\x4e\x04\x00\x00\x64\x2a\x01\x10\x4f\x04\x00\x00\x70\x2a\x01\x10\x50\x04\x00\x00\x7c\x2a\x01\x10\x52\x04\x00\x00\x88\x2a\x01\x10\x56\x04\x00\x00\x94\x2a\x01\x10\x57\x04\x00\x00\xa0\x2a\x01\x10\x5a\x04\x00\x00\xb0\x2a\x01\x10\x65\x04\x00\x00\xc0\x2a\x01\x10\x6b\x04\x00\x00\xd0\x2a\x01\x10\x6c\x04\x00\x00\xe0\x2a\x01\x10\x81\x04\x00\x00\xec\x2a\x01\x10\x01\x08\x00\x00\xf8\x2a\x01\x10\x04\x08\x00\x00\x10\x18\x01\x10\x07\x08\x00\x00\x04\x2b\x01\x10\x09\x08\x00\x00\x10\x2b\x01\x10\x0a\x08\x00\x00\x1c\x2b\x01\x10\x0c\x08\x00\x00\x28\x2b\x01\x10\x10\x08\x00\x00\x34\x2b\x01\x10\x13\x08\x00\x00\x40\x2b\x01\x10\x14\x08\x00\x00\x4c\x2b\x01\x10\x16\x08\x00\x00\x58\x2b\x01\x10\x1a\x08\x00\x00\x64\x2b\x01\x10\x1d\x08\x00\x00\x7c\x2b\x01\x10\x2c\x08\x00\x00\x88\x2b\x01\x10\x3b\x08\x00\x00\xa0\x2b\x01\x10\x3e\x08\x00\x00\xac\x2b\x01\x10\x43\x08\x00\x00\xb8\x2b\x01\x10\x6b\x08\x00\x00\xd0\x2b\x01\x10\x01\x0c\x00\x00\xe0\x2b\x01\x10\x04\x0c\x00\x00\xec\x2b\x01\x10\x07\x0c\x00\x00\xf8\x2b\x01\x10\x09\x0c\x00\x00\x04\x2c\x01\x10\x0a\x0c\x00\x00\x10\x2c\x01\x10\x0c\x0c\x00\x00\x1c\x2c\x01\x10\x1a\x0c\x00\x00\x28\x2c\x01\x10\x3b\x0c\x00\x00\x40\x2c\x01\x10\x6b\x0c\x00\x00\x4c\x2c\x01\x10\x01\x10\x00\x00\x5c\x2c\x01\x10\x04\x10\x00\x00\x68\x2c\x01\x10\x07\x10\x00\x00\x74\x2c\x01\x10\x09\x10\x00\x00\x80\x2c\x01\x10\x0a\x10\x00\x00\x8c\x2c\x01\x10\x0c\x10\x00\x00\x98\x2c\x01\x10\x1a\x10\x00\x00\xa4\x2c\x01\x10\x3b\x10\x00\x00\xb0\x2c\x01\x10\x01\x14\x00\x00\xc0\x2c\x01\x10\x04\x14\x00\x00\xcc\x2c\x01\x10\x07\x14\x00\x00\xd8\x2c\x01\x10\x09\x14\x00\x00\xe4\x2c\x01\x10\x0a\x14\x00\x00\xf0\x2c\x01\x10\x0c\x14\x00\x00\xfc\x2c\x01\x10\x1a\x14\x00\x00\x08\x2d\x01\x10\x3b\x14\x00\x00\x20\x2d\x01\x10\x01\x18\x00\x00\x30\x2d\x01\x10\x09\x18\x00\x00\x3c\x2d\x01\x10\x0a\x18\x00\x00\x48\x2d\x01\x10\x0c\x18\x00\x00\x54\x2d\x01\x10\x1a\x18\x00\x00\x60\x2d\x01\x10\x3b\x18\x00\x00\x78\x2d\x01\x10\x01\x1c\x00\x00\x88\x2d\x01\x10\x09\x1c\x00\x00\x94\x2d\x01\x10\x0a\x1c\x00\x00\xa0\x2d\x01\x10\x1a\x1c\x00\x00\xac\x2d\x01\x10\x3b\x1c\x00\x00\xc4\x2d\x01\x10\x01\x20\x00\x00\xd4\x2d\x01\x10\x09\x20\x00\x00\xe0\x2d\x01\x10\x0a\x20\x00\x00\xec\x2d\x01\x10\x3b\x20\x00\x00\xf8\x2d\x01\x10\x01\x24\x00\x00\x08\x2e\x01\x10\x09\x24\x00\x00\x14\x2e\x01\x10\x0a\x24\x00\x00\x20\x2e\x01\x10\x3b\x24\x00\x00\x2c\x2e\x01\x10\x01\x28\x00\x00\x3c\x2e\x01\x10\x09\x28\x00\x00\x48\x2e\x01\x10\x0a\x28\x00\x00\x54\x2e\x01\x10\x01\x2c\x00\x00\x60\x2e\x01\x10\x09\x2c\x00\x00\x6c\x2e\x01\x10\x0a\x2c\x00\x00\x78\x2e\x01\x10\x01\x30\x00\x00\x84\x2e\x01\x10\x09\x30\x00\x00\x90\x2e\x01\x10\x0a\x30\x00\x00\x9c\x2e\x01\x10\x01\x34\x00\x00\xa8\x2e\x01\x10\x09\x34\x00\x00\xb4\x2e\x01\x10\x0a\x34\x00\x00\xc0\x2e\x01\x10\x01\x38\x00\x00\xcc\x2e\x01\x10\x0a\x38\x00\x00\xd8\x2e\x01\x10\x01\x3c\x00\x00\xe4\x2e\x01\x10\x0a\x3c\x00\x00\xf0\x2e\x01\x10\x01\x40\x00\x00\xfc\x2e\x01\x10\x0a\x40\x00\x00\x08\x2f\x01\x10\x0a\x44\x00\x00\x14\x2f\x01\x10\x0a\x48\x00\x00\x20\x2f\x01\x10\x0a\x4c\x00\x00\x2c\x2f\x01\x10\x0a\x50\x00\x00\x38\x2f\x01\x10\x04\x7c\x00\x00\x44\x2f\x01\x10\x1a\x7c\x00\x00\x54\x2f\x01\x10\x61\x00\x72\x00\x00\x00\x00\x00\x62\x00\x67\x00\x00\x00\x00\x00\x63\x00\x61\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x43\x00\x48\x00\x53\x00\x00\x00\x00\x00\x63\x00\x73\x00\x00\x00\x00\x00\x64\x00\x61\x00\x00\x00\x00\x00\x64\x00\x65\x00\x00\x00\x00\x00\x65\x00\x6c\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x00\x00\x00\x00\x65\x00\x73\x00\x00\x00\x00\x00\x66\x00\x69\x00\x00\x00\x00\x00\x66\x00\x72\x00\x00\x00\x00\x00\x68\x00\x65\x00\x00\x00\x00\x00\x68\x00\x75\x00\x00\x00\x00\x00\x69\x00\x73\x00\x00\x00\x00\x00\x69\x00\x74\x00\x00\x00\x00\x00\x6a\x00\x61\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x00\x00\x00\x00\x6e\x00\x6c\x00\x00\x00\x00\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x70\x00\x6c\x00\x00\x00\x00\x00\x70\x00\x74\x00\x00\x00\x00\x00\x72\x00\x6f\x00\x00\x00\x00\x00\x72\x00\x75\x00\x00\x00\x00\x00\x68\x00\x72\x00\x00\x00\x00\x00\x73\x00\x6b\x00\x00\x00\x00\x00\x73\x00\x71\x00\x00\x00\x00\x00\x73\x00\x76\x00\x00\x00\x00\x00\x74\x00\x68\x00\x00\x00\x00\x00\x74\x00\x72\x00\x00\x00\x00\x00\x75\x00\x72\x00\x00\x00\x00\x00\x69\x00\x64\x00\x00\x00\x00\x00\x75\x00\x6b\x00\x00\x00\x00\x00\x62\x00\x65\x00\x00\x00\x00\x00\x73\x00\x6c\x00\x00\x00\x00\x00\x65\x00\x74\x00\x00\x00\x00\x00\x6c\x00\x76\x00\x00\x00\x00\x00\x6c\x00\x74\x00\x00\x00\x00\x00\x66\x00\x61\x00\x00\x00\x00\x00\x76\x00\x69\x00\x00\x00\x00\x00\x68\x00\x79\x00\x00\x00\x00\x00\x61\x00\x7a\x00\x00\x00\x00\x00\x65\x00\x75\x00\x00\x00\x00\x00\x6d\x00\x6b\x00\x00\x00\x00\x00\x61\x00\x66\x00\x00\x00\x00\x00\x6b\x00\x61\x00\x00\x00\x00\x00\x66\x00\x6f\x00\x00\x00\x00\x00\x68\x00\x69\x00\x00\x00\x00\x00\x6d\x00\x73\x00\x00\x00\x00\x00\x6b\x00\x6b\x00\x00\x00\x00\x00\x6b\x00\x79\x00\x00\x00\x00\x00\x73\x00\x77\x00\x00\x00\x00\x00\x75\x00\x7a\x00\x00\x00\x00\x00\x74\x00\x74\x00\x00\x00\x00\x00\x70\x00\x61\x00\x00\x00\x00\x00\x67\x00\x75\x00\x00\x00\x00\x00\x74\x00\x61\x00\x00\x00\x00\x00\x74\x00\x65\x00\x00\x00\x00\x00\x6b\x00\x6e\x00\x00\x00\x00\x00\x6d\x00\x72\x00\x00\x00\x00\x00\x73\x00\x61\x00\x00\x00\x00\x00\x6d\x00\x6e\x00\x00\x00\x00\x00\x67\x00\x6c\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x6b\x00\x00\x00\x73\x00\x79\x00\x72\x00\x00\x00\x64\x00\x69\x00\x76\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x53\x00\x41\x00\x00\x00\x62\x00\x67\x00\x2d\x00\x42\x00\x47\x00\x00\x00\x63\x00\x61\x00\x2d\x00\x45\x00\x53\x00\x00\x00\x63\x00\x73\x00\x2d\x00\x43\x00\x5a\x00\x00\x00\x64\x00\x61\x00\x2d\x00\x44\x00\x4b\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x44\x00\x45\x00\x00\x00\x65\x00\x6c\x00\x2d\x00\x47\x00\x52\x00\x00\x00\x66\x00\x69\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x46\x00\x52\x00\x00\x00\x68\x00\x65\x00\x2d\x00\x49\x00\x4c\x00\x00\x00\x68\x00\x75\x00\x2d\x00\x48\x00\x55\x00\x00\x00\x69\x00\x73\x00\x2d\x00\x49\x00\x53\x00\x00\x00\x69\x00\x74\x00\x2d\x00\x49\x00\x54\x00\x00\x00\x6e\x00\x6c\x00\x2d\x00\x4e\x00\x4c\x00\x00\x00\x6e\x00\x62\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x70\x00\x6c\x00\x2d\x00\x50\x00\x4c\x00\x00\x00\x70\x00\x74\x00\x2d\x00\x42\x00\x52\x00\x00\x00\x72\x00\x6f\x00\x2d\x00\x52\x00\x4f\x00\x00\x00\x72\x00\x75\x00\x2d\x00\x52\x00\x55\x00\x00\x00\x68\x00\x72\x00\x2d\x00\x48\x00\x52\x00\x00\x00\x73\x00\x6b\x00\x2d\x00\x53\x00\x4b\x00\x00\x00\x73\x00\x71\x00\x2d\x00\x41\x00\x4c\x00\x00\x00\x73\x00\x76\x00\x2d\x00\x53\x00\x45\x00\x00\x00\x74\x00\x68\x00\x2d\x00\x54\x00\x48\x00\x00\x00\x74\x00\x72\x00\x2d\x00\x54\x00\x52\x00\x00\x00\x75\x00\x72\x00\x2d\x00\x50\x00\x4b\x00\x00\x00\x69\x00\x64\x00\x2d\x00\x49\x00\x44\x00\x00\x00\x75\x00\x6b\x00\x2d\x00\x55\x00\x41\x00\x00\x00\x62\x00\x65\x00\x2d\x00\x42\x00\x59\x00\x00\x00\x73\x00\x6c\x00\x2d\x00\x53\x00\x49\x00\x00\x00\x65\x00\x74\x00\x2d\x00\x45\x00\x45\x00\x00\x00\x6c\x00\x76\x00\x2d\x00\x4c\x00\x56\x00\x00\x00\x6c\x00\x74\x00\x2d\x00\x4c\x00\x54\x00\x00\x00\x66\x00\x61\x00\x2d\x00\x49\x00\x52\x00\x00\x00\x76\x00\x69\x00\x2d\x00\x56\x00\x4e\x00\x00\x00\x68\x00\x79\x00\x2d\x00\x41\x00\x4d\x00\x00\x00\x61\x00\x7a\x00\x2d\x00\x41\x00\x5a\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x65\x00\x75\x00\x2d\x00\x45\x00\x53\x00\x00\x00\x6d\x00\x6b\x00\x2d\x00\x4d\x00\x4b\x00\x00\x00\x74\x00\x6e\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x78\x00\x68\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x7a\x00\x75\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x61\x00\x66\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x6b\x00\x61\x00\x2d\x00\x47\x00\x45\x00\x00\x00\x66\x00\x6f\x00\x2d\x00\x46\x00\x4f\x00\x00\x00\x68\x00\x69\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x6d\x00\x74\x00\x2d\x00\x4d\x00\x54\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x6d\x00\x73\x00\x2d\x00\x4d\x00\x59\x00\x00\x00\x6b\x00\x6b\x00\x2d\x00\x4b\x00\x5a\x00\x00\x00\x6b\x00\x79\x00\x2d\x00\x4b\x00\x47\x00\x00\x00\x73\x00\x77\x00\x2d\x00\x4b\x00\x45\x00\x00\x00\x75\x00\x7a\x00\x2d\x00\x55\x00\x5a\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x74\x00\x74\x00\x2d\x00\x52\x00\x55\x00\x00\x00\x62\x00\x6e\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x70\x00\x61\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x67\x00\x75\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x74\x00\x61\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x74\x00\x65\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x6b\x00\x6e\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x6d\x00\x6c\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x6d\x00\x72\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x73\x00\x61\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x6d\x00\x6e\x00\x2d\x00\x4d\x00\x4e\x00\x00\x00\x63\x00\x79\x00\x2d\x00\x47\x00\x42\x00\x00\x00\x67\x00\x6c\x00\x2d\x00\x45\x00\x53\x00\x00\x00\x6b\x00\x6f\x00\x6b\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x73\x00\x79\x00\x72\x00\x2d\x00\x53\x00\x59\x00\x00\x00\x00\x00\x64\x00\x69\x00\x76\x00\x2d\x00\x4d\x00\x56\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x42\x00\x4f\x00\x00\x00\x00\x00\x6e\x00\x73\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x6d\x00\x69\x00\x2d\x00\x4e\x00\x5a\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x49\x00\x51\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x43\x00\x48\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x47\x00\x42\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x4d\x00\x58\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x42\x00\x45\x00\x00\x00\x69\x00\x74\x00\x2d\x00\x43\x00\x48\x00\x00\x00\x6e\x00\x6c\x00\x2d\x00\x42\x00\x45\x00\x00\x00\x6e\x00\x6e\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x70\x00\x74\x00\x2d\x00\x50\x00\x54\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x53\x00\x50\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x76\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x61\x00\x7a\x00\x2d\x00\x41\x00\x5a\x00\x2d\x00\x43\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x53\x00\x45\x00\x00\x00\x6d\x00\x73\x00\x2d\x00\x42\x00\x4e\x00\x00\x00\x75\x00\x7a\x00\x2d\x00\x55\x00\x5a\x00\x2d\x00\x43\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x45\x00\x43\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x45\x00\x47\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x48\x00\x4b\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x41\x00\x54\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x41\x00\x55\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x45\x00\x53\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x43\x00\x41\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x53\x00\x50\x00\x2d\x00\x43\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x50\x00\x45\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4c\x00\x59\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x53\x00\x47\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x4c\x00\x55\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x43\x00\x41\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x47\x00\x54\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x43\x00\x48\x00\x00\x00\x68\x00\x72\x00\x2d\x00\x42\x00\x41\x00\x00\x00\x73\x00\x6d\x00\x6a\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x44\x00\x5a\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x4d\x00\x4f\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x4c\x00\x49\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x4e\x00\x5a\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x43\x00\x52\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x4c\x00\x55\x00\x00\x00\x62\x00\x73\x00\x2d\x00\x42\x00\x41\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6a\x00\x2d\x00\x53\x00\x45\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4d\x00\x41\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x49\x00\x45\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x50\x00\x41\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x4d\x00\x43\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x42\x00\x41\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x61\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x54\x00\x4e\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x44\x00\x4f\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x42\x00\x41\x00\x2d\x00\x43\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x61\x00\x2d\x00\x53\x00\x45\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4f\x00\x4d\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x4a\x00\x4d\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x56\x00\x45\x00\x00\x00\x73\x00\x6d\x00\x73\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x59\x00\x45\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x43\x00\x42\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x43\x00\x4f\x00\x00\x00\x73\x00\x6d\x00\x6e\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x53\x00\x59\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x42\x00\x5a\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x50\x00\x45\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4a\x00\x4f\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x54\x00\x54\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x41\x00\x52\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4c\x00\x42\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x5a\x00\x57\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x45\x00\x43\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4b\x00\x57\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x50\x00\x48\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x43\x00\x4c\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x41\x00\x45\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x55\x00\x59\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x42\x00\x48\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x50\x00\x59\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x51\x00\x41\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x42\x00\x4f\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x53\x00\x56\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x48\x00\x4e\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x4e\x00\x49\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x50\x00\x52\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x43\x00\x48\x00\x54\x00\x00\x00\x00\x00\x73\x00\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x55\x01\x10\x42\x00\x00\x00\xc0\x26\x01\x10\x2c\x00\x00\x00\x80\x36\x01\x10\x71\x00\x00\x00\x58\x25\x01\x10\x00\x00\x00\x00\x8c\x36\x01\x10\xd8\x00\x00\x00\x98\x36\x01\x10\xda\x00\x00\x00\xa4\x36\x01\x10\xb1\x00\x00\x00\xb0\x36\x01\x10\xa0\x00\x00\x00\xbc\x36\x01\x10\x8f\x00\x00\x00\xc8\x36\x01\x10\xcf\x00\x00\x00\xd4\x36\x01\x10\xd5\x00\x00\x00\xe0\x36\x01\x10\xd2\x00\x00\x00\xec\x36\x01\x10\xa9\x00\x00\x00\xf8\x36\x01\x10\xb9\x00\x00\x00\x04\x37\x01\x10\xc4\x00\x00\x00\x10\x37\x01\x10\xdc\x00\x00\x00\x1c\x37\x01\x10\x43\x00\x00\x00\x28\x37\x01\x10\xcc\x00\x00\x00\x34\x37\x01\x10\xbf\x00\x00\x00\x40\x37\x01\x10\xc8\x00\x00\x00\xa8\x26\x01\x10\x29\x00\x00\x00\x4c\x37\x01\x10\x9b\x00\x00\x00\x64\x37\x01\x10\x6b\x00\x00\x00\x68\x26\x01\x10\x21\x00\x00\x00\x7c\x37\x01\x10\x63\x00\x00\x00\x60\x25\x01\x10\x01\x00\x00\x00\x88\x37\x01\x10\x44\x00\x00\x00\x94\x37\x01\x10\x7d\x00\x00\x00\xa0\x37\x01\x10\xb7\x00\x00\x00\x68\x25\x01\x10\x02\x00\x00\x00\xb8\x37\x01\x10\x45\x00\x00\x00\x80\x25\x01\x10\x04\x00\x00\x00\xc4\x37\x01\x10\x47\x00\x00\x00\xd0\x37\x01\x10\x87\x00\x00\x00\x88\x25\x01\x10\x05\x00\x00\x00\xdc\x37\x01\x10\x48\x00\x00\x00\x90\x25\x01\x10\x06\x00\x00\x00\xe8\x37\x01\x10\xa2\x00\x00\x00\xf4\x37\x01\x10\x91\x00\x00\x00\x00\x38\x01\x10\x49\x00\x00\x00\x0c\x38\x01\x10\xb3\x00\x00\x00\x18\x38\x01\x10\xab\x00\x00\x00\x68\x27\x01\x10\x41\x00\x00\x00\x24\x38\x01\x10\x8b\x00\x00\x00\x98\x25\x01\x10\x07\x00\x00\x00\x34\x38\x01\x10\x4a\x00\x00\x00\xa0\x25\x01\x10\x08\x00\x00\x00\x40\x38\x01\x10\xa3\x00\x00\x00\x4c\x38\x01\x10\xcd\x00\x00\x00\x58\x38\x01\x10\xac\x00\x00\x00\x64\x38\x01\x10\xc9\x00\x00\x00\x70\x38\x01\x10\x92\x00\x00\x00\x7c\x38\x01\x10\xba\x00\x00\x00\x88\x38\x01\x10\xc5\x00\x00\x00\x94\x38\x01\x10\xb4\x00\x00\x00\xa0\x38\x01\x10\xd6\x00\x00\x00\xac\x38\x01\x10\xd0\x00\x00\x00\xb8\x38\x01\x10\x4b\x00\x00\x00\xc4\x38\x01\x10\xc0\x00\x00\x00\xd0\x38\x01\x10\xd3\x00\x00\x00\xa8\x25\x01\x10\x09\x00\x00\x00\xdc\x38\x01\x10\xd1\x00\x00\x00\xe8\x38\x01\x10\xdd\x00\x00\x00\xf4\x38\x01\x10\xd7\x00\x00\x00\x00\x39\x01\x10\xca\x00\x00\x00\x0c\x39\x01\x10\xb5\x00\x00\x00\x18\x39\x01\x10\xc1\x00\x00\x00\x24\x39\x01\x10\xd4\x00\x00\x00\x30\x39\x01\x10\xa4\x00\x00\x00\x3c\x39\x01\x10\xad\x00\x00\x00\x48\x39\x01\x10\xdf\x00\x00\x00\x54\x39\x01\x10\x93\x00\x00\x00\x60\x39\x01\x10\xe0\x00\x00\x00\x6c\x39\x01\x10\xbb\x00\x00\x00\x78\x39\x01\x10\xce\x00\x00\x00\x84\x39\x01\x10\xe1\x00\x00\x00\x90\x39\x01\x10\xdb\x00\x00\x00\x9c\x39\x01\x10\xde\x00\x00\x00\xa8\x39\x01\x10\xd9\x00\x00\x00\xb4\x39\x01\x10\xc6\x00\x00\x00\x78\x26\x01\x10\x23\x00\x00\x00\xc0\x39\x01\x10\x65\x00\x00\x00\xb0\x26\x01\x10\x2a\x00\x00\x00\xcc\x39\x01\x10\x6c\x00\x00\x00\x90\x26\x01\x10\x26\x00\x00\x00\xd8\x39\x01\x10\x68\x00\x00\x00\xb0\x25\x01\x10\x0a\x00\x00\x00\xe4\x39\x01\x10\x4c\x00\x00\x00\xd0\x26\x01\x10\x2e\x00\x00\x00\xf0\x39\x01\x10\x73\x00\x00\x00\xb8\x25\x01\x10\x0b\x00\x00\x00\xfc\x39\x01\x10\x94\x00\x00\x00\x08\x3a\x01\x10\xa5\x00\x00\x00\x14\x3a\x01\x10\xae\x00\x00\x00\x20\x3a\x01\x10\x4d\x00\x00\x00\x2c\x3a\x01\x10\xb6\x00\x00\x00\x38\x3a\x01\x10\xbc\x00\x00\x00\x50\x27\x01\x10\x3e\x00\x00\x00\x44\x3a\x01\x10\x88\x00\x00\x00\x18\x27\x01\x10\x37\x00\x00\x00\x50\x3a\x01\x10\x7f\x00\x00\x00\xc0\x25\x01\x10\x0c\x00\x00\x00\x5c\x3a\x01\x10\x4e\x00\x00\x00\xd8\x26\x01\x10\x2f\x00\x00\x00\x68\x3a\x01\x10\x74\x00\x00\x00\x20\x26\x01\x10\x18\x00\x00\x00\x74\x3a\x01\x10\xaf\x00\x00\x00\x80\x3a\x01\x10\x5a\x00\x00\x00\xc8\x25\x01\x10\x0d\x00\x00\x00\x8c\x3a\x01\x10\x4f\x00\x00\x00\xa0\x26\x01\x10\x28\x00\x00\x00\x98\x3a\x01\x10\x6a\x00\x00\x00\x58\x26\x01\x10\x1f\x00\x00\x00\xa4\x3a\x01\x10\x61\x00\x00\x00\xd0\x25\x01\x10\x0e\x00\x00\x00\xb0\x3a\x01\x10\x50\x00\x00\x00\xd8\x25\x01\x10\x0f\x00\x00\x00\xbc\x3a\x01\x10\x95\x00\x00\x00\xc8\x3a\x01\x10\x51\x00\x00\x00\xe0\x25\x01\x10\x10\x00\x00\x00\xd4\x3a\x01\x10\x52\x00\x00\x00\xc8\x26\x01\x10\x2d\x00\x00\x00\xe0\x3a\x01\x10\x72\x00\x00\x00\xe8\x26\x01\x10\x31\x00\x00\x00\xec\x3a\x01\x10\x78\x00\x00\x00\x30\x27\x01\x10\x3a\x00\x00\x00\xf8\x3a\x01\x10\x82\x00\x00\x00\xe8\x25\x01\x10\x11\x00\x00\x00\x58\x27\x01\x10\x3f\x00\x00\x00\x04\x3b\x01\x10\x89\x00\x00\x00\x14\x3b\x01\x10\x53\x00\x00\x00\xf0\x26\x01\x10\x32\x00\x00\x00\x20\x3b\x01\x10\x79\x00\x00\x00\x88\x26\x01\x10\x25\x00\x00\x00\x2c\x3b\x01\x10\x67\x00\x00\x00\x80\x26\x01\x10\x24\x00\x00\x00\x38\x3b\x01\x10\x66\x00\x00\x00\x44\x3b\x01\x10\x8e\x00\x00\x00\xb8\x26\x01\x10\x2b\x00\x00\x00\x50\x3b\x01\x10\x6d\x00\x00\x00\x5c\x3b\x01\x10\x83\x00\x00\x00\x48\x27\x01\x10\x3d\x00\x00\x00\x68\x3b\x01\x10\x86\x00\x00\x00\x38\x27\x01\x10\x3b\x00\x00\x00\x74\x3b\x01\x10\x84\x00\x00\x00\xe0\x26\x01\x10\x30\x00\x00\x00\x80\x3b\x01\x10\x9d\x00\x00\x00\x8c\x3b\x01\x10\x77\x00\x00\x00\x98\x3b\x01\x10\x75\x00\x00\x00\xa4\x3b\x01\x10\x55\x00\x00\x00\xf0\x25\x01\x10\x12\x00\x00\x00\xb0\x3b\x01\x10\x96\x00\x00\x00\xbc\x3b\x01\x10\x54\x00\x00\x00\xc8\x3b\x01\x10\x97\x00\x00\x00\xf8\x25\x01\x10\x13\x00\x00\x00\xd4\x3b\x01\x10\x8d\x00\x00\x00\x10\x27\x01\x10\x36\x00\x00\x00\xe0\x3b\x01\x10\x7e\x00\x00\x00\x00\x26\x01\x10\x14\x00\x00\x00\xec\x3b\x01\x10\x56\x00\x00\x00\x08\x26\x01\x10\x15\x00\x00\x00\xf8\x3b\x01\x10\x57\x00\x00\x00\x04\x3c\x01\x10\x98\x00\x00\x00\x10\x3c\x01\x10\x8c\x00\x00\x00\x20\x3c\x01\x10\x9f\x00\x00\x00\x30\x3c\x01\x10\xa8\x00\x00\x00\x10\x26\x01\x10\x16\x00\x00\x00\x40\x3c\x01\x10\x58\x00\x00\x00\x18\x26\x01\x10\x17\x00\x00\x00\x4c\x3c\x01\x10\x59\x00\x00\x00\x40\x27\x01\x10\x3c\x00\x00\x00\x58\x3c\x01\x10\x85\x00\x00\x00\x64\x3c\x01\x10\xa7\x00\x00\x00\x70\x3c\x01\x10\x76\x00\x00\x00\x7c\x3c\x01\x10\x9c\x00\x00\x00\x28\x26\x01\x10\x19\x00\x00\x00\x88\x3c\x01\x10\x5b\x00\x00\x00\x70\x26\x01\x10\x22\x00\x00\x00\x94\x3c\x01\x10\x64\x00\x00\x00\xa0\x3c\x01\x10\xbe\x00\x00\x00\xb0\x3c\x01\x10\xc3\x00\x00\x00\xc0\x3c\x01\x10\xb0\x00\x00\x00\xd0\x3c\x01\x10\xb8\x00\x00\x00\xe0\x3c\x01\x10\xcb\x00\x00\x00\xf0\x3c\x01\x10\xc7\x00\x00\x00\x30\x26\x01\x10\x1a\x00\x00\x00\x00\x3d\x01\x10\x5c\x00\x00\x00\x54\x2f\x01\x10\xe3\x00\x00\x00\x0c\x3d\x01\x10\xc2\x00\x00\x00\x24\x3d\x01\x10\xbd\x00\x00\x00\x3c\x3d\x01\x10\xa6\x00\x00\x00\x54\x3d\x01\x10\x99\x00\x00\x00\x38\x26\x01\x10\x1b\x00\x00\x00\x6c\x3d\x01\x10\x9a\x00\x00\x00\x78\x3d\x01\x10\x5d\x00\x00\x00\xf8\x26\x01\x10\x33\x00\x00\x00\x84\x3d\x01\x10\x7a\x00\x00\x00\x60\x27\x01\x10\x40\x00\x00\x00\x90\x3d\x01\x10\x8a\x00\x00\x00\x20\x27\x01\x10\x38\x00\x00\x00\xa0\x3d\x01\x10\x80\x00\x00\x00\x28\x27\x01\x10\x39\x00\x00\x00\xac\x3d\x01\x10\x81\x00\x00\x00\x40\x26\x01\x10\x1c\x00\x00\x00\xb8\x3d\x01\x10\x5e\x00\x00\x00\xc4\x3d\x01\x10\x6e\x00\x00\x00\x48\x26\x01\x10\x1d\x00\x00\x00\xd0\x3d\x01\x10\x5f\x00\x00\x00\x08\x27\x01\x10\x35\x00\x00\x00\xdc\x3d\x01\x10\x7c\x00\x00\x00\x60\x26\x01\x10\x20\x00\x00\x00\xe8\x3d\x01\x10\x62\x00\x00\x00\x50\x26\x01\x10\x1e\x00\x00\x00\xf4\x3d\x01\x10\x60\x00\x00\x00\x00\x27\x01\x10\x34\x00\x00\x00\x00\x3e\x01\x10\x9e\x00\x00\x00\x18\x3e\x01\x10\x7b\x00\x00\x00\x98\x26\x01\x10\x27\x00\x00\x00\x30\x3e\x01\x10\x69\x00\x00\x00\x3c\x3e\x01\x10\x6f\x00\x00\x00\x48\x3e\x01\x10\x03\x00\x00\x00\x58\x3e\x01\x10\xe2\x00\x00\x00\x68\x3e\x01\x10\x90\x00\x00\x00\x74\x3e\x01\x10\xa1\x00\x00\x00\x80\x3e\x01\x10\xb2\x00\x00\x00\x8c\x3e\x01\x10\xaa\x00\x00\x00\x98\x3e\x01\x10\x46\x00\x00\x00\xa4\x3e\x01\x10\x70\x00\x00\x00\x61\x00\x66\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x61\x00\x65\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x62\x00\x68\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x64\x00\x7a\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x65\x00\x67\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x69\x00\x71\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6a\x00\x6f\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6b\x00\x77\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6c\x00\x62\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6c\x00\x79\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6d\x00\x61\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6f\x00\x6d\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x71\x00\x61\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x73\x00\x61\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x73\x00\x79\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x74\x00\x6e\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x79\x00\x65\x00\x00\x00\x61\x00\x7a\x00\x2d\x00\x61\x00\x7a\x00\x2d\x00\x63\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x61\x00\x7a\x00\x2d\x00\x61\x00\x7a\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x62\x00\x65\x00\x2d\x00\x62\x00\x79\x00\x00\x00\x62\x00\x67\x00\x2d\x00\x62\x00\x67\x00\x00\x00\x62\x00\x6e\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x62\x00\x73\x00\x2d\x00\x62\x00\x61\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x63\x00\x61\x00\x2d\x00\x65\x00\x73\x00\x00\x00\x63\x00\x73\x00\x2d\x00\x63\x00\x7a\x00\x00\x00\x63\x00\x79\x00\x2d\x00\x67\x00\x62\x00\x00\x00\x64\x00\x61\x00\x2d\x00\x64\x00\x6b\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x61\x00\x74\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x63\x00\x68\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x64\x00\x65\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x6c\x00\x69\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x6c\x00\x75\x00\x00\x00\x64\x00\x69\x00\x76\x00\x2d\x00\x6d\x00\x76\x00\x00\x00\x00\x00\x65\x00\x6c\x00\x2d\x00\x67\x00\x72\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x61\x00\x75\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x62\x00\x7a\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x63\x00\x61\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x63\x00\x62\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x67\x00\x62\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x69\x00\x65\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x6a\x00\x6d\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x6e\x00\x7a\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x70\x00\x68\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x74\x00\x74\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x75\x00\x73\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x7a\x00\x77\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x61\x00\x72\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x62\x00\x6f\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x63\x00\x6c\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x63\x00\x6f\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x63\x00\x72\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x64\x00\x6f\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x65\x00\x63\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x65\x00\x73\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x67\x00\x74\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x68\x00\x6e\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x6d\x00\x78\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x6e\x00\x69\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x70\x00\x61\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x70\x00\x65\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x70\x00\x72\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x70\x00\x79\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x73\x00\x76\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x75\x00\x79\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x76\x00\x65\x00\x00\x00\x65\x00\x74\x00\x2d\x00\x65\x00\x65\x00\x00\x00\x65\x00\x75\x00\x2d\x00\x65\x00\x73\x00\x00\x00\x66\x00\x61\x00\x2d\x00\x69\x00\x72\x00\x00\x00\x66\x00\x69\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x66\x00\x6f\x00\x2d\x00\x66\x00\x6f\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x62\x00\x65\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x63\x00\x61\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x63\x00\x68\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x66\x00\x72\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x6c\x00\x75\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x6d\x00\x63\x00\x00\x00\x67\x00\x6c\x00\x2d\x00\x65\x00\x73\x00\x00\x00\x67\x00\x75\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x68\x00\x65\x00\x2d\x00\x69\x00\x6c\x00\x00\x00\x68\x00\x69\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x68\x00\x72\x00\x2d\x00\x62\x00\x61\x00\x00\x00\x68\x00\x72\x00\x2d\x00\x68\x00\x72\x00\x00\x00\x68\x00\x75\x00\x2d\x00\x68\x00\x75\x00\x00\x00\x68\x00\x79\x00\x2d\x00\x61\x00\x6d\x00\x00\x00\x69\x00\x64\x00\x2d\x00\x69\x00\x64\x00\x00\x00\x69\x00\x73\x00\x2d\x00\x69\x00\x73\x00\x00\x00\x69\x00\x74\x00\x2d\x00\x63\x00\x68\x00\x00\x00\x69\x00\x74\x00\x2d\x00\x69\x00\x74\x00\x00\x00\x6a\x00\x61\x00\x2d\x00\x6a\x00\x70\x00\x00\x00\x6b\x00\x61\x00\x2d\x00\x67\x00\x65\x00\x00\x00\x6b\x00\x6b\x00\x2d\x00\x6b\x00\x7a\x00\x00\x00\x6b\x00\x6e\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x6b\x00\x6f\x00\x6b\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x2d\x00\x6b\x00\x72\x00\x00\x00\x6b\x00\x79\x00\x2d\x00\x6b\x00\x67\x00\x00\x00\x6c\x00\x74\x00\x2d\x00\x6c\x00\x74\x00\x00\x00\x6c\x00\x76\x00\x2d\x00\x6c\x00\x76\x00\x00\x00\x6d\x00\x69\x00\x2d\x00\x6e\x00\x7a\x00\x00\x00\x6d\x00\x6b\x00\x2d\x00\x6d\x00\x6b\x00\x00\x00\x6d\x00\x6c\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x6d\x00\x6e\x00\x2d\x00\x6d\x00\x6e\x00\x00\x00\x6d\x00\x72\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x6d\x00\x73\x00\x2d\x00\x62\x00\x6e\x00\x00\x00\x6d\x00\x73\x00\x2d\x00\x6d\x00\x79\x00\x00\x00\x6d\x00\x74\x00\x2d\x00\x6d\x00\x74\x00\x00\x00\x6e\x00\x62\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x6e\x00\x6c\x00\x2d\x00\x62\x00\x65\x00\x00\x00\x6e\x00\x6c\x00\x2d\x00\x6e\x00\x6c\x00\x00\x00\x6e\x00\x6e\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x6e\x00\x73\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x70\x00\x61\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x70\x00\x6c\x00\x2d\x00\x70\x00\x6c\x00\x00\x00\x70\x00\x74\x00\x2d\x00\x62\x00\x72\x00\x00\x00\x70\x00\x74\x00\x2d\x00\x70\x00\x74\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x62\x00\x6f\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x65\x00\x63\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x70\x00\x65\x00\x00\x00\x00\x00\x72\x00\x6f\x00\x2d\x00\x72\x00\x6f\x00\x00\x00\x72\x00\x75\x00\x2d\x00\x72\x00\x75\x00\x00\x00\x73\x00\x61\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x73\x00\x65\x00\x00\x00\x73\x00\x6b\x00\x2d\x00\x73\x00\x6b\x00\x00\x00\x73\x00\x6c\x00\x2d\x00\x73\x00\x69\x00\x00\x00\x73\x00\x6d\x00\x61\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x61\x00\x2d\x00\x73\x00\x65\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6a\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6a\x00\x2d\x00\x73\x00\x65\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6e\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x73\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x00\x00\x73\x00\x71\x00\x2d\x00\x61\x00\x6c\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x62\x00\x61\x00\x2d\x00\x63\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x62\x00\x61\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x73\x00\x70\x00\x2d\x00\x63\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x73\x00\x70\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x76\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x73\x00\x76\x00\x2d\x00\x73\x00\x65\x00\x00\x00\x73\x00\x77\x00\x2d\x00\x6b\x00\x65\x00\x00\x00\x73\x00\x79\x00\x72\x00\x2d\x00\x73\x00\x79\x00\x00\x00\x00\x00\x74\x00\x61\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x74\x00\x65\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x74\x00\x68\x00\x2d\x00\x74\x00\x68\x00\x00\x00\x74\x00\x6e\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x74\x00\x72\x00\x2d\x00\x74\x00\x72\x00\x00\x00\x74\x00\x74\x00\x2d\x00\x72\x00\x75\x00\x00\x00\x75\x00\x6b\x00\x2d\x00\x75\x00\x61\x00\x00\x00\x75\x00\x72\x00\x2d\x00\x70\x00\x6b\x00\x00\x00\x75\x00\x7a\x00\x2d\x00\x75\x00\x7a\x00\x2d\x00\x63\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x75\x00\x7a\x00\x2d\x00\x75\x00\x7a\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x76\x00\x69\x00\x2d\x00\x76\x00\x6e\x00\x00\x00\x78\x00\x68\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x63\x00\x68\x00\x73\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x63\x00\x68\x00\x74\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x63\x00\x6e\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x68\x00\x6b\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x6d\x00\x6f\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x73\x00\x67\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x74\x00\x77\x00\x00\x00\x7a\x00\x75\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x00\xe4\x0b\x54\x02\x00\x00\x00\x00\x00\x10\x63\x2d\x5e\xc7\x6b\x05\x00\x00\x00\x00\x00\x00\x40\xea\xed\x74\x46\xd0\x9c\x2c\x9f\x0c\x00\x00\x00\x00\x61\xf5\xb9\xab\xbf\xa4\x5c\xc3\xf1\x29\x63\x1d\x00\x00\x00\x00\x00\x64\xb5\xfd\x34\x05\xc4\xd2\x87\x66\x92\xf9\x15\x3b\x6c\x44\x00\x00\x00\x00\x00\x00\x10\xd9\x90\x65\x94\x2c\x42\x62\xd7\x01\x45\x22\x9a\x17\x26\x27\x4f\x9f\x00\x00\x00\x40\x02\x95\x07\xc1\x89\x56\x24\x1c\xa7\xfa\xc5\x67\x6d\xc8\x73\xdc\x6d\xad\xeb\x72\x01\x00\x00\x00\x00\xc1\xce\x64\x27\xa2\x63\xca\x18\xa4\xef\x25\x7b\xd1\xcd\x70\xef\xdf\x6b\x1f\x3e\xea\x9d\x5f\x03\x00\x00\x00\x00\x00\xe4\x6e\xfe\xc3\xcd\x6a\x0c\xbc\x66\x32\x1f\x39\x2e\x03\x02\x45\x5a\x25\xf8\xd2\x71\x56\x4a\xc2\xc3\xda\x07\x00\x00\x10\x8f\x2e\xa8\x08\x43\xb2\xaa\x7c\x1a\x21\x8e\x40\xce\x8a\xf3\x0b\xce\xc4\x84\x27\x0b\xeb\x7c\xc3\x94\x25\xad\x49\x12\x00\x00\x00\x40\x1a\xdd\xda\x54\x9f\xcc\xbf\x61\x59\xdc\xab\xab\x5c\xc7\x0c\x44\x05\xf5\x67\x16\xbc\xd1\x52\xaf\xb7\xfb\x29\x8d\x8f\x60\x94\x2a\x00\x00\x00\x00\x00\x21\x0c\x8a\xbb\x17\xa4\x8e\xaf\x56\xa9\x9f\x47\x06\x36\xb2\x4b\x5d\xe0\x5f\xdc\x80\x0a\xaa\xfe\xf0\x40\xd9\x8e\xa8\xd0\x80\x1a\x6b\x23\x63\x00\x00\x64\x38\x4c\x32\x96\xc7\x57\x83\xd5\x42\x4a\xe4\x61\x22\xa9\xd9\x3d\x10\x3c\xbd\x72\xf3\xe5\x91\x74\x15\x59\xc0\x0d\xa6\x1d\xec\x6c\xd9\x2a\x10\xd3\xe6\x00\x00\x00\x10\x85\x1e\x5b\x61\x4f\x6e\x69\x2a\x7b\x18\x1c\xe2\x50\x04\x2b\x34\xdd\x2f\xee\x27\x50\x63\x99\x71\xc9\xa6\x16\xe9\x4a\x8e\x28\x2e\x08\x17\x6f\x6e\x49\x1a\x6e\x19\x02\x00\x00\x00\x40\x32\x26\x40\xad\x04\x50\x72\x1e\xf9\xd5\xd1\x94\x29\xbb\xcd\x5b\x66\x96\x2e\x3b\xa2\xdb\x7d\xfa\x65\xac\x53\xde\x77\x9b\xa2\x20\xb0\x53\xf9\xbf\xc6\xab\x25\x94\x4b\x4d\xe3\x04\x00\x81\x2d\xc3\xfb\xf4\xd0\x22\x52\x50\x28\x0f\xb7\xf3\xf2\x13\x57\x13\x14\x42\xdc\x7d\x5d\x39\xd6\x99\x19\x59\xf8\x1c\x38\x92\x00\xd6\x14\xb3\x86\xb9\x77\xa5\x7a\x61\xfe\xb7\x12\x6a\x61\x0b\x00\x00\xe4\x11\x1d\x8d\x67\xc3\x56\x20\x1f\x94\x3a\x8b\x36\x09\x9b\x08\x69\x70\xbd\xbe\x65\x76\x20\xeb\xc4\x26\x9b\x9d\xe8\x67\x15\x6e\x09\x15\x9d\x2b\xf2\x32\x71\x13\x51\x48\xbe\xce\xa2\xe5\x45\x52\x7f\x1a\x00\x00\x00\x10\xbb\x78\x94\xf7\x02\xc0\x74\x1b\x8c\x00\x5d\xf0\xb0\x75\xc6\xdb\xa9\x14\xb9\xd9\xe2\xdf\x72\x0f\x65\x4c\x4b\x28\x77\x16\xe0\xf6\x6d\xc2\x91\x43\x51\xcf\xc9\x95\x27\x55\xab\xe2\xd6\x27\xe6\xa8\x9c\xa6\xb1\x3d\x00\x00\x00\x00\x40\x4a\xd0\xec\xf4\xf0\x88\x23\x7f\xc5\x6d\x0a\x58\x6f\x04\xbf\x43\xc3\x5d\x2d\xf8\x48\x08\x11\xee\x1c\x59\xa0\xfa\x28\xf0\xf4\xcd\x3f\xa5\x2e\x19\xa0\x71\xd6\xbc\x87\x44\x69\x7d\x01\x6e\xf9\x10\x9d\x56\x1a\x79\x75\xa4\x8f\x00\x00\xe1\xb2\xb9\x3c\x75\x88\x82\x93\x16\x3f\xcd\x6b\x3a\xb4\x89\xde\x87\x9e\x08\x46\x45\x4d\x68\x0c\xa6\xdb\xfd\x91\x93\x24\xdf\x13\xec\x68\x30\x27\x44\xb4\x99\xee\x41\x81\xb6\xc3\xca\x02\x58\xf1\x51\x68\xd9\xa2\x25\x76\x7d\x8d\x71\x4e\x01\x00\x00\x64\xfb\xe6\x83\x5a\xf2\x0f\xad\x57\x94\x11\xb5\x80\x00\x66\xb5\x29\x20\xcf\xd2\xc5\xd7\x7d\x6d\x3f\xa5\x1c\x4d\xb7\xcd\xde\x70\x9d\xda\x3d\x41\x16\xb7\x4e\xca\xd0\x71\x98\x13\xe4\xd7\x90\x3a\x40\x4f\xe2\x3f\xab\xf9\x6f\x77\x4d\x26\xe6\xaf\x0a\x03\x00\x00\x00\x10\x31\x55\xab\x09\xd2\x58\x0c\xa6\xcb\x26\x61\x56\x87\x83\x1c\x6a\xc1\xf4\x87\x75\x76\xe8\x44\x2c\xcf\x47\xa0\x41\x9e\x05\x08\xc9\x3e\x06\xba\xa0\xe8\xc8\xcf\xe7\x55\xc0\xfa\xe1\xb2\x44\x01\xef\xb0\x7e\x20\x24\x73\x25\x72\xd1\x81\xf9\xb8\xe4\xae\x05\x15\x07\x40\x62\x3b\x7a\x4f\x5d\xa4\xce\x33\x41\xe2\x4f\x6d\x6d\x0f\x21\xf2\x33\x56\xe5\x56\x13\xc1\x25\x97\xd7\xeb\x28\x84\xeb\x96\xd3\x77\x3b\x49\x1e\xae\x2d\x1f\x47\x20\x38\xad\x96\xd1\xce\xfa\x8a\xdb\xcd\xde\x4e\x86\xc0\x68\x55\xa1\x5d\x69\xb2\x89\x3c\x12\x24\x71\x45\x7d\x10\x00\x00\x41\x1c\x27\x4a\x17\x6e\x57\xae\x62\xec\xaa\x89\x22\xef\xdd\xfb\xa2\xb6\xe4\xef\xe1\x17\xf2\xbd\x66\x33\x80\x88\xb4\x37\x3e\x2c\xb8\xbf\x91\xde\xac\x19\x08\x64\xf4\xd4\x4e\x6a\xff\x35\x0e\x6a\x56\x67\x14\xb9\xdb\x40\xca\x3b\x2a\x78\x68\x9b\x32\x6b\xd9\xc5\xaf\xf5\xbc\x69\x64\x26\x00\x00\x00\xe4\xf4\x5f\x80\xfb\xaf\xd1\x55\xed\xa8\x20\x4a\x9b\xf8\x57\x97\xab\x0a\xfe\xae\x01\x7b\xa6\x2c\x4a\x69\x95\xbf\x1e\x29\x1c\xc4\xc7\xaa\xd2\xd5\xd8\x76\xc7\x36\xd1\x0c\x55\xda\x93\x90\x9d\xc7\x9a\xa8\xcb\x4b\x25\x18\x76\xf0\x0d\x09\x88\xa8\xf7\x74\x10\x1f\x3a\xfc\x11\x48\xe5\xad\x8e\x63\x59\x10\xe7\xcb\x97\xe8\x69\xd7\x26\x3e\x72\xe4\xb4\x86\xaa\x90\x5b\x22\x39\x33\x9c\x75\x07\x7a\x4b\x91\xe9\x47\x2d\x77\xf9\x6e\x9a\xe7\x40\x0b\x16\xc4\xf8\x92\x0c\x10\xf0\x5f\xf2\x11\x6c\xc3\x25\x42\x8b\xf9\xc9\x9d\x91\x0b\x73\xaf\x7c\xff\x05\x85\x2d\x43\xb0\x69\x75\x2b\x2d\x2c\x84\x57\xa6\x10\xef\x1f\xd0\x00\x40\x7a\xc7\xe5\x62\xb8\xe8\x6a\x88\xd8\x10\xe5\x98\xcd\xc8\xc5\x55\x89\x10\x55\xb6\x59\xd0\xd4\xbe\xfb\x58\x31\x82\xb8\x03\x19\x45\x4c\x03\x39\xc9\x4d\x19\xac\x00\xc5\x1f\xe2\xc0\x4c\x79\xa1\x80\xc9\x3b\xd1\x2d\xb1\xe9\xf8\x22\x6d\x5e\x9a\x89\x38\x7b\xd8\x19\x79\xce\x72\x76\xc6\x78\x9f\xb9\xe5\x79\x4e\x03\x94\xe4\x01\x00\x00\x00\x00\x00\x00\xa1\xe9\xd4\x5c\x6c\x6f\x7d\xe4\x9b\xe7\xd9\x3b\xf9\xa1\x6f\x62\x77\x51\x34\x8b\xc6\xe8\x59\x2b\xde\x58\xde\x3c\xcf\x58\xff\x46\x22\x15\x7c\x57\xa8\x59\x75\xe7\x26\x53\x67\x77\x17\x63\xb7\xe6\xeb\x5f\x0a\xfd\xe3\x69\x39\xe8\x33\x35\xa0\x05\xa8\x87\xb9\x31\xf6\x43\x0f\x1f\x21\xdb\x43\x5a\xd8\x96\xf5\x1b\xab\xa2\x19\x3f\x68\x04\x00\x00\x00\x64\xfe\x7d\xbe\x2f\x04\xc9\x4b\xb0\xed\xf5\xe1\xda\x4e\xa1\x8f\x73\xdb\x09\xe4\x9c\xee\x4f\x67\x0d\x9f\x15\xa9\xd6\xb5\xb5\xf6\x0e\x96\x38\x73\x91\xc2\x49\xeb\xcc\x97\x2b\x5f\x95\x3f\x38\x0f\xf6\xb3\x91\x20\x14\x37\x78\xd1\xdf\x42\xd1\xc1\xde\x22\x3e\x15\x57\xdf\xaf\x8a\x5f\xe5\xf5\x77\x8b\xca\xe7\xa3\x5b\x52\x2f\x03\x3d\x4f\xe7\x42\x0a\x00\x00\x00\x00\x10\xdd\xf4\x52\x09\x45\x5d\xe1\x42\xb4\xae\x2e\x34\xb3\xa3\x6f\xa3\xcd\x3f\x6e\x7a\x28\xb4\xf7\x77\xc1\x4b\xd0\xc8\xd2\x67\xe0\xf8\xa8\xae\x67\x3b\xc9\xad\xb3\x56\xc8\x6c\x0b\x9d\x9d\x95\x00\xc1\x48\x5b\x3d\x8a\xbe\x4a\xf4\x36\xd9\x52\x4d\xe8\xdb\x71\xc5\x21\x1c\xf9\x09\x81\x45\x4a\x6a\xd8\xaa\xd7\x7c\x4c\xe1\x08\x9c\xa5\x9b\x75\x00\x88\x3c\xe4\x17\x00\x00\x00\x00\x00\x40\x92\xd4\x10\xf1\x04\xbe\x72\x64\x18\x0c\xc1\x36\x87\xfb\xab\x78\x14\x29\xaf\x51\xfc\x39\x97\xeb\x25\x15\x30\x2b\x4c\x0b\x0e\x03\xa1\x3b\x3c\xfe\x28\xba\xfc\x88\x77\x58\x43\x9e\xb8\xa4\xe4\x3d\x73\xc2\xf2\x46\x7c\x98\x62\x74\x8f\x0f\x21\x19\xdb\xae\xb6\xa3\x2e\xb2\x14\x50\xaa\x8d\xab\x39\xea\x42\x34\x96\x97\xa9\xdf\xdf\x01\xfe\xd3\xf3\xd2\x80\x02\x79\xa0\x37\x00\x00\x00\x01\x9b\x9c\x50\xf1\xad\xdc\xc7\x2c\xad\x3d\x38\x37\x4d\xc6\x73\xd0\x67\x6d\xea\x06\xa8\x9b\x51\xf8\xf2\x03\xc4\xa2\xe1\x52\xa0\x3a\x23\x10\xd7\xa9\x73\x85\x44\xba\xd9\x12\xcf\x03\x18\x87\x70\x9b\x3a\xdc\x52\xe8\x52\xb2\xe5\x4e\xfb\x17\x07\x2f\xa6\x4d\xbe\xe1\xd7\xab\x0a\x4f\xed\x62\x8c\x7b\xec\xb9\xce\x21\x40\x66\xd4\x00\x83\x15\xa1\xe6\x75\xe3\xcc\xf2\x29\x2f\x84\x81\x00\x00\x00\x00\xe4\x17\x77\x64\xfb\xf5\xd3\x71\x3d\x76\xa0\xe9\x2f\x14\x7d\x66\x4c\xf4\x33\x2e\xf1\xb8\xf3\x8e\x0d\x0f\x13\x69\x94\x4c\x73\xa8\x0f\x26\x60\x40\x13\x01\x3c\x0a\x88\x71\xcc\x21\x2d\xa5\x37\xef\xc9\xda\x8a\xb4\x31\xbb\x42\x41\x4c\xf9\xd6\x6c\x05\x8b\xc8\xb8\x01\x05\xe2\x7c\xed\x97\x52\xc4\x61\xc3\x62\xaa\xd8\xda\x87\xde\xea\x33\xb8\x61\x68\xf0\x94\xbd\x9a\xcc\x13\x6a\xd5\xc1\x8d\x2d\x01\x00\x00\x00\x00\x10\x13\xe8\x36\x7a\xc6\x9e\x29\x16\xf4\x0a\x3f\x49\xf3\xcf\xa6\xa5\x77\xa3\x23\xbe\xa4\x82\x5b\xa2\xcc\x2f\x72\x10\x35\x7f\x44\x9d\xbe\xb8\x13\xc2\xa8\x4e\x32\x4c\xc9\xad\x33\x9e\xbc\xba\xfe\xac\x76\x32\x21\x4c\x2e\x32\xcd\x13\x3e\xb4\x91\xfe\x70\x36\xd9\x5c\xbb\x85\x97\x14\x42\xfd\x1a\xcc\x46\xf8\xdd\x38\xe6\xd2\x87\x07\x69\x17\xd1\x02\x1a\xfe\xf1\xb5\x3e\xae\xab\xb9\xc3\x6f\xee\x08\x1c\xbe\x02\x00\x00\x00\x00\x00\x40\xaa\xc2\x40\x81\xd9\x77\xf8\x2c\x3d\xd7\xe1\x71\x98\x2f\xe7\xd5\x09\x63\x51\x72\xdd\x19\xa8\xaf\x46\x5a\x2a\xd6\xce\xdc\x02\x2a\xfe\xdd\x46\xce\x8d\x24\x13\x27\xad\xd2\x23\xb7\x19\xbb\x04\xc4\x2b\xcc\x06\xb7\xca\xeb\xb1\x47\xdc\x4b\x09\x9d\xca\x02\xdc\xc5\x8e\x51\xe6\x31\x80\x56\xc3\x8e\xa8\x58\x2f\x34\x42\x1e\x04\x8b\x14\xe5\xbf\xfe\x13\xfc\xff\x05\x0f\x79\x63\x67\xfd\x36\xd5\x66\x76\x50\xe1\xb9\x62\x06\x00\x00\x00\x61\xb0\x67\x1a\x0a\x01\xd2\xc0\xe1\x05\xd0\x3b\x73\x12\xdb\x3f\x2e\x9f\xa3\xe2\x9d\xb2\x61\xe2\xdc\x63\x2a\xbc\x04\x26\x94\x9b\xd5\x70\x61\x96\x25\xe3\xc2\xb9\x75\x0b\x14\x21\x2c\x1d\x1f\x60\x6a\x13\xb8\xa2\x3b\xd2\x89\x73\x7d\xf1\x60\xdf\xd7\xca\xc6\x2b\xdf\x69\x06\x37\x87\xb8\x24\xed\x06\x93\x66\xeb\x6e\x49\x19\x6f\xdb\x8d\x93\x75\x82\x74\x5e\x36\x9a\x6e\xc5\x31\xb7\x90\x36\xc5\x42\x28\xc8\x8e\x79\xae\x24\xde\x0e\x00\x00\x00\x00\x64\x41\xc1\x9a\x88\xd5\x99\x2c\x43\xd9\x1a\xe7\x80\xa2\x2e\x3d\xf6\x6b\x3d\x79\x49\x82\x43\xa9\xe7\x79\x4a\xe6\xfd\x22\x9a\x70\xd6\xe0\xef\xcf\xca\x05\xd7\xa4\x8d\xbd\x6c\x00\x64\xe3\xb3\xdc\x4e\xa5\x6e\x08\xa8\xa1\x9e\x45\x8f\x74\xc8\x54\x8e\xfc\x57\xc6\x74\xcc\xd4\xc3\xb8\x42\x6e\x63\xd9\x57\xcc\x5b\xb5\x35\xe9\xfe\x13\x6c\x61\x51\xc4\x1a\xdb\xba\x95\xb5\x9d\x4e\xf1\xa1\x50\xe7\xf9\xdc\x71\x7f\x63\x07\x2b\x9f\x2f\xde\x9d\x22\x00\x00\x00\x00\x00\x10\x89\xbd\x5e\x3c\x56\x37\x77\xe3\x38\xa3\xcb\x3d\x4f\x9e\xd2\x81\x2c\x9e\xf7\xa4\x74\xc7\xf9\xc3\x97\xe7\x1c\x6a\x38\xe4\x5f\xac\x9c\x8b\xf3\x07\xfa\xec\x88\xd5\xac\xc1\x5a\x3e\xce\xcc\xaf\x85\x70\x3f\x1f\x9d\xd3\x6d\x2d\xe8\x0c\x18\x7d\x17\x6f\x94\x69\x5e\xe1\x2c\x8e\x64\x48\x39\xa1\x95\x11\xe0\x0f\x34\x58\x3c\x17\xb4\x94\xf6\x48\x27\xbd\x57\x26\x7c\x2e\xda\x8b\x75\xa0\x90\x80\x3b\x13\xb6\xdb\x2d\x90\x48\xcf\x6d\x7e\x04\xe4\x24\x99\x50\x00\x00\x00\x00\x00\x02\x02\x00\x00\x03\x05\x00\x00\x04\x09\x00\x01\x04\x0d\x00\x01\x05\x12\x00\x01\x06\x18\x00\x02\x06\x1e\x00\x02\x07\x25\x00\x02\x08\x2d\x00\x03\x08\x35\x00\x03\x09\x3e\x00\x03\x0a\x48\x00\x04\x0a\x52\x00\x04\x0b\x5d\x00\x04\x0c\x69\x00\x05\x0c\x75\x00\x05\x0d\x82\x00\x05\x0e\x90\x00\x05\x0f\x9f\x00\x06\x0f\xae\x00\x06\x10\xbe\x00\x06\x11\xcf\x00\x07\x11\xe0\x00\x07\x12\xf2\x00\x07\x13\x05\x01\x08\x13\x18\x01\x08\x15\x2d\x01\x08\x16\x43\x01\x09\x16\x59\x01\x09\x17\x70\x01\x09\x18\x88\x01\x0a\x18\xa0\x01\x0a\x19\xb9\x01\x0a\x1a\xd3\x01\x0a\x1b\xee\x01\x0b\x1b\x09\x02\x0b\x1c\x25\x02\x0b\x1d\x0a\x00\x00\x00\x64\x00\x00\x00\xe8\x03\x00\x00\x10\x27\x00\x00\xa0\x86\x01\x00\x40\x42\x0f\x00\x80\x96\x98\x00\x00\xe1\xf5\x05\x00\xca\x9a\x3b\x30\x00\x00\x00\x31\x23\x49\x4e\x46\x00\x00\x00\x31\x23\x51\x4e\x41\x4e\x00\x00\x31\x23\x53\x4e\x41\x4e\x00\x00\x31\x23\x49\x4e\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x6f\x67\x31\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\xf0\x3f\x33\x04\x00\x00\x00\x00\x00\x00\x33\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x43\x00\x4f\x00\x4e\x00\x4f\x00\x55\x00\x54\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\x0f\x00\xff\xff\xff\xff\xff\xff\x0f\x00\x00\x00\x00\x00\x00\xc0\xdb\x3f\x00\x00\x00\x00\x00\xc0\xdb\x3f\x10\xf8\xff\xff\xff\xff\x8f\x42\x10\xf8\xff\xff\xff\xff\x8f\x42\x00\x00\x00\x80\xff\xff\xff\x7f\x00\x00\x00\x80\xff\xff\xff\x7f\x00\x78\x9f\x50\x13\x44\xd3\x3f\x58\xb3\x12\x1f\x31\xef\x1f\x3d\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x43\x00\x00\x00\x00\x00\x00\x30\x43\x00\x00\x00\x00\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\xf0\x7f\x01\x00\x00\x00\x00\x00\xf0\x7f\x01\x00\x00\x00\x00\x00\xf0\x7f\xf9\xce\x97\xc6\x14\x89\x35\x40\x3d\x81\x29\x64\x09\x93\x08\xc0\x55\x84\x35\x6a\x80\xc9\x25\xc0\xd2\x35\x96\xdc\x02\x6a\xfc\x3f\xf7\x99\x18\x7e\x9f\xab\x16\x40\x35\xb1\x77\xdc\xf2\x7a\xf2\xbf\x08\x41\x2e\xbf\x6c\x7a\x5a\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x80\xff\xff\xdc\xa7\xd7\xb9\x85\x66\x71\xb1\x0d\x40\x00\x00\x00\x00\x00\x00\xff\xff\x0d\x40\xf7\x36\x43\x0c\x98\x19\xf6\x95\xfd\x3f\x00\x00\x00\x00\x00\x00\xe0\x3f\x03\x65\x78\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x14\x00\x51\xd0\x00\x10\x5a\xd3\x00\x10\x5f\xd3\x00\x10\x81\xd1\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xff\xff\x35\xc2\x68\x21\xa2\xda\x0f\xc9\xff\x3f\x35\xc2\x68\x21\xa2\xda\x0f\xc9\xfe\x3f\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\x08\x40\x08\x04\x08\x08\x08\x04\x08\x08\x00\x04\x0c\x08\x00\x04\x0c\x08\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x7f\x02\x35\xc2\x68\x21\xa2\xda\x0f\xc9\x3e\x40\xff\xff\xff\xff\xff\xff\xef\x7f\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x98\xc0\x00\x00\x00\x00\x00\x00\x98\x40\x00\x00\x00\x00\x00\x00\xf0\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x6f\x67\x00\x6c\x6f\x67\x31\x30\x00\x00\x00\x65\x78\x70\x00\x70\x6f\x77\x00\x61\x73\x69\x6e\x00\x00\x00\x00\x61\x63\x6f\x73\x00\x00\x00\x00\x73\x71\x72\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\x00\x80\x10\x44\x00\x00\x01\x00\x00\x00\x00\x00\x00\x80\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0a\xa8\x03\x7c\x3f\x1b\xf7\x51\x2d\x38\x05\x3e\x3d\x00\x00\xde\xb6\x9d\x57\x8b\x3f\x05\x30\xfb\xfe\x09\x6b\x38\x3d\x00\x80\x96\xde\xae\x70\x94\x3f\x1d\xe1\x91\x0c\x78\xfc\x39\x3d\x00\x00\x3e\x8e\x2e\xda\x9a\x3f\x1a\x70\x6e\x9e\xd1\x1b\x35\x3d\x00\xc0\x59\xf7\xd8\xad\xa0\x3f\xa1\x00\x00\x09\x51\x2a\x1b\x3d\x00\x00\x63\xc6\xf7\xfa\xa3\x3f\x3f\xf5\x81\xf1\x62\x36\x08\x3d\x00\xc0\xef\x59\x1e\x17\xa7\x3f\xdb\x54\xcf\x3f\x1a\xbd\x16\x3d\x00\x00\xc7\x02\x90\x3e\xaa\x3f\x86\xd3\xd0\xc8\x57\xd2\x21\x3d\x00\x40\xc3\x2d\x33\x32\xad\x3f\x1f\x44\xd9\xf8\xdb\x7a\x1b\x3d\x00\xa0\xd6\x70\x11\x28\xb0\x3f\x76\x50\xaf\x28\x8b\xf3\x1b\x3d\x00\x60\xf1\xec\x1f\x9c\xb1\x3f\xd4\x55\x53\x1e\x3f\xe0\x3e\x3d\x00\xc0\x65\xfd\x1b\x15\xb3\x3f\x95\x67\x8c\x04\x80\xe2\x37\x3d\x00\x60\xc5\x80\x27\x93\xb4\x3f\xf3\xa5\x62\xcd\xac\xc4\x2f\x3d\x00\x80\xe9\x5e\x73\x05\xb6\x3f\x9f\x7d\xa1\x23\xcf\xc3\x17\x3d\x00\xa0\x4a\x8d\x77\x6b\xb7\x3f\x7a\x6e\xa0\x12\xe8\x03\x1c\x3d\x00\xc0\xe4\x4e\x0b\xd6\xb8\x3f\x82\x4c\x4e\xcc\xe5\x00\x39\x3d\x00\x40\x24\x22\xb4\x33\xba\x3f\x35\x57\x67\x34\x70\xf1\x36\x3d\x00\x80\xa7\x54\xb6\x95\xbb\x3f\xc7\x4e\x76\x24\x5e\x0e\x29\x3d\x00\xe0\xe9\x02\x26\xea\xbc\x3f\xcb\xcb\x2e\x82\x29\xd1\xeb\x3c\x00\xa0\x6c\xc1\xb4\x42\xbe\x3f\xe9\x4d\x8d\xf3\x0f\xe5\x25\x3d\x00\x60\x6a\xb1\x05\x8d\xbf\x3f\xa7\x77\xb7\xa2\xa5\x8e\x2a\x3d\x00\x20\x3c\xc5\x9b\x6d\xc0\x3f\x45\xfa\xe1\xee\x8d\x81\x32\x3d\x00\x00\xde\xac\x3e\x0d\xc1\x3f\xae\xf0\x83\xcb\x45\x8a\x1e\x3d\x00\xd0\x74\x15\x3f\xb8\xc1\x3f\xd4\xff\x93\xf1\x19\x0b\x01\x3d\x00\xd0\x4f\x05\xfe\x51\xc2\x3f\xc0\x77\x28\x40\x09\xac\xfe\x3c\x00\xe0\xf4\x1c\x30\xf7\xc2\x3f\x41\x63\x1a\x0d\xc7\xf5\x30\x3d\x00\x50\x79\x0f\x70\x94\xc3\x3f\x64\x72\x1a\x79\x3f\xe9\x1f\x3d\x00\xa0\xb4\x53\x74\x29\xc4\x3f\x34\x4b\xbc\xc5\x09\xce\x3e\x3d\x00\xc0\xfe\xfa\x24\xca\xc4\x3f\x51\x68\xe6\x42\x43\x20\x2e\x3d\x00\x30\x09\x12\x75\x62\xc5\x3f\x2d\x17\xaa\xb3\xec\xdf\x30\x3d\x00\x00\xf6\x1a\x1a\xf2\xc5\x3f\x13\x61\x3e\x2d\x1b\xef\x3f\x3d\x00\x00\x90\x16\xa2\x8d\xc6\x3f\xd0\x99\x96\xfc\x2c\x94\xed\x3c\x00\x00\x28\x6c\x58\x20\xc7\x3f\xcd\x54\x40\x62\xa8\x20\x3d\x3d\x00\x50\x1c\xff\x95\xb4\xc7\x3f\xc5\x33\x91\x68\x2c\x01\x25\x3d\x00\xa0\xce\x66\xa2\x3f\xc8\x3f\x9f\x23\x87\x86\xc1\xc6\x20\x3d\x00\xf0\x56\x0c\x0e\xcc\xc8\x3f\xdf\xa0\xcf\xa1\xb4\xe3\x36\x3d\x00\xd0\xe7\xef\xdf\x59\xc9\x3f\xe5\xe0\xff\x7a\x02\x20\x24\x3d\x00\xc0\xd2\x47\x1f\xe9\xc9\x3f\x20\x24\xf2\x6c\x0e\x33\x35\x3d\x00\x40\x03\x8b\xa4\x6e\xca\x3f\x7f\x5b\x2b\xb9\xac\xeb\x33\x3d\x00\xf0\x52\xc5\xb7\x00\xcb\x3f\x73\xaa\x64\x4c\x69\xf4\x3d\x3d\x00\x70\xf9\x7c\xe6\x88\xcb\x3f\x72\xa0\x78\x22\x23\xff\x32\x3d\x00\x40\x2e\xba\xe3\x06\xcc\x3f\x7c\xbd\x55\xcd\x15\xcb\x32\x3d\x00\x00\x6c\xd4\x9d\x91\xcc\x3f\x72\xac\xe6\x94\x46\xb6\x0e\x3d\x00\x90\x13\x61\xfb\x11\xcd\x3f\x0b\x96\xae\x91\xdb\x34\x1a\x3d\x00\x10\xfd\xab\x59\x9f\xcd\x3f\x73\x6c\xd7\xbc\x23\x7b\x20\x3d\x00\x60\x7e\x52\x3d\x16\xce\x3f\xe4\x93\x2e\xf2\x69\x9d\x31\x3d\x00\xa0\x02\xdc\x2c\x9a\xce\x3f\x87\xf1\x81\x90\xf5\xeb\x20\x3d\x00\x90\x94\x76\x58\x1f\xcf\x3f\x00\x90\x17\xea\xeb\xaf\x07\x3d\x00\x70\xdb\x1f\x80\x99\xcf\x3f\x68\x96\xf2\xf7\x7d\x73\x22\x3d\x00\xd0\x09\x45\x5b\x0a\xd0\x3f\x7f\x25\x53\x23\x5b\x6b\x1f\x3d\x00\xe8\xfb\x37\x80\x48\xd0\x3f\xc6\x12\xb9\xb9\x93\x6a\x1b\x3d\x00\xa8\x21\x56\x31\x87\xd0\x3f\xae\xf3\xbf\x7d\xda\x61\x32\x3d\x00\xb8\x6a\x1d\x71\xc6\xd0\x3f\x32\xc1\x30\x8d\x4a\xe9\x35\x3d\x00\xa8\xd2\xcd\xd9\xff\xd0\x3f\x80\x9d\xf1\xf6\x0e\x35\x16\x3d\x00\x78\xc2\xbe\x2f\x40\xd1\x3f\x8b\xba\x22\x42\x20\x3c\x31\x3d\x00\x90\x69\x19\x97\x7a\xd1\x3f\x99\x5c\x2d\x21\x79\xf2\x21\x3d\x00\x58\xac\x30\x7a\xb5\xd1\x3f\x7e\x84\xff\x62\x3e\xcf\x3d\x3d\x00\xb8\x3a\x15\xdb\xf0\xd1\x3f\xdf\x0e\x0c\x23\x2e\x58\x27\x3d\x00\x48\x42\x4f\x0e\x26\xd2\x3f\xf9\x1f\xa4\x28\x10\x7e\x15\x3d\x00\x78\x11\xa6\x62\x62\xd2\x3f\x12\x19\x0c\x2e\x1a\xb0\x12\x3d\x00\xd8\x43\xc0\x71\x98\xd2\x3f\x79\x37\x9e\xac\x69\x39\x2b\x3d\x00\x80\x0b\x76\xc1\xd5\xd2\x3f\xbf\x08\x0f\xbe\xde\xea\x3a\x3d\x00\x30\xbb\xa7\xb3\x0c\xd3\x3f\x32\xd8\xb6\x19\x99\x92\x38\x3d\x00\x78\x9f\x50\x13\x44\xd3\x3f\x58\xb3\x12\x1f\x31\xef\x1f\x3d\x00\x00\x00\x00\x00\xc0\xdb\x3f\x00\x00\x00\x00\x00\xc0\xdb\x3f\x00\x00\x00\x00\x00\x51\xdb\x3f\x00\x00\x00\x00\x00\x51\xdb\x3f\x00\x00\x00\x00\xf0\xe8\xda\x3f\x00\x00\x00\x00\xf0\xe8\xda\x3f\x00\x00\x00\x00\xe0\x80\xda\x3f\x00\x00\x00\x00\xe0\x80\xda\x3f\x00\x00\x00\x00\xc0\x1f\xda\x3f\x00\x00\x00\x00\xc0\x1f\xda\x3f\x00\x00\x00\x00\xa0\xbe\xd9\x3f\x00\x00\x00\x00\xa0\xbe\xd9\x3f\x00\x00\x00\x00\x80\x5d\xd9\x3f\x00\x00\x00\x00\x80\x5d\xd9\x3f\x00\x00\x00\x00\x50\x03\xd9\x3f\x00\x00\x00\x00\x50\x03\xd9\x3f\x00\x00\x00\x00\x20\xa9\xd8\x3f\x00\x00\x00\x00\x20\xa9\xd8\x3f\x00\x00\x00\x00\xe0\x55\xd8\x3f\x00\x00\x00\x00\xe0\x55\xd8\x3f\x00\x00\x00\x00\x28\xff\xd7\x3f\x00\x00\x00\x00\x28\xff\xd7\x3f\x00\x00\x00\x00\x60\xaf\xd7\x3f\x00\x00\x00\x00\x60\xaf\xd7\x3f\x00\x00\x00\x00\x98\x5f\xd7\x3f\x00\x00\x00\x00\x98\x5f\xd7\x3f\x00\x00\x00\x00\xd0\x0f\xd7\x3f\x00\x00\x00\x00\xd0\x0f\xd7\x3f\x00\x00\x00\x00\x80\xc3\xd6\x3f\x00\x00\x00\x00\x80\xc3\xd6\x3f\x00\x00\x00\x00\xa8\x7a\xd6\x3f\x00\x00\x00\x00\xa8\x7a\xd6\x3f\x00\x00\x00\x00\xd0\x31\xd6\x3f\x00\x00\x00\x00\xd0\x31\xd6\x3f\x00\x00\x00\x00\x70\xec\xd5\x3f\x00\x00\x00\x00\x70\xec\xd5\x3f\x00\x00\x00\x00\x10\xa7\xd5\x3f\x00\x00\x00\x00\x10\xa7\xd5\x3f\x00\x00\x00\x00\x28\x65\xd5\x3f\x00\x00\x00\x00\x28\x65\xd5\x3f\x00\x00\x00\x00\x40\x23\xd5\x3f\x00\x00\x00\x00\x40\x23\xd5\x3f\x00\x00\x00\x00\xd0\xe4\xd4\x3f\x00\x00\x00\x00\xd0\xe4\xd4\x3f\x00\x00\x00\x00\x60\xa6\xd4\x3f\x00\x00\x00\x00\x60\xa6\xd4\x3f\x00\x00\x00\x00\x68\x6b\xd4\x3f\x00\x00\x00\x00\x68\x6b\xd4\x3f\x00\x00\x00\x00\xf8\x2c\xd4\x3f\x00\x00\x00\x00\xf8\x2c\xd4\x3f\x00\x00\x00\x00\x78\xf5\xd3\x3f\x00\x00\x00\x00\x78\xf5\xd3\x3f\x00\x00\x00\x00\x80\xba\xd3\x3f\x00\x00\x00\x00\x80\xba\xd3\x3f\x00\x00\x00\x00\x00\x83\xd3\x3f\x00\x00\x00\x00\x00\x83\xd3\x3f\x00\x00\x00\x00\xf8\x4e\xd3\x3f\x00\x00\x00\x00\xf8\x4e\xd3\x3f\x00\x00\x00\x00\x78\x17\xd3\x3f\x00\x00\x00\x00\x78\x17\xd3\x3f\x00\x00\x00\x00\x70\xe3\xd2\x3f\x00\x00\x00\x00\x70\xe3\xd2\x3f\x00\x00\x00\x00\xe0\xb2\xd2\x3f\x00\x00\x00\x00\xe0\xb2\xd2\x3f\x00\x00\x00\x00\xd8\x7e\xd2\x3f\x00\x00\x00\x00\xd8\x7e\xd2\x3f\x00\x00\x00\x00\x48\x4e\xd2\x3f\x00\x00\x00\x00\x48\x4e\xd2\x3f\x00\x00\x00\x00\xb8\x1d\xd2\x3f\x00\x00\x00\x00\xb8\x1d\xd2\x3f\x00\x00\x00\x00\xa0\xf0\xd1\x3f\x00\x00\x00\x00\xa0\xf0\xd1\x3f\x00\x00\x00\x00\x88\xc3\xd1\x3f\x00\x00\x00\x00\x88\xc3\xd1\x3f\x00\x00\x00\x00\x70\x96\xd1\x3f\x00\x00\x00\x00\x70\x96\xd1\x3f\x00\x00\x00\x00\x58\x69\xd1\x3f\x00\x00\x00\x00\x58\x69\xd1\x3f\x00\x00\x00\x00\xb8\x3f\xd1\x3f\x00\x00\x00\x00\xb8\x3f\xd1\x3f\x00\x00\x00\x00\xa0\x12\xd1\x3f\x00\x00\x00\x00\xa0\x12\xd1\x3f\x00\x00\x00\x00\x00\xe9\xd0\x3f\x00\x00\x00\x00\x00\xe9\xd0\x3f\x00\x00\x00\x00\xd8\xc2\xd0\x3f\x00\x00\x00\x00\xd8\xc2\xd0\x3f\x00\x00\x00\x00\x38\x99\xd0\x3f\x00\x00\x00\x00\x38\x99\xd0\x3f\x00\x00\x00\x00\x10\x73\xd0\x3f\x00\x00\x00\x00\x10\x73\xd0\x3f\x00\x00\x00\x00\x70\x49\xd0\x3f\x00\x00\x00\x00\x70\x49\xd0\x3f\x00\x00\x00\x00\xc0\x26\xd0\x3f\x00\x00\x00\x00\xc0\x26\xd0\x3f\x00\x00\x00\x00\x98\x00\xd0\x3f\x00\x00\x00\x00\x98\x00\xd0\x3f\x00\x00\x00\x00\xe0\xb4\xcf\x3f\x00\x00\x00\x00\xe0\xb4\xcf\x3f\x00\x00\x00\x00\x80\x6f\xcf\x3f\x00\x00\x00\x00\x80\x6f\xcf\x3f\x00\x00\x00\x00\x20\x2a\xcf\x3f\x00\x00\x00\x00\x20\x2a\xcf\x3f\x00\x00\x00\x00\xc0\xe4\xce\x3f\x00\x00\x00\x00\xc0\xe4\xce\x3f\x00\x00\x00\x00\x60\x9f\xce\x3f\x00\x00\x00\x00\x60\x9f\xce\x3f\x00\x00\x00\x00\x00\x5a\xce\x3f\x00\x00\x00\x00\x00\x5a\xce\x3f\x00\x00\x00\x00\x90\x1b\xce\x3f\x00\x00\x00\x00\x90\x1b\xce\x3f\x00\x00\x00\x00\x30\xd6\xcd\x3f\x00\x00\x00\x00\x30\xd6\xcd\x3f\x00\x00\x00\x00\xc0\x97\xcd\x3f\x00\x00\x00\x00\xc0\x97\xcd\x3f\x00\x00\x00\x00\x50\x59\xcd\x3f\x00\x00\x00\x00\x50\x59\xcd\x3f\x00\x00\x00\x00\xe0\x1a\xcd\x3f\x00\x00\x00\x00\xe0\x1a\xcd\x3f\x00\x00\x00\x00\x60\xe3\xcc\x3f\x00\x00\x00\x00\x60\xe3\xcc\x3f\x00\x00\x00\x00\xf0\xa4\xcc\x3f\x00\x00\x00\x00\xf0\xa4\xcc\x3f\x00\x00\x00\x00\x70\x6d\xcc\x3f\x00\x00\x00\x00\x70\x6d\xcc\x3f\x00\x00\x00\x00\x00\x2f\xcc\x3f\x00\x00\x00\x00\x00\x2f\xcc\x3f\x00\x00\x00\x00\x80\xf7\xcb\x3f\x00\x00\x00\x00\x80\xf7\xcb\x3f\x00\x00\x00\x00\x00\xc0\xcb\x3f\x00\x00\x00\x00\x00\xc0\xcb\x3f\x00\x00\x00\x00\x00\x00\xe0\x3f\x74\x61\x6e\x68\x00\x00\x00\x00\x61\x74\x61\x6e\x00\x00\x00\x00\x61\x74\x61\x6e\x32\x00\x00\x00\x73\x69\x6e\x00\x63\x6f\x73\x00\x74\x61\x6e\x00\x63\x65\x69\x6c\x00\x00\x00\x00\x66\x6c\x6f\x6f\x72\x00\x00\x00\x66\x61\x62\x73\x00\x00\x00\x00\x6d\x6f\x64\x66\x00\x00\x00\x00\x6c\x64\x65\x78\x70\x00\x00\x00\x5f\x63\x61\x62\x73\x00\x00\x00\x5f\x68\x79\x70\x6f\x74\x00\x00\x66\x6d\x6f\x64\x00\x00\x00\x00\x66\x72\x65\x78\x70\x00\x00\x00\x5f\x79\x30\x00\x5f\x79\x31\x00\x5f\x79\x6e\x00\x5f\x6c\x6f\x67\x62\x00\x00\x00\x5f\x6e\x65\x78\x74\x61\x66\x74\x65\x72\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x4b\x01\x10\x1d\x00\x00\x00\x04\x4b\x01\x10\x1a\x00\x00\x00\xf4\x4a\x01\x10\x1b\x00\x00\x00\xf8\x4a\x01\x10\x1f\x00\x00\x00\xe0\x54\x01\x10\x13\x00\x00\x00\xe8\x54\x01\x10\x21\x00\x00\x00\x68\x53\x01\x10\x0e\x00\x00\x00\x08\x4b\x01\x10\x0d\x00\x00\x00\x10\x4b\x01\x10\x0f\x00\x00\x00\x70\x53\x01\x10\x10\x00\x00\x00\x78\x53\x01\x10\x05\x00\x00\x00\x18\x4b\x01\x10\x1e\x00\x00\x00\x80\x53\x01\x10\x12\x00\x00\x00\x84\x53\x01\x10\x20\x00\x00\x00\x88\x53\x01\x10\x0c\x00\x00\x00\x8c\x53\x01\x10\x0b\x00\x00\x00\x94\x53\x01\x10\x15\x00\x00\x00\x9c\x53\x01\x10\x1c\x00\x00\x00\xa4\x53\x01\x10\x19\x00\x00\x00\xac\x53\x01\x10\x11\x00\x00\x00\xb4\x53\x01\x10\x18\x00\x00\x00\xbc\x53\x01\x10\x16\x00\x00\x00\xc4\x53\x01\x10\x17\x00\x00\x00\xcc\x53\x01\x10\x22\x00\x00\x00\xd4\x53\x01\x10\x23\x00\x00\x00\xd8\x53\x01\x10\x24\x00\x00\x00\xdc\x53\x01\x10\x25\x00\x00\x00\xe0\x53\x01\x10\x26\x00\x00\x00\xe8\x53\x01\x10\x73\x69\x6e\x68\x00\x00\x00\x00\x63\x6f\x73\x68\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x7f\xff\xff\xff\xff\xff\xff\xef\x7f\x00\x00\x00\x00\x00\x00\x00\x80\x53\x79\x73\x74\x72\x61\x79\x20\x65\x72\x72\x6f\x72\x20\x25\x73\x3a\x20\x25\x64\x20\x25\x73\x0a\x00\x00\x00\x00\x67\x65\x74\x20\x74\x72\x61\x79\x20\x6d\x65\x6e\x75\x20\x70\x6f\x73\x69\x74\x69\x6f\x6e\x00\x00\x67\x65\x74\x20\x6d\x65\x6e\x75\x20\x69\x74\x65\x6d\x20\x69\x64\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x79\x00\x73\x00\x74\x00\x72\x00\x61\x00\x79\x00\x43\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x00\x00\x00\x00\x6c\x6f\x61\x64\x20\x69\x63\x6f\x6e\x20\x69\x6d\x61\x67\x65\x00\x00\x00\x00\x00\x06\x7e\xb7\x57\x00\x00\x00\x00\x02\x00\x00\x00\x61\x00\x00\x00\x14\x57\x01\x00\x14\x43\x01\x00\x00\x00\x00\x00\x06\x7e\xb7\x57\x00\x00\x00\x00\x0c\x00\x00\x00\x14\x00\x00\x00\x78\x57\x01\x00\x78\x43\x01\x00\x00\x00\x00\x00\x06\x7e\xb7\x57\x00\x00\x00\x00\x0d\x00\x00\x00\xfc\x02\x00\x00\x8c\x57\x01\x00\x8c\x43\x01\x00\x00\x00\x00\x00\x06\x7e\xb7\x57\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x70\x01\x10\x50\x56\x01\x10\x03\x00\x00\x00\x64\x01\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\xe0\x25\x00\x00\x90\x2d\x00\x00\x20\x30\x00\x00\x00\x00\x00\x00\x45\x54\x57\x30\x10\x00\x00\x00\x86\x0e\x04\x88\x2b\x05\x8a\xbb\x05\x05\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x2f\x00\x00\x49\x6e\x76\x6f\x6b\x65\x4d\x61\x69\x6e\x56\x69\x61\x43\x52\x54\x00\x22\x4d\x61\x69\x6e\x20\x49\x6e\x76\x6f\x6b\x65\x64\x2e\x22\x00\x02\x46\x69\x6c\x65\x4e\x61\x6d\x65\x00\x01\x05\x05\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x2e\x00\x00\x45\x78\x69\x74\x4d\x61\x69\x6e\x56\x69\x61\x43\x52\x54\x00\x22\x4d\x61\x69\x6e\x20\x52\x65\x74\x75\x72\x6e\x65\x64\x2e\x22\x00\x02\x46\x69\x6c\x65\x4e\x61\x6d\x65\x00\x01\x02\x2b\x00\x4d\x69\x63\x72\x6f\x73\x6f\x66\x74\x2e\x43\x52\x54\x50\x72\x6f\x76\x69\x64\x65\x72\x00\x13\x00\x01\x1a\x73\x50\x4f\xcf\x89\x82\x47\xb3\xe0\xdc\xe8\xc9\x04\x76\xba\x01\x52\x53\x44\x53\xd8\x49\xbc\xe5\x3e\xab\x19\x46\xa9\x61\x88\xe3\xe9\xc4\xeb\x72\x01\x00\x00\x00\x44\x3a\x5c\x7e\x47\x49\x54\x5c\x66\x6f\x72\x67\x6f\x64\x73\x61\x6b\x65\x73\x6c\x75\x63\x6b\x63\x6f\x6c\x6f\x72\x73\x5c\x73\x79\x73\x74\x72\x61\x79\x2d\x6d\x61\x73\x74\x65\x72\x5c\x73\x79\x73\x74\x72\x61\x79\x5c\x52\x65\x6c\x65\x61\x73\x65\x5c\x73\x79\x73\x74\x72\x61\x79\x2e\x70\x64\x62\x00\x00\x00\x00\x00\x00\x00\x00\xae\x00\x00\x00\xae\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\x47\x43\x54\x4c\x00\x10\x00\x00\x5f\x02\x00\x00\x2e\x74\x65\x78\x74\x00\x00\x00\x60\x12\x00\x00\x8b\xe5\x00\x00\x2e\x74\x65\x78\x74\x24\x6d\x6e\x00\x00\x00\x00\x00\x00\x01\x00\x64\x01\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x35\x00\x00\x00\x00\x64\x01\x01\x00\x04\x00\x00\x00\x2e\x30\x30\x63\x66\x67\x00\x00\x68\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x43\x41\x00\x00\x00\x00\x6c\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x43\x5a\x00\x00\x00\x00\x70\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x49\x41\x00\x00\x00\x00\x74\x01\x01\x00\x0c\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x49\x43\x00\x00\x00\x00\x80\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x49\x5a\x00\x00\x00\x00\x84\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x50\x41\x00\x00\x00\x00\x88\x01\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x50\x58\x00\x00\x00\x00\x90\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x50\x58\x41\x00\x00\x00\x94\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x50\x5a\x00\x00\x00\x00\x98\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x54\x41\x00\x00\x00\x00\x9c\x01\x01\x00\x04\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x54\x5a\x00\x00\x00\x00\xa0\x01\x01\x00\xac\x54\x00\x00\x2e\x72\x64\x61\x74\x61\x00\x00\x50\x56\x01\x00\x0c\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x73\x78\x64\x61\x74\x61\x00\x00\x00\x60\x56\x01\x00\x10\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x45\x54\x57\x30\x00\x00\x00\x00\x70\x56\x01\x00\x77\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x45\x54\x57\x31\x00\x00\x00\x00\xe7\x56\x01\x00\x2c\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x45\x54\x57\x32\x00\x00\x00\x00\x13\x57\x01\x00\x01\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x45\x54\x57\x39\x00\x00\x00\x00\x14\x57\x01\x00\x74\x03\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x7a\x7a\x64\x62\x67\x00\x00\x00\x88\x5a\x01\x00\x04\x00\x00\x00\x2e\x72\x74\x63\x24\x49\x41\x41\x00\x00\x00\x00\x8c\x5a\x01\x00\x04\x00\x00\x00\x2e\x72\x74\x63\x24\x49\x5a\x5a\x00\x00\x00\x00\x90\x5a\x01\x00\x04\x00\x00\x00\x2e\x72\x74\x63\x24\x54\x41\x41\x00\x00\x00\x00\x94\x5a\x01\x00\x04\x00\x00\x00\x2e\x72\x74\x63\x24\x54\x5a\x5a\x00\x00\x00\x00\x98\x5a\x01\x00\xcc\x03\x00\x00\x2e\x78\x64\x61\x74\x61\x24\x78\x00\x00\x00\x00\x70\x5e\x01\x00\xa1\x00\x00\x00\x2e\x65\x64\x61\x74\x61\x00\x00\x14\x5f\x01\x00\x50\x00\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x32\x00\x00\x00\x00\x64\x5f\x01\x00\x14\x00\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x33\x00\x00\x00\x00\x78\x5f\x01\x00\x64\x01\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x34\x00\x00\x00\x00\xdc\x60\x01\x00\x4a\x06\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x36\x00\x00\x00\x00\x00\x70\x01\x00\xd0\x07\x00\x00\x2e\x64\x61\x74\x61\x00\x00\x00\xd0\x77\x01\x00\xdc\x0c\x00\x00\x2e\x62\x73\x73\x00\x00\x00\x00\x00\x90\x01\x00\x88\x00\x00\x00\x2e\x67\x66\x69\x64\x73\x24\x78\x00\x00\x00\x00\x88\x90\x01\x00\x1c\x00\x00\x00\x2e\x67\x66\x69\x64\x73\x24\x79\x00\x00\x00\x00\x00\xa0\x01\x00\x58\x00\x00\x00\x2e\x72\x73\x72\x63\x24\x30\x31\x00\x00\x00\x00\x60\xa0\x01\x00\x80\x01\x00\x00\x2e\x72\x73\x72\x63\x24\x30\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd0\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x7d\x19\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xf8\x19\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\xda\x1a\x00\x10\xf9\x1a\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\xe6\x1e\x00\x10\xf9\x1e\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xc5\x32\x00\x10\x00\x00\x00\x00\xe4\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x45\x4a\x00\x10\x00\x00\x00\x00\x2d\x4a\x00\x10\x3d\x4a\x00\x10\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xcd\x4d\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x1e\x4e\x00\x10\x00\x00\x00\x00\xe4\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\xf3\x52\x00\x10\xf7\x52\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd0\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x80\x5f\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xc4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x0b\x61\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\xde\x60\x00\x10\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x0b\x63\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x08\x6c\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x14\x6b\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x75\x6b\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xc0\x6b\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd2\x7b\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x01\x82\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xb2\x7c\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xdd\x86\x00\x10\x00\x00\x00\x00\xe4\xff\xff\xff\x00\x00\x00\x00\xb4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xe1\x89\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x34\x87\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd0\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x7d\x8d\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x13\x8e\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xcc\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x05\x95\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xcc\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x7b\x98\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xb6\x9f\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xcb\xc0\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xc4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x27\xc3\x00\x10\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\x89\xe6\x00\x10\x9c\xe6\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x7e\xb7\x57\x00\x00\x00\x00\xca\x5e\x01\x00\x01\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x98\x5e\x01\x00\xac\x5e\x01\x00\xc0\x5e\x01\x00\x80\x16\x00\x00\x80\x14\x00\x00\xc0\x17\x00\x00\xd0\x15\x00\x00\x40\x16\x00\x00\xd6\x5e\x01\x00\xee\x5e\x01\x00\xf9\x5e\x01\x00\xfe\x5e\x01\x00\x06\x5f\x01\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x73\x79\x73\x74\x72\x61\x79\x2e\x64\x6c\x6c\x00\x61\x64\x64\x5f\x6f\x72\x5f\x75\x70\x64\x61\x74\x65\x5f\x6d\x65\x6e\x75\x5f\x69\x74\x65\x6d\x00\x6e\x61\x74\x69\x76\x65\x4c\x6f\x6f\x70\x00\x71\x75\x69\x74\x00\x73\x65\x74\x49\x63\x6f\x6e\x00\x73\x65\x74\x54\x6f\x6f\x6c\x74\x69\x70\x00\x00\x00\x00\x80\x5f\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x61\x01\x00\x08\x00\x01\x00\x84\x60\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x62\x01\x00\x0c\x01\x01\x00\x7c\x60\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x62\x01\x00\x04\x01\x01\x00\x78\x5f\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x67\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x67\x01\x00\x00\x00\x00\x00\xfe\x60\x01\x00\xec\x60\x01\x00\xf2\x66\x01\x00\xe2\x66\x01\x00\xd4\x66\x01\x00\xc4\x66\x01\x00\xb0\x66\x01\x00\xa2\x66\x01\x00\x94\x66\x01\x00\x88\x66\x01\x00\x78\x66\x01\x00\x66\x66\x01\x00\x56\x66\x01\x00\x4a\x66\x01\x00\x36\x66\x01\x00\x24\x66\x01\x00\x12\x66\x01\x00\x00\x66\x01\x00\xee\x65\x01\x00\xb8\x62\x01\x00\xd4\x62\x01\x00\xf2\x62\x01\x00\x06\x63\x01\x00\x1a\x63\x01\x00\x36\x63\x01\x00\x50\x63\x01\x00\x66\x63\x01\x00\x7c\x63\x01\x00\x96\x63\x01\x00\xac\x63\x01\x00\xc0\x63\x01\x00\xd2\x63\x01\x00\xe8\x63\x01\x00\x00\x64\x01\x00\x28\x64\x01\x00\x34\x64\x01\x00\x42\x64\x01\x00\x50\x64\x01\x00\x5a\x64\x01\x00\x68\x64\x01\x00\x7a\x64\x01\x00\x8c\x64\x01\x00\x98\x64\x01\x00\xa8\x64\x01\x00\xc0\x64\x01\x00\xd8\x64\x01\x00\xf0\x64\x01\x00\xfe\x64\x01\x00\x14\x65\x01\x00\x2a\x65\x01\x00\x40\x65\x01\x00\x4c\x65\x01\x00\x58\x65\x01\x00\x68\x65\x01\x00\x78\x65\x01\x00\x86\x65\x01\x00\x90\x65\x01\x00\xa2\x65\x01\x00\xae\x65\x01\x00\xba\x65\x01\x00\xd4\x65\x01\x00\xdc\x60\x01\x00\x00\x00\x00\x00\x98\x62\x01\x00\x00\x00\x00\x00\x7a\x62\x01\x00\x66\x62\x01\x00\x52\x62\x01\x00\x44\x62\x01\x00\x30\x62\x01\x00\x1c\x62\x01\x00\x0e\x62\x01\x00\x00\x62\x01\x00\xee\x61\x01\x00\xd0\x61\x01\x00\xbe\x61\x01\x00\xaa\x61\x01\x00\x9c\x61\x01\x00\x90\x61\x01\x00\x7e\x61\x01\x00\x6c\x61\x01\x00\x58\x61\x01\x00\x46\x61\x01\x00\x30\x61\x01\x00\x20\x61\x01\x00\xde\x61\x01\x00\x00\x00\x00\x00\x50\x02\x47\x65\x74\x4c\x61\x73\x74\x45\x72\x72\x6f\x72\x00\x00\x9a\x01\x46\x6f\x72\x6d\x61\x74\x4d\x65\x73\x73\x61\x67\x65\x57\x00\x00\x67\x02\x47\x65\x74\x4d\x6f\x64\x75\x6c\x65\x48\x61\x6e\x64\x6c\x65\x57\x00\x00\x4b\x45\x52\x4e\x45\x4c\x33\x32\x2e\x64\x6c\x6c\x00\x00\x33\x01\x47\x65\x74\x43\x75\x72\x73\x6f\x72\x50\x6f\x73\x00\x00\xd5\x02\x53\x65\x74\x46\x6f\x72\x65\x67\x72\x6f\x75\x6e\x64\x57\x69\x6e\x64\x6f\x77\x00\x39\x03\x54\x72\x61\x63\x6b\x50\x6f\x70\x75\x70\x4d\x65\x6e\x75\x00\x00\x6a\x01\x47\x65\x74\x4d\x65\x6e\x75\x49\x74\x65\x6d\x49\x6e\x66\x6f\x57\x00\x00\x71\x02\x50\x6f\x73\x74\x51\x75\x69\x74\x4d\x65\x73\x73\x61\x67\x65\x00\xa1\x00\x44\x65\x66\x57\x69\x6e\x64\x6f\x77\x50\x72\x6f\x63\x57\x00\x00\x23\x02\x4c\x6f\x61\x64\x49\x63\x6f\x6e\x57\x00\x21\x02\x4c\x6f\x61\x64\x43\x75\x72\x73\x6f\x72\x57\x00\x89\x02\x52\x65\x67\x69\x73\x74\x65\x72\x43\x6c\x61\x73\x73\x45\x78\x57\x00\x00\x71\x00\x43\x72\x65\x61\x74\x65\x57\x69\x6e\x64\x6f\x77\x45\x78\x57\x00\x20\x03\x53\x68\x6f\x77\x57\x69\x6e\x64\x6f\x77\x00\x00\x57\x03\x55\x70\x64\x61\x74\x65\x57\x69\x6e\x64\x6f\x77\x00\x00\x6e\x00\x43\x72\x65\x61\x74\x65\x50\x6f\x70\x75\x70\x4d\x65\x6e\x75\x00\xe2\x02\x53\x65\x74\x4d\x65\x6e\x75\x49\x6e\x66\x6f\x00\x73\x01\x47\x65\x74\x4d\x65\x73\x73\x61\x67\x65\x57\x00\x3f\x03\x54\x72\x61\x6e\x73\x6c\x61\x74\x65\x4d\x65\x73\x73\x61\x67\x65\x00\x00\xb5\x00\x44\x69\x73\x70\x61\x74\x63\x68\x4d\x65\x73\x73\x61\x67\x65\x57\x00\x00\x25\x02\x4c\x6f\x61\x64\x49\x6d\x61\x67\x65\x57\x00\x00\x67\x01\x47\x65\x74\x4d\x65\x6e\x75\x49\x74\x65\x6d\x43\x6f\x75\x6e\x74\x00\x00\xe5\x02\x53\x65\x74\x4d\x65\x6e\x75\x49\x74\x65\x6d\x49\x6e\x66\x6f\x57\x00\x00\xea\x01\x49\x6e\x73\x65\x72\x74\x4d\x65\x6e\x75\x49\x74\x65\x6d\x57\x00\x55\x53\x45\x52\x33\x32\x2e\x64\x6c\x6c\x00\x00\x43\x01\x53\x68\x65\x6c\x6c\x5f\x4e\x6f\x74\x69\x66\x79\x49\x63\x6f\x6e\x57\x00\x53\x48\x45\x4c\x4c\x33\x32\x2e\x64\x6c\x6c\x00\x82\x05\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x46\x69\x6c\x74\x65\x72\x00\x00\x43\x05\x53\x65\x74\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x46\x69\x6c\x74\x65\x72\x00\x09\x02\x47\x65\x74\x43\x75\x72\x72\x65\x6e\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x61\x05\x54\x65\x72\x6d\x69\x6e\x61\x74\x65\x50\x72\x6f\x63\x65\x73\x73\x00\x00\x6d\x03\x49\x73\x50\x72\x6f\x63\x65\x73\x73\x6f\x72\x46\x65\x61\x74\x75\x72\x65\x50\x72\x65\x73\x65\x6e\x74\x00\x2d\x04\x51\x75\x65\x72\x79\x50\x65\x72\x66\x6f\x72\x6d\x61\x6e\x63\x65\x43\x6f\x75\x6e\x74\x65\x72\x00\x0a\x02\x47\x65\x74\x43\x75\x72\x72\x65\x6e\x74\x50\x72\x6f\x63\x65\x73\x73\x49\x64\x00\x0e\x02\x47\x65\x74\x43\x75\x72\x72\x65\x6e\x74\x54\x68\x72\x65\x61\x64\x49\x64\x00\x00\xd6\x02\x47\x65\x74\x53\x79\x73\x74\x65\x6d\x54\x69\x6d\x65\x41\x73\x46\x69\x6c\x65\x54\x69\x6d\x65\x00\x4b\x03\x49\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x53\x4c\x69\x73\x74\x48\x65\x61\x64\x00\x67\x03\x49\x73\x44\x65\x62\x75\x67\x67\x65\x72\x50\x72\x65\x73\x65\x6e\x74\x00\xbe\x02\x47\x65\x74\x53\x74\x61\x72\x74\x75\x70\x49\x6e\x66\x6f\x57\x00\x63\x02\x47\x65\x74\x4d\x6f\x64\x75\x6c\x65\x46\x69\x6c\x65\x4e\x61\x6d\x65\x57\x00\x00\x54\x03\x49\x6e\x74\x65\x72\x6c\x6f\x63\x6b\x65\x64\x46\x6c\x75\x73\x68\x53\x4c\x69\x73\x74\x00\x48\x03\x49\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x41\x6e\x64\x53\x70\x69\x6e\x43\x6f\x75\x6e\x74\x00\x73\x05\x54\x6c\x73\x41\x6c\x6c\x6f\x63\x00\x00\x75\x05\x54\x6c\x73\x47\x65\x74\x56\x61\x6c\x75\x65\x00\x76\x05\x54\x6c\x73\x53\x65\x74\x56\x61\x6c\x75\x65\x00\x74\x05\x54\x6c\x73\x46\x72\x65\x65\x00\x9e\x01\x46\x72\x65\x65\x4c\x69\x62\x72\x61\x72\x79\x00\x9d\x02\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00\x00\xa7\x03\x4c\x6f\x61\x64\x4c\x69\x62\x72\x61\x72\x79\x45\x78\x57\x00\x00\xad\x04\x52\x74\x6c\x55\x6e\x77\x69\x6e\x64\x00\x0b\x05\x53\x65\x74\x4c\x61\x73\x74\x45\x72\x72\x6f\x72\x00\x00\x25\x01\x45\x6e\x74\x65\x72\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x00\x00\xa2\x03\x4c\x65\x61\x76\x65\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x00\x00\x05\x01\x44\x65\x6c\x65\x74\x65\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x00\x51\x01\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x66\x02\x47\x65\x74\x4d\x6f\x64\x75\x6c\x65\x48\x61\x6e\x64\x6c\x65\x45\x78\x57\x00\x00\xd1\x03\x4d\x75\x6c\x74\x69\x42\x79\x74\x65\x54\x6f\x57\x69\x64\x65\x43\x68\x61\x72\x00\xcd\x05\x57\x69\x64\x65\x43\x68\x61\x72\x54\x6f\x4d\x75\x6c\x74\x69\x42\x79\x74\x65\x00\x33\x03\x48\x65\x61\x70\x46\x72\x65\x65\x00\x00\x2f\x03\x48\x65\x61\x70\x41\x6c\x6c\x6f\x63\x00\x96\x03\x4c\x43\x4d\x61\x70\x53\x74\x72\x69\x6e\x67\x57\x00\x00\xc0\x02\x47\x65\x74\x53\x74\x64\x48\x61\x6e\x64\x6c\x65\x00\x00\x3e\x02\x47\x65\x74\x46\x69\x6c\x65\x54\x79\x70\x65\x00\xa4\x01\x47\x65\x74\x41\x43\x50\x00\x00\x72\x03\x49\x73\x56\x61\x6c\x69\x64\x43\x6f\x64\x65\x50\x61\x67\x65\x00\x86\x02\x47\x65\x74\x4f\x45\x4d\x43\x50\x00\x00\xb3\x01\x47\x65\x74\x43\x50\x49\x6e\x66\x6f\x00\x27\x02\x47\x65\x74\x45\x6e\x76\x69\x72\x6f\x6e\x6d\x65\x6e\x74\x53\x74\x72\x69\x6e\x67\x73\x57\x00\x00\x9d\x01\x46\x72\x65\x65\x45\x6e\x76\x69\x72\x6f\x6e\x6d\x65\x6e\x74\x53\x74\x72\x69\x6e\x67\x73\x57\x00\xa2\x02\x47\x65\x74\x50\x72\x6f\x63\x65\x73\x73\x48\x65\x61\x70\x00\x00\xc8\x01\x47\x65\x74\x43\x6f\x6d\x6d\x61\x6e\x64\x4c\x69\x6e\x65\x41\x00\xc9\x01\x47\x65\x74\x43\x6f\x6d\x6d\x61\x6e\x64\x4c\x69\x6e\x65\x57\x00\xc5\x02\x47\x65\x74\x53\x74\x72\x69\x6e\x67\x54\x79\x70\x65\x57\x00\x00\x92\x01\x46\x6c\x75\x73\x68\x46\x69\x6c\x65\x42\x75\x66\x66\x65\x72\x73\x00\x00\xe1\x05\x57\x72\x69\x74\x65\x46\x69\x6c\x65\x00\xdc\x01\x47\x65\x74\x43\x6f\x6e\x73\x6f\x6c\x65\x43\x50\x00\x00\xee\x01\x47\x65\x74\x43\x6f\x6e\x73\x6f\x6c\x65\x4d\x6f\x64\x65\x00\x00\x22\x05\x53\x65\x74\x53\x74\x64\x48\x61\x6e\x64\x6c\x65\x00\x00\x38\x03\x48\x65\x61\x70\x53\x69\x7a\x65\x00\x00\x36\x03\x48\x65\x61\x70\x52\x65\x41\x6c\x6c\x6f\x63\x00\x7f\x00\x43\x6c\x6f\x73\x65\x48\x61\x6e\x64\x6c\x65\x00\xfd\x04\x53\x65\x74\x46\x69\x6c\x65\x50\x6f\x69\x6e\x74\x65\x72\x45\x78\x00\x00\xe0\x05\x57\x72\x69\x74\x65\x43\x6f\x6e\x73\x6f\x6c\x65\x57\x00\xc2\x00\x43\x72\x65\x61\x74\x65\x46\x69\x6c\x65\x57\x00\xfe\x00\x44\x65\x63\x6f\x64\x65\x50\x6f\x69\x6e\x74\x65\x72\x00\x40\x04\x52\x61\x69\x73\x65\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x00\x00\x1a\x03\x53\x79\x73\x74\x65\x6d\x46\x75\x6e\x63\x74\x69\x6f\x6e\x30\x33\x36\x00\x41\x44\x56\x41\x50\x49\x33\x32\x2e\x64\x6c\x6c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\x19\xbf\x44\x4e\xe6\x40\xbb\xff\xff\xff\xff\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x56\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x90\xec\x5e\x22\xc0\xb2\x44\xa5\xdd\xfd\x71\x6a\x22\x2a\x15\x00\x00\x00\x00\x00\x00\x00\x00\x08\x24\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x05\x93\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x20\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x20\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x0c\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x0a\x0a\x0a\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x38\x19\x01\x10\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x72\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x72\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x72\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x72\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x72\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x77\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\xb8\x1b\x01\x10\x38\x1d\x01\x10\x90\x16\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x71\x01\x10\x30\x75\x01\x10\x43\x00\x00\x00\x01\x02\x04\x08\xa4\x03\x00\x00\x60\x82\x79\x82\x21\x00\x00\x00\x00\x00\x00\x00\xa6\xdf\x00\x00\x00\x00\x00\x00\xa1\xa5\x00\x00\x00\x00\x00\x00\x81\x9f\xe0\xfc\x00\x00\x00\x00\x40\x7e\x80\xfc\x00\x00\x00\x00\xa8\x03\x00\x00\xc1\xa3\xda\xa3\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xfe\x00\x00\x00\x00\x00\x00\x40\xfe\x00\x00\x00\x00\x00\x00\xb5\x03\x00\x00\xc1\xa3\xda\xa3\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xfe\x00\x00\x00\x00\x00\x00\x41\xfe\x00\x00\x00\x00\x00\x00\xb6\x03\x00\x00\xcf\xa2\xe4\xa2\x1a\x00\xe5\xa2\xe8\xa2\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xfe\x00\x00\x00\x00\x00\x00\x40\x7e\xa1\xfe\x00\x00\x00\x00\x51\x05\x00\x00\x51\xda\x5e\xda\x20\x00\x5f\xda\x6a\xda\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xd3\xd8\xde\xe0\xf9\x00\x00\x31\x7e\x81\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x00\x00\x00\x00\x00\x00\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x00\x00\x00\x00\x00\x00\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x75\x01\x10\xfe\xff\xff\xff\x2e\x00\x00\x00\x2e\x00\x00\x00\x58\x77\x01\x10\xac\x80\x01\x10\xac\x80\x01\x10\xac\x80\x01\x10\xac\x80\x01\x10\xac\x80\x01\x10\xac\x80\x01\x10\xac\x80\x01\x10\xac\x80\x01\x10\xac\x80\x01\x10\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x5c\x77\x01\x10\xb0\x80\x01\x10\xb0\x80\x01\x10\xb0\x80\x01\x10\xb0\x80\x01\x10\xb0\x80\x01\x10\xb0\x80\x01\x10\xb0\x80\x01\x10\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x4d\x00\x00\x19\x4d\x00\x00\x6c\x85\x00\x00\xa3\x51\x00\x00\xbd\x51\x00\x00\x6c\x85\x00\x00\x0b\x52\x00\x00\x6c\x85\x00\x00\x55\x81\x00\x00\x6c\x85\x00\x00\x53\x85\x00\x00\x17\x63\x00\x00\xc1\x62\x00\x00\xa3\x6f\x00\x00\x77\x6f\x00\x00\x02\x52\x00\x00\x49\x85\x00\x00\x38\x85\x00\x00\x33\x7c\x00\x00\xdb\x7b\x00\x00\x6c\x85\x00\x00\x6c\x85\x00\x00\xb3\x5e\x00\x00\x06\x5e\x00\x00\xc5\x51\x00\x00\x91\x51\x00\x00\x37\x31\x00\x00\x0f\x32\x00\x00\x2d\x6d\x00\x00\x89\x7b\x00\x00\xad\xbf\x00\x00\x65\x8a\x00\x00\x19\xc8\x00\x00\x9c\xcd\x00\x00\x36\x00\x00\x00\x49\x00\x00\x00\x4c\x00\x00\x00\x0a\x00\x00\x00\x0d\x00\x00\x00\x64\x00\x00\x00\x51\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x18\x00\x00\x00\x18\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x30\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x09\x04\x00\x00\x48\x00\x00\x00\x60\xa0\x01\x00\x7d\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\x2d\x38\x27\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x27\x79\x65\x73\x27\x3f\x3e\x0d\x0a\x3c\x61\x73\x73\x65\x6d\x62\x6c\x79\x20\x78\x6d\x6c\x6e\x73\x3d\x27\x75\x72\x6e\x3a\x73\x63\x68\x65\x6d\x61\x73\x2d\x6d\x69\x63\x72\x6f\x73\x6f\x66\x74\x2d\x63\x6f\x6d\x3a\x61\x73\x6d\x2e\x76\x31\x27\x20\x6d\x61\x6e\x69\x66\x65\x73\x74\x56\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\x30\x27\x3e\x0d\x0a\x20\x20\x3c\x74\x72\x75\x73\x74\x49\x6e\x66\x6f\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x75\x72\x6e\x3a\x73\x63\x68\x65\x6d\x61\x73\x2d\x6d\x69\x63\x72\x6f\x73\x6f\x66\x74\x2d\x63\x6f\x6d\x3a\x61\x73\x6d\x2e\x76\x33\x22\x3e\x0d\x0a\x20\x20\x20\x20\x3c\x73\x65\x63\x75\x72\x69\x74\x79\x3e\x0d\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x71\x75\x65\x73\x74\x65\x64\x50\x72\x69\x76\x69\x6c\x65\x67\x65\x73\x3e\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x71\x75\x65\x73\x74\x65\x64\x45\x78\x65\x63\x75\x74\x69\x6f\x6e\x4c\x65\x76\x65\x6c\x20\x6c\x65\x76\x65\x6c\x3d\x27\x61\x73\x49\x6e\x76\x6f\x6b\x65\x72\x27\x20\x75\x69\x41\x63\x63\x65\x73\x73\x3d\x27\x66\x61\x6c\x73\x65\x27\x20\x2f\x3e\x0d\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x72\x65\x71\x75\x65\x73\x74\x65\x64\x50\x72\x69\x76\x69\x6c\x65\x67\x65\x73\x3e\x0d\x0a\x20\x20\x20\x20\x3c\x2f\x73\x65\x63\x75\x72\x69\x74\x79\x3e\x0d\x0a\x20\x20\x3c\x2f\x74\x72\x75\x73\x74\x49\x6e\x66\x6f\x3e\x0d\x0a\x3c\x2f\x61\x73\x73\x65\x6d\x62\x6c\x79\x3e\x0d\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x40\x01\x00\x00\x24\x30\xb1\x30\xea\x30\xde\x31\xed\x31\x7f\x32\x89\x32\xa1\x32\xa9\x32\xae\x32\xc2\x32\xd5\x32\xdb\x32\x07\x33\x14\x33\x1e\x33\x36\x33\x3e\x33\x43\x33\x8a\x33\xb3\x33\xdd\x33\xf0\x33\x1e\x34\x35\x34\x45\x34\x64\x34\x6a\x34\x77\x34\x8a\x34\x93\x34\xbb\x34\xc0\x34\xc8\x34\xd3\x34\xe6\x34\xed\x34\xf3\x34\xf9\x34\x01\x35\x1e\x35\x27\x35\x2c\x35\x34\x35\x3d\x35\x43\x35\x4d\x35\x57\x35\x61\x35\x74\x35\x8e\x35\x95\x35\xe2\x35\xed\x35\x05\x36\x0d\x36\x12\x36\x22\x36\x29\x36\x2f\x36\x39\x36\x51\x36\x5f\x36\x68\x36\x70\x36\xf0\x36\xf6\x36\x22\x37\x30\x37\x3a\x37\x52\x37\x5a\x37\x5f\x37\x8e\x37\x94\x37\xa7\x37\xad\x37\xc1\x37\xc9\x37\xd1\x37\x16\x38\x7b\x38\xaa\x38\xba\x38\xd1\x38\xe2\x38\xf3\x38\xf8\x38\x11\x39\x16\x39\x23\x39\x70\x39\x8d\x39\x97\x39\xa5\x39\xb7\x39\xcc\x39\x0a\x3a\xe3\x3a\x16\x3b\x64\x3b\x6d\x3b\x78\x3b\x7f\x3b\x9f\x3b\xa5\x3b\xab\x3b\xb1\x3b\xb7\x3b\xbd\x3b\xc4\x3b\xcb\x3b\xd2\x3b\xd9\x3b\xe0\x3b\xe7\x3b\xee\x3b\xf6\x3b\xfe\x3b\x06\x3c\x12\x3c\x1b\x3c\x20\x3c\x26\x3c\x30\x3c\x3a\x3c\x4a\x3c\x5a\x3c\x6a\x3c\x73\x3c\xd8\x3c\x88\x3d\xb9\x3d\x08\x3e\x1b\x3e\x2e\x3e\x3a\x3e\x4a\x3e\x5b\x3e\x81\x3e\x96\x3e\x9d\x3e\xa3\x3e\xb5\x3e\xbf\x3e\x20\x3f\x2d\x3f\x54\x3f\x5c\x3f\x75\x3f\xaf\x3f\xca\x3f\xd6\x3f\xe5\x3f\xee\x3f\xfb\x3f\x00\x20\x00\x00\x20\x01\x00\x00\x2a\x30\x32\x30\x3d\x30\x43\x30\x49\x30\x55\x30\x78\x30\xa9\x30\x54\x31\x73\x31\x7d\x31\x8e\x31\x9a\x31\xa3\x31\xa8\x31\xce\x31\xd3\x31\xf8\x31\x01\x32\x1e\x32\x60\x32\x6e\x32\x89\x32\x94\x32\x23\x33\x2c\x33\x34\x33\x7b\x33\x8a\x33\x91\x33\xc7\x33\xd0\x33\xdd\x33\xe8\x33\xf1\x33\x00\x34\x1b\x34\x32\x34\x4d\x34\x70\x34\x80\x34\x98\x34\xc3\x34\xe9\x34\x0c\x35\x1c\x35\x34\x35\x5f\x35\x81\x35\x8f\x35\xf8\x35\x79\x36\x81\x36\x93\x36\xe4\x36\x0c\x37\xb2\x37\x05\x38\x18\x38\x90\x38\x2e\x39\x41\x39\x55\x39\x61\x39\x9d\x39\xad\x39\xc4\x39\xcc\x39\xf6\x39\x12\x3a\x21\x3a\x2d\x3a\x3b\x3a\x5d\x3a\x6d\x3a\x72\x3a\x77\x3a\xad\x3a\xb2\x3a\xb7\x3a\xf0\x3a\xf5\x3a\xfa\x3a\x2a\x3b\x2f\x3b\x34\x3b\x73\x3b\x78\x3b\x7d\x3b\xa4\x3b\xad\x3b\xb2\x3b\xb7\x3b\xdb\x3b\xe7\x3b\xec\x3b\xf1\x3b\x15\x3c\x21\x3c\x26\x3c\x2b\x3c\x52\x3c\x5e\x3c\x63\x3c\x68\x3c\x98\x3c\xa0\x3c\xab\x3c\xb8\x3c\xce\x3c\xe0\x3c\xec\x3c\x15\x3d\x21\x3d\x38\x3e\x69\x3e\x7e\x3e\x98\x3e\xb2\x3e\xc0\x3e\xc6\x3e\xdb\x3e\xf7\x3e\x09\x3f\x14\x3f\x29\x3f\x33\x3f\x41\x3f\x5c\x3f\x6d\x3f\x79\x3f\x95\x3f\xb5\x3f\xc3\x3f\xca\x3f\xd0\x3f\xe2\x3f\xf4\x3f\xf9\x3f\x00\x00\x00\x30\x00\x00\x78\x00\x00\x00\x0c\x30\x71\x30\x7d\x30\xf5\x30\x0f\x31\x18\x31\x38\x31\x52\x31\x61\x31\x6f\x31\x7b\x31\x87\x31\x95\x31\xa5\x31\xba\x31\xd1\x31\xf4\x31\x09\x32\x1f\x32\x2c\x32\x3a\x32\x48\x32\x53\x32\x69\x32\x7d\x32\x86\x32\xf7\x35\x00\x36\x08\x36\xa6\x36\xc3\x37\xd5\x37\x0b\x39\x94\x39\x98\x39\x9c\x39\xa0\x39\xa4\x39\xa8\x39\xac\x39\xb0\x39\x96\x3e\xb2\x3e\xb6\x3e\xba\x3e\xbe\x3e\xc2\x3e\xc6\x3e\xca\x3e\xce\x3e\xd2\x3e\xd6\x3e\xda\x3e\xde\x3e\x30\x3f\x00\x00\x00\x40\x00\x00\x88\x00\x00\x00\x65\x33\x7f\x33\xd4\x33\xf1\x33\x17\x34\x80\x34\xff\x36\x33\x37\x5a\x37\x74\x37\xc0\x37\xf4\x38\x0a\x39\x41\x39\x71\x39\x80\x39\x96\x39\xac\x39\xc3\x39\xca\x39\xd6\x39\xe9\x39\xee\x39\xfa\x39\xff\x39\x10\x3a\x7a\x3a\x81\x3a\x93\x3a\x9c\x3a\xe4\x3a\xf6\x3a\xfe\x3a\x08\x3b\x11\x3b\x22\x3b\x34\x3b\x4f\x3b\x7b\x3b\x82\x3b\xb5\x3b\xba\x3b\xe0\x3c\xf8\x3c\x25\x3d\x40\x3d\x50\x3d\x55\x3d\x5f\x3d\x64\x3d\x6f\x3d\x7a\x3d\x8e\x3d\xdf\x3d\x83\x3e\x96\x3e\xa5\x3e\xc6\x3e\x1f\x3f\x2a\x3f\x79\x3f\x91\x3f\xdb\x3f\x00\x00\x00\x50\x00\x00\x08\x01\x00\x00\x71\x30\x88\x30\x06\x31\x4a\x31\x5c\x31\x92\x31\x97\x31\xa4\x31\xb0\x31\xc6\x31\xd9\x31\x0c\x32\x1b\x32\x20\x32\x31\x32\x37\x32\x42\x32\x4a\x32\x55\x32\x5b\x32\x66\x32\x6c\x32\x7a\x32\x83\x32\x88\x32\xa8\x32\xad\x32\xce\x32\xeb\x32\x19\x33\x1f\x33\x31\x33\x6f\x33\x75\x33\xfc\x33\x69\x34\x6f\x34\xc1\x37\xaf\x38\xb9\x38\xc6\x38\xf9\x38\x0b\x39\x3b\x39\x58\x39\x63\x39\xb5\x39\xbc\x39\xcf\x39\xff\x39\x32\x3a\x45\x3a\x5c\x3a\x64\x3a\xa0\x3a\xb0\x3a\xc7\x3a\xcf\x3a\xf6\x3a\x0f\x3b\x1e\x3b\x2a\x3b\x38\x3b\x5a\x3b\x6c\x3b\x77\x3b\x7c\x3b\x81\x3b\x9c\x3b\xa6\x3b\xc2\x3b\xcd\x3b\xd2\x3b\xd7\x3b\xf2\x3b\xfc\x3b\x18\x3c\x23\x3c\x28\x3c\x2d\x3c\x48\x3c\x52\x3c\x6e\x3c\x79\x3c\x7e\x3c\x83\x3c\xa1\x3c\xab\x3c\xc7\x3c\xd2\x3c\xd7\x3c\xdc\x3c\xfd\x3c\x0d\x3d\x29\x3d\x34\x3d\x39\x3d\x3e\x3d\x71\x3d\x95\x3d\xb1\x3d\xbc\x3d\xc1\x3d\xc6\x3d\xe4\x3d\x07\x3e\x12\x3e\x1f\x3e\x34\x3e\x3f\x3e\x53\x3e\x58\x3e\x5d\x3e\x7f\x3e\x8d\x3e\x9c\x3e\xc0\x3e\xd2\x3e\xde\x3e\xec\x3e\x0d\x3f\x14\x3f\x2a\x3f\x40\x3f\x4d\x3f\x52\x3f\x60\x3f\x00\x00\x00\x60\x00\x00\x74\x00\x00\x00\x42\x30\x61\x30\x66\x30\x63\x31\x9c\x31\xcc\x31\xe7\x31\x22\x32\x59\x32\x6b\x32\xa1\x32\xc4\x32\x1e\x33\x2e\x33\x81\x33\x9b\x33\x2f\x35\x36\x36\x6c\x36\x89\x37\xa5\x37\xf8\x37\x20\x39\xd3\x3a\x23\x3b\x54\x3b\x84\x3b\xcf\x3b\xcb\x3c\xdf\x3c\x5b\x3d\x14\x3e\x1b\x3e\x43\x3e\x5d\x3e\x74\x3e\x7b\x3e\xb0\x3e\xc1\x3e\xdc\x3e\xe8\x3e\xf9\x3e\x02\x3f\x37\x3f\x48\x3f\x62\x3f\x6b\x3f\x78\x3f\x82\x3f\xa4\x3f\xb5\x3f\xca\x3f\xd4\x3f\xf7\x3f\x00\x70\x00\x00\x78\x00\x00\x00\x01\x30\xf4\x34\xbf\x37\xfe\x37\x05\x38\x15\x38\x24\x38\x2b\x38\x43\x38\x4a\x38\x68\x38\x7d\x3a\x88\x3a\xc4\x3a\xd6\x3a\xdc\x3a\x81\x3b\x8c\x3b\x96\x3b\x9c\x3b\xb0\x3b\xbc\x3b\xe0\x3b\xf9\x3b\x26\x3c\x2d\x3c\x38\x3c\x46\x3c\x4d\x3c\x53\x3c\x6e\x3c\x75\x3c\x7e\x3c\xf8\x3c\x07\x3d\x19\x3d\x2b\x3d\x47\x3d\x65\x3d\x6f\x3d\x80\x3d\x85\x3d\x9a\x3d\xcd\x3d\xd4\x3d\xdb\x3d\xe2\x3d\xfc\x3d\x0b\x3e\x15\x3e\x22\x3e\x2c\x3e\x3c\x3e\x94\x3e\xcc\x3e\xe7\x3e\x00\x80\x00\x00\xb8\x00\x00\x00\xf9\x30\x26\x31\x47\x31\x4c\x31\x57\x31\x6b\x31\x76\x31\x8d\x31\xbd\x31\xd2\x31\xe0\x31\xe9\x31\x1e\x32\x55\x32\x8b\x32\x9e\x32\x30\x33\x64\x33\x8b\x33\xd6\x33\x48\x34\x6b\x34\x91\x34\xb3\x34\x3a\x35\x41\x35\x4b\x35\x55\x35\x5a\x35\x60\x35\x65\x35\x76\x35\x9a\x35\xce\x35\xf9\x35\x1b\x36\x48\x36\x5a\x36\x76\x36\x9a\x36\xb5\x36\xc0\x36\xec\x36\x0a\x37\x15\x37\x92\x37\x99\x37\xa0\x37\xa7\x37\xb4\x37\xf5\x37\x02\x38\x0f\x38\x1c\x38\x33\x38\xfa\x38\x77\x39\x80\x39\x98\x39\xaa\x39\xd7\x39\x05\x3a\x39\x3a\x41\x3a\x5a\x3a\x6c\x3a\x78\x3a\x80\x3a\x98\x3a\xaf\x3a\xe3\x3a\xde\x3b\x5d\x3c\x8a\x3c\x0d\x3d\x8d\x3d\xc0\x3d\xd5\x3d\xe6\x3d\x6c\x3e\x82\x3e\xc2\x3e\xde\x3e\xfd\x3e\x2d\x3f\xb9\x3f\xd8\x3f\x00\x00\x00\x90\x00\x00\x88\x00\x00\x00\x11\x30\x38\x30\x43\x30\x53\x30\xca\x30\x01\x31\x20\x31\x36\x31\x40\x31\x5f\x31\x7d\x31\xec\x31\x15\x32\x3e\x32\x5c\x32\xda\x32\x03\x33\x2c\x33\x48\x33\xd1\x33\xff\x33\x30\x34\x4c\x34\x7f\x34\x9c\x34\xbe\x34\x3d\x35\x99\x35\x39\x36\xa8\x36\xb2\x36\x00\x37\xd8\x37\xf2\x37\x32\x38\x41\x38\x4f\x38\x6c\x38\x74\x38\x9d\x38\xa4\x38\xc0\x38\xc7\x38\xde\x38\xf4\x38\x2f\x39\x36\x39\x86\x39\x9a\x39\x09\x3a\x5d\x3a\xe3\x3a\xdd\x3b\xd0\x3c\x1d\x3d\xf5\x3d\x5e\x3e\x88\x3e\xb7\x3e\x1d\x3f\x56\x3f\x6c\x3f\x8d\x3f\x00\x00\x00\xa0\x00\x00\x18\x00\x00\x00\x05\x30\xba\x35\x26\x36\xf9\x3d\x01\x3e\x38\x3e\x3f\x3e\x00\x00\x00\xb0\x00\x00\x54\x00\x00\x00\x69\x31\x5e\x32\x66\x32\x9d\x32\xa4\x32\xa9\x35\xed\x38\xf4\x38\xfb\x38\x02\x39\x5a\x3b\x61\x3b\xd3\x3b\xe7\x3b\x1f\x3c\x31\x3c\x43\x3c\x55\x3c\x67\x3c\x79\x3c\x8b\x3c\x9d\x3c\xaf\x3c\xc1\x3c\xd3\x3c\xe5\x3c\xf7\x3c\x18\x3d\x2a\x3d\x3c\x3d\x4e\x3d\x60\x3d\x99\x3e\xdf\x3e\x68\x3f\x7a\x3f\xe3\x3f\xe9\x3f\x00\xc0\x00\x00\x94\x00\x00\x00\x48\x30\x4e\x30\x5b\x30\x8e\x30\x2c\x31\x42\x31\x9c\x31\xd9\x31\xe3\x31\xfe\x31\x5b\x32\x8e\x32\xae\x32\xd8\x32\x98\x33\xa2\x33\xcc\x33\x18\x34\x27\x34\x46\x34\x57\x34\x32\x35\x72\x35\xdd\x35\xf7\x35\x04\x36\x34\x36\x58\x36\x63\x36\x70\x36\x82\x36\xca\x36\xe3\x36\x67\x37\x7c\x37\x85\x37\x8e\x37\xa4\x37\x09\x38\x0f\x38\x14\x38\x1a\x38\x2b\x38\xe8\x3a\x2d\x3b\x09\x3c\x89\x3c\xcd\x3c\xa4\x3d\xe9\x3d\xf1\x3d\xf9\x3d\x01\x3e\x09\x3e\x27\x3e\x2f\x3e\x91\x3e\x9d\x3e\xb1\x3e\xbd\x3e\xc9\x3e\xe9\x3e\x30\x3f\x5a\x3f\x62\x3f\x7f\x3f\x8f\x3f\x9b\x3f\xaa\x3f\x00\x00\x00\xd0\x00\x00\x7c\x00\x00\x00\xae\x30\xdf\x30\x21\x31\x58\x31\x75\x31\x89\x31\x94\x31\xe1\x31\x69\x32\xd0\x32\x85\x33\xf9\x33\x16\x34\x26\x34\x7b\x34\x7c\x35\x8c\x35\x9d\x35\xa5\x35\xb5\x35\xc6\x35\x2c\x36\x37\x36\x42\x36\x48\x36\x51\x36\x93\x36\xbe\x36\xe3\x36\xef\x36\xfb\x36\x0e\x37\x2d\x37\x58\x37\x70\x37\xb5\x37\xc1\x37\xcd\x37\xd9\x37\xec\x37\x10\x38\x90\x38\xb2\x39\xc4\x39\xd6\x39\x46\x3a\xa7\x3a\x02\x3b\x70\x3b\x8f\x3b\xc0\x3b\x15\x3d\x4f\x3e\x6a\x3e\x80\x3e\x96\x3e\x9e\x3e\x00\x00\x00\xe0\x00\x00\x4c\x00\x00\x00\xf7\x31\xfa\x32\x0b\x33\x92\x35\x98\x35\x9e\x35\x06\x36\x0b\x36\x1d\x36\x3b\x36\x4f\x36\x55\x36\xa1\x37\xbe\x37\xc2\x39\xde\x39\xb4\x3a\xc7\x3a\xe5\x3a\xf3\x3a\xa1\x3c\xd8\x3c\xdf\x3c\xe4\x3c\xe8\x3c\xec\x3c\xf0\x3c\x46\x3d\x8b\x3d\x90\x3d\x94\x3d\x98\x3d\x9c\x3d\x00\x00\x00\xf0\x00\x00\x30\x00\x00\x00\x34\x30\x47\x30\x65\x30\x73\x30\x21\x32\x58\x32\x5f\x32\x64\x32\x68\x32\x6c\x32\x70\x32\xc6\x32\x0b\x33\x10\x33\x14\x33\x18\x33\x1c\x33\x86\x35\xc2\x36\x00\x00\x00\x00\x01\x00\x44\x01\x00\x00\x64\x31\x74\x31\x78\x31\x7c\x31\x88\x31\x8c\x31\x90\x31\xa4\x31\xa8\x31\xac\x31\xd4\x31\xd8\x31\xdc\x31\xe0\x31\x50\x33\x54\x33\x58\x33\x5c\x33\x60\x33\x64\x33\x68\x33\x6c\x33\x70\x33\x74\x33\x78\x33\x7c\x33\x80\x33\x84\x33\x88\x33\x8c\x33\x90\x33\x94\x33\x98\x33\x9c\x33\xa0\x33\xa4\x33\xa8\x33\xac\x33\xb0\x33\xb4\x33\xb8\x33\xbc\x33\xc0\x33\xc4\x33\xc8\x33\xcc\x33\xd0\x33\xd4\x33\xd8\x33\xdc\x33\xe0\x33\xe4\x33\xe8\x33\xec\x33\xf0\x33\xf4\x33\xf8\x33\xfc\x33\x00\x34\x04\x34\x08\x34\x0c\x34\x10\x34\x14\x34\x18\x34\x1c\x34\x20\x34\x24\x34\x28\x34\x2c\x34\x30\x34\x34\x34\x38\x34\x3c\x34\x40\x34\x44\x34\x48\x34\x4c\x34\x50\x34\x54\x34\x58\x34\x5c\x34\x60\x34\x64\x34\x68\x34\x6c\x34\x70\x34\x74\x34\x78\x34\x7c\x34\x80\x34\x84\x34\x88\x34\x8c\x34\x90\x34\x94\x34\x98\x34\x9c\x34\xa0\x34\xa4\x34\xa8\x34\xac\x34\xb0\x34\xb4\x34\xb8\x34\xbc\x34\xc0\x34\xc4\x34\xc8\x34\xcc\x34\xd0\x34\xd4\x34\xd8\x34\xdc\x34\xf0\x3b\xf8\x3b\x00\x3c\x04\x3c\x08\x3c\x0c\x3c\x10\x3c\x14\x3c\x18\x3c\x1c\x3c\x24\x3c\x28\x3c\x2c\x3c\x30\x3c\x34\x3c\x38\x3c\x3c\x3c\x40\x3c\x4c\x3c\x54\x3c\x58\x3c\x5c\x3c\x60\x3c\x64\x3c\xd0\x3d\xd4\x3d\xd8\x3d\xdc\x3d\xe0\x3d\xe4\x3d\xe8\x3d\xec\x3d\xf0\x3d\xf4\x3d\xf8\x3d\xfc\x3d\x00\x3e\x04\x3e\x08\x3e\x0c\x3e\x10\x3e\x14\x3e\x18\x3e\x1c\x3e\x00\x10\x01\x00\x30\x01\x00\x00\x90\x36\x94\x36\x98\x36\x9c\x36\xa0\x36\xa4\x36\xa8\x36\xac\x36\xb0\x36\xb4\x36\xb8\x36\xbc\x36\xc0\x36\xc4\x36\xc8\x36\xcc\x36\xd0\x36\xd4\x36\xd8\x36\xdc\x36\xe0\x36\xe4\x36\xe8\x36\xec\x36\xf0\x36\xf4\x36\xf8\x36\xfc\x36\x00\x37\x04\x37\x08\x37\x0c\x37\x10\x37\x14\x37\x18\x37\x1c\x37\x20\x37\x24\x37\x28\x37\x2c\x37\x30\x37\x34\x37\x38\x37\x44\x37\x48\x37\x4c\x37\x50\x37\x54\x37\x58\x37\x5c\x37\x60\x37\x64\x37\x68\x37\x6c\x37\x70\x37\x74\x37\x78\x37\x7c\x37\x80\x37\x84\x37\x88\x37\x8c\x37\x90\x37\x94\x37\x98\x37\x9c\x37\xa0\x37\xa4\x37\xa8\x37\xac\x37\xb0\x37\xb4\x37\xb8\x37\xbc\x37\xc0\x37\xc4\x37\xc8\x37\xcc\x37\xd0\x37\xd4\x37\xd8\x37\xdc\x37\xe0\x37\xe4\x37\xe8\x37\xec\x37\xf0\x37\xf4\x37\xf8\x37\xfc\x37\x00\x38\x3c\x3e\x44\x3e\x4c\x3e\x54\x3e\x5c\x3e\x64\x3e\x6c\x3e\x74\x3e\x7c\x3e\x84\x3e\x8c\x3e\x94\x3e\x9c\x3e\xa4\x3e\xac\x3e\xb4\x3e\xbc\x3e\xc4\x3e\xcc\x3e\xd4\x3e\xdc\x3e\xe4\x3e\xec\x3e\xf4\x3e\xfc\x3e\x04\x3f\x0c\x3f\x14\x3f\x1c\x3f\x24\x3f\x2c\x3f\x34\x3f\x3c\x3f\x44\x3f\x4c\x3f\x54\x3f\x5c\x3f\x64\x3f\x6c\x3f\x74\x3f\x7c\x3f\x84\x3f\x8c\x3f\x94\x3f\x9c\x3f\xa4\x3f\xac\x3f\xb4\x3f\xbc\x3f\xc4\x3f\xcc\x3f\xd4\x3f\xdc\x3f\xe4\x3f\xec\x3f\xf4\x3f\xfc\x3f\x00\x20\x01\x00\x88\x01\x00\x00\x04\x30\x0c\x30\x14\x30\x1c\x30\x24\x30\x2c\x30\x34\x30\x3c\x30\x44\x30\x4c\x30\x54\x30\x5c\x30\x64\x30\x6c\x30\x74\x30\x7c\x30\x84\x30\x8c\x30\x94\x30\x9c\x30\xa4\x30\xac\x30\xb4\x30\xbc\x30\xc4\x30\xcc\x30\xd4\x30\xdc\x30\xe4\x30\xec\x30\xf4\x30\xfc\x30\x04\x31\x0c\x31\x14\x31\x1c\x31\x24\x31\x2c\x31\x34\x31\x3c\x31\x44\x31\x4c\x31\x54\x31\x5c\x31\x64\x31\x6c\x31\x74\x31\x7c\x31\x84\x31\x8c\x31\x94\x31\x9c\x31\xa4\x31\xac\x31\xb4\x31\xbc\x31\xc4\x31\xcc\x31\xd4\x31\xdc\x31\xe4\x31\xec\x31\xf4\x31\xfc\x31\x04\x32\x0c\x32\x14\x32\x1c\x32\x24\x32\x2c\x32\x34\x32\x3c\x32\x44\x32\x4c\x32\x54\x32\x5c\x32\x64\x32\x6c\x32\x74\x32\x7c\x32\x84\x32\x8c\x32\x94\x32\x9c\x32\xa4\x32\xac\x32\xb4\x32\xbc\x32\xc4\x32\xcc\x32\xd4\x32\xdc\x32\xe4\x32\xec\x32\xf4\x32\xfc\x32\x04\x33\x0c\x33\x14\x33\x1c\x33\x24\x33\x2c\x33\x34\x33\x3c\x33\x44\x33\x4c\x33\x54\x33\x5c\x33\x64\x33\x6c\x33\x74\x33\x7c\x33\x84\x33\x8c\x33\x94\x33\x9c\x33\xa4\x33\xac\x33\xb4\x33\xbc\x33\xc4\x33\xcc\x33\xd4\x33\xdc\x33\xe4\x33\xec\x33\xf4\x33\xfc\x33\x04\x34\x0c\x34\x14\x34\x1c\x34\x24\x34\x2c\x34\x34\x34\x3c\x34\x44\x34\x4c\x34\x54\x34\x5c\x34\x64\x34\x6c\x34\x74\x34\x7c\x34\x84\x34\x8c\x34\x94\x34\x9c\x34\xa4\x34\xac\x34\xb4\x34\xbc\x34\xc4\x34\xcc\x34\xd4\x34\xdc\x34\xe4\x34\xec\x34\xf4\x34\xfc\x34\x04\x35\x0c\x35\x14\x35\x1c\x35\x24\x35\x2c\x35\x34\x35\x3c\x35\x44\x35\x4c\x35\x54\x35\x60\x3f\x68\x3f\x70\x3f\x78\x3f\x80\x3f\x88\x3f\x90\x3f\x98\x3f\xa0\x3f\xa8\x3f\xb0\x3f\xb8\x3f\xc0\x3f\xc8\x3f\xd0\x3f\xd8\x3f\xe0\x3f\xe8\x3f\xf0\x3f\xf8\x3f\x00\x00\x00\x30\x01\x00\xa8\x01\x00\x00\x00\x30\x08\x30\x10\x30\x18\x30\x20\x30\x28\x30\x30\x30\x38\x30\x40\x30\x48\x30\x50\x30\x58\x30\x60\x30\x68\x30\x70\x30\x78\x30\x80\x30\x88\x30\x90\x30\x98\x30\xa0\x30\xa8\x30\xb0\x30\xb8\x30\xc0\x30\xc8\x30\xd0\x30\xd8\x30\xe0\x30\xe8\x30\xf0\x30\xf8\x30\x00\x31\x08\x31\x10\x31\x18\x31\x20\x31\x28\x31\x30\x31\x38\x31\x40\x31\x48\x31\x50\x31\x58\x31\x60\x31\x68\x31\x70\x31\x78\x31\x80\x31\x88\x31\x90\x31\x98\x31\xa0\x31\xa8\x31\xb0\x31\xb8\x31\xc0\x31\xc8\x31\xd0\x31\xd8\x31\xe0\x31\xe8\x31\xf0\x31\xf8\x31\x00\x32\x08\x32\x10\x32\x18\x32\x20\x32\x28\x32\x30\x32\x38\x32\x40\x32\x48\x32\x50\x32\x58\x32\x60\x32\x68\x32\x70\x32\x78\x32\x80\x32\x88\x32\x90\x32\x98\x32\xa0\x32\xa8\x32\xb0\x32\xb8\x32\xc0\x32\xc8\x32\xd0\x32\xd8\x32\xe0\x32\xe8\x32\xf0\x32\xf8\x32\x00\x33\x08\x33\x10\x33\x18\x33\x20\x33\x28\x33\x30\x33\x38\x33\x40\x33\x48\x33\x50\x33\x58\x33\x60\x33\x68\x33\x70\x33\x78\x33\x80\x33\x88\x33\x90\x33\x98\x33\xa0\x33\xa8\x33\xb0\x33\xb8\x33\xc0\x33\xc8\x33\xd0\x33\xd8\x33\xe0\x33\xe8\x33\xf0\x33\xf8\x33\x00\x34\x08\x34\x10\x34\x18\x34\x20\x34\x28\x34\x30\x34\x38\x34\x40\x34\x48\x34\x50\x34\x58\x34\x60\x34\x68\x34\x70\x34\x78\x34\x80\x34\x88\x34\x90\x34\x98\x34\xa0\x34\xa8\x34\xb0\x34\xb8\x34\xc0\x34\xc8\x34\xd0\x34\xd8\x34\xe0\x34\xe8\x34\xf0\x34\xf8\x34\x00\x35\x08\x35\x10\x35\x18\x35\x20\x35\x28\x35\x30\x35\x38\x35\x40\x35\x48\x35\x50\x35\x58\x35\x60\x35\x68\x35\x70\x35\x78\x35\x80\x35\x88\x35\x90\x35\x98\x35\xa0\x35\xa8\x35\xb0\x35\xb8\x35\xc0\x35\xc8\x35\xd0\x35\xd8\x35\xe0\x35\xe8\x35\xf0\x35\xf8\x35\x00\x36\x08\x36\x10\x36\x18\x36\x20\x36\x28\x36\x30\x36\x38\x36\x40\x36\x48\x36\x50\x36\x58\x36\x60\x36\x68\x36\x70\x36\x78\x36\x00\x40\x01\x00\x10\x00\x00\x00\x5a\x3a\x5e\x3a\x62\x3a\x66\x3a\x00\x50\x01\x00\x94\x00\x00\x00\xfc\x33\x04\x34\x0c\x34\x14\x34\x1c\x34\x24\x34\x2c\x34\x34\x34\x3c\x34\x44\x34\x4c\x34\x54\x34\x5c\x34\x64\x34\x6c\x34\x74\x34\x7c\x34\x84\x34\x8c\x34\x94\x34\x9c\x34\xa4\x34\xac\x34\xb4\x34\xbc\x34\xc4\x34\xcc\x34\xd4\x34\xdc\x34\x2c\x36\x30\x36\x38\x36\xb0\x3a\xd0\x3a\xec\x3a\xf0\x3a\x0c\x3b\x10\x3b\x30\x3b\x50\x3b\x58\x3b\x5c\x3b\x78\x3b\x98\x3b\xb4\x3b\xb8\x3b\xd8\x3b\xf8\x3b\x04\x3c\x20\x3c\x40\x3c\x60\x3c\x80\x3c\xa0\x3c\xc0\x3c\xe0\x3c\x00\x3d\x20\x3d\x40\x3d\x60\x3d\x80\x3d\xa0\x3d\xc0\x3d\xe0\x3d\x00\x3e\x20\x3e\x40\x3e\x5c\x3e\x60\x3e\x00\x00\x00\x70\x01\x00\x4c\x00\x00\x00\x1c\x30\x50\x30\x70\x31\xa0\x31\xb0\x31\xc0\x31\xd0\x31\xe0\x31\xf8\x31\x04\x32\x08\x32\x0c\x32\x28\x32\x2c\x32\x50\x37\x60\x37\x64\x37\x68\x37\x6c\x37\x70\x37\x74\x37\x78\x37\x7c\x37\x80\x37\x84\x37\x90\x37\x94\x37\x98\x37\x9c\x37\xa0\x37\xa4\x37\xa8\x37\xac\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - -func systray386DllBytes() ([]byte, error) { - return bindataRead( - _systray386Dll, - "systray386.dll", - ) -} - -func systray386Dll() (*asset, error) { - bytes, err := systray386DllBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "systray386.dll", size: 94208, mode: os.FileMode(438), modTime: time.Unix(1471643142, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _systrayamd64Dll = "\x4d\x5a\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01\x00\x00\x0e\x1f\xba\x0e\x00\xb4\x09\xcd\x21\xb8\x01\x4c\xcd\x21\x54\x68\x69\x73\x20\x70\x72\x6f\x67\x72\x61\x6d\x20\x63\x61\x6e\x6e\x6f\x74\x20\x62\x65\x20\x72\x75\x6e\x20\x69\x6e\x20\x44\x4f\x53\x20\x6d\x6f\x64\x65\x2e\x0d\x0d\x0a\x24\x00\x00\x00\x00\x00\x00\x00\xfb\xa6\x36\x99\xbf\xc7\x58\xca\xbf\xc7\x58\xca\xbf\xc7\x58\xca\x0b\x5b\xa9\xca\xbb\xc7\x58\xca\x0b\x5b\xab\xca\xd0\xc7\x58\xca\x0b\x5b\xaa\xca\xb3\xc7\x58\xca\xd1\x9c\x5b\xcb\xb8\xc7\x58\xca\xd1\x9c\x5d\xcb\xab\xc7\x58\xca\xd1\x9c\x5c\xcb\xaf\xc7\x58\xca\x62\x38\x93\xca\xb6\xc7\x58\xca\xbf\xc7\x59\xca\xd8\xc7\x58\xca\x6d\x9c\x51\xcb\xbc\xc7\x58\xca\x6d\x9c\x58\xcb\xbe\xc7\x58\xca\x6d\x9c\xa7\xca\xbe\xc7\x58\xca\x6d\x9c\x5a\xcb\xbe\xc7\x58\xca\x52\x69\x63\x68\xbf\xc7\x58\xca\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x45\x00\x00\x64\x86\x07\x00\x04\x7e\xb7\x57\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x00\x22\x20\x0b\x02\x0e\x00\x00\xec\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x00\xb0\x1c\x00\x00\x00\x10\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x04\x00\x00\x00\x00\x00\x00\x02\x00\x60\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\xe0\x8f\x01\x00\xa1\x00\x00\x00\x84\x90\x01\x00\x64\x00\x00\x00\x00\xe0\x01\x00\xe0\x01\x00\x00\x00\xc0\x01\x00\xcc\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x01\x00\x10\x06\x00\x00\xf0\x7d\x01\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x7e\x01\x00\x94\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xd8\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x74\x65\x78\x74\x00\x00\x00\xa0\xeb\x00\x00\x00\x10\x00\x00\x00\xec\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x60\x2e\x72\x64\x61\x74\x61\x00\x00\x3e\x9a\x00\x00\x00\x00\x01\x00\x00\x9c\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x40\x2e\x64\x61\x74\x61\x00\x00\x00\x28\x1e\x00\x00\x00\xa0\x01\x00\x00\x0a\x00\x00\x00\x8c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\xc0\x2e\x70\x64\x61\x74\x61\x00\x00\xcc\x0f\x00\x00\x00\xc0\x01\x00\x00\x10\x00\x00\x00\x96\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x40\x2e\x67\x66\x69\x64\x73\x00\x00\x98\x00\x00\x00\x00\xd0\x01\x00\x00\x02\x00\x00\x00\xa6\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x40\x2e\x72\x73\x72\x63\x00\x00\x00\xe0\x01\x00\x00\x00\xe0\x01\x00\x00\x02\x00\x00\x00\xa8\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x40\x2e\x72\x65\x6c\x6f\x63\x00\x00\x10\x06\x00\x00\x00\xf0\x01\x00\x00\x08\x00\x00\x00\xaa\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8b\xc2\x48\x8b\xf9\x48\x85\xd2\x75\x04\x48\x8d\x41\x28\x4c\x89\x41\x38\x48\x8d\x15\x53\x00\x00\x00\x4c\x89\x49\x40\x4c\x8b\xc1\x4c\x8d\x49\x20\x48\x8b\xc8\xe8\x4c\x1f\x00\x00\x8b\xd8\x85\xc0\x74\x10\x0f\xb7\xd8\x81\xcb\x00\x00\x07\x80\x85\xc0\x0f\x4e\xd8\xeb\x16\x4c\x8b\x47\x08\xba\x02\x00\x00\x00\x48\x8b\x4f\x20\x45\x0f\xb7\x08\xe8\xa4\x1f\x00\x00\x48\x8b\x74\x24\x38\x8b\xc3\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x54\x41\x56\x41\x57\x48\x83\xec\x40\x48\x8b\x9c\x24\x90\x00\x00\x00\x4d\x8b\xf9\x41\x8a\xf0\x44\x8b\xf2\x4c\x8b\xe1\x48\x85\xdb\x74\x6d\x48\x8b\xac\x24\x80\x00\x00\x00\x8b\xc2\x85\xd2\x74\x22\x83\xf8\x01\x75\x20\x41\x0f\xb6\xc8\xb8\x00\x01\x00\x00\xff\xc1\x4c\x89\x4b\x10\x45\x84\xc0\x48\x89\x6b\x18\x0f\x45\xc1\x89\x03\xeb\x03\x83\x23\x00\x48\x8b\x7b\x38\x48\x85\xff\x74\x31\x48\x8b\xcf\xe8\x1a\x14\x00\x00\x48\x8b\x43\x40\x4d\x8b\xcf\x48\x89\x44\x24\x30\x44\x8a\xc6\x48\x8b\x84\x24\x88\x00\x00\x00\x41\x8b\xd6\x48\x89\x44\x24\x28\x49\x8b\xcc\x48\x89\x6c\x24\x20\xff\xd7\x48\x8b\x5c\x24\x60\x48\x8b\x6c\x24\x68\x48\x8b\x74\x24\x70\x48\x8b\x7c\x24\x78\x48\x83\xc4\x40\x41\x5f\x41\x5e\x41\x5c\xc3\xcc\xcc\x40\x53\x48\x83\xec\x40\x48\x8d\x05\xab\x6d\x01\x00\x44\x8b\xd2\x44\x2b\xd0\x4d\x8b\xd8\x8a\x05\x4f\x6e\x01\x00\x4c\x8d\x42\x04\x8b\x02\x48\x8b\xd9\x48\x8b\x54\x24\x78\x41\x81\xca\x00\x00\x00\x0b\x89\x44\x24\x34\x41\x8b\x00\x89\x44\x24\x38\x41\x8b\x40\x04\x49\x83\xc0\x08\x89\x44\x24\x3c\x48\x8b\x41\x08\x48\x89\x02\x48\x8b\x41\x08\x48\x89\x54\x24\x28\x44\x89\x54\x24\x30\x0f\xb7\x08\x4c\x89\x42\x10\x89\x4a\x08\xc7\x42\x0c\x02\x00\x00\x00\x41\x0f\xb7\x00\x4d\x8b\xc3\x89\x42\x18\x8b\x44\x24\x70\xc7\x42\x1c\x01\x00\x00\x00\x48\x8d\x54\x24\x30\x48\x8b\x4b\x20\x89\x44\x24\x20\xe8\x0f\x1f\x00\x00\x48\x83\xc4\x40\x5b\xc3\xcc\xcc\xcc\xcc\xcc\xb8\x01\x00\x00\x00\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x40\x53\x48\x83\xec\x40\x48\x8b\xd9\x48\x8d\x4c\x24\x58\xff\x15\xbc\xf0\x00\x00\x85\xc0\x75\x4a\xff\x15\xfa\xef\x00\x00\x45\x33\xc9\x33\xd2\x8b\xd8\xb9\x00\x31\x00\x00\x33\xc0\x44\x8b\xc3\x48\x89\x44\x24\x30\x89\x44\x24\x28\x48\x89\x44\x24\x20\xff\x15\xe5\xed\x00\x00\x45\x33\xc9\x48\x8d\x15\x43\x6b\x01\x00\x44\x8b\xc3\x48\x8d\x0d\x19\x6b\x01\x00\xe8\x74\x06\x00\x00\x48\x83\xc4\x40\x5b\xc3\x48\x8b\xcb\xff\x15\x5d\xf0\x00\x00\x44\x8b\x4c\x24\x5c\x33\xc0\x44\x8b\x44\x24\x58\x48\x8b\x0d\x92\xab\x01\x00\x48\x89\x44\x24\x30\x8d\x50\x20\x48\x89\x5c\x24\x28\x89\x44\x24\x20\xff\x15\x2b\xf0\x00\x00\x48\x83\xc4\x40\x5b\xc3\xcc\xcc\xcc\xcc\xcc\x48\x81\xec\x98\x00\x00\x00\x8b\xd1\xc7\x44\x24\x40\x50\x00\x00\x00\x48\x8b\x0d\x58\xab\x01\x00\x4c\x8d\x4c\x24\x40\x41\xb8\x01\x00\x00\x00\xc7\x44\x24\x44\x20\x00\x00\x00\xff\x15\xe7\xef\x00\x00\x85\xc0\x75\x5f\x48\x89\x9c\x24\x90\x00\x00\x00\xff\x15\x35\xef\x00\x00\x45\x33\xc9\x33\xd2\x8b\xd8\xb9\x00\x31\x00\x00\x33\xc0\x44\x8b\xc3\x48\x89\x44\x24\x30\x89\x44\x24\x28\x48\x89\x44\x24\x20\xff\x15\x20\xed\x00\x00\x45\x33\xc9\x48\x8d\x15\x96\x6a\x01\x00\x44\x8b\xc3\x48\x8d\x0d\x54\x6a\x01\x00\xe8\xaf\x05\x00\x00\x48\x8b\x9c\x24\x90\x00\x00\x00\x83\xc8\xff\x48\x81\xc4\x98\x00\x00\x00\xc3\x8b\x44\x24\x70\x48\x81\xc4\x98\x00\x00\x00\xc3\x48\x83\xec\x28\x83\xfa\x02\x74\x54\x81\xfa\x26\x01\x00\x00\x74\x30\x81\xfa\x01\x04\x00\x00\x75\x11\x49\x8b\xc1\x48\x2d\x02\x02\x00\x00\x74\x11\x48\x83\xf8\x03\x74\x0b\x48\x83\xc4\x28\x48\xff\x25\x33\xef\x00\x00\xe8\x86\xfe\xff\xff\x33\xc0\x48\x83\xc4\x28\xc3\x41\x8b\xc8\xe8\x17\xff\xff\xff\x83\xf8\xff\x74\x17\x8b\xc8\xff\x15\x9a\xa6\x01\x00\x33\xc0\x48\x83\xc4\x28\xc3\x33\xc9\xff\x15\x0b\xef\x00\x00\x33\xc0\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\xcc\x48\x83\xec\x78\x48\x8d\x05\x85\xff\xff\xff\x48\x89\x4c\x24\x38\x48\x89\x44\x24\x28\xba\x00\x7f\x00\x00\x33\xc0\xc7\x44\x24\x20\x50\x00\x00\x00\x33\xc9\x48\x89\x44\x24\x30\xc7\x44\x24\x24\x03\x00\x00\x00\xff\x15\xb7\xee\x00\x00\xba\x00\x7f\x00\x00\x33\xc9\x48\x89\x44\x24\x40\xff\x15\x9d\xee\x00\x00\x66\x0f\x6f\x05\xed\x69\x01\x00\xba\x00\x7f\x00\x00\x48\x89\x44\x24\x48\x33\xc9\x48\x8d\x05\xaa\x69\x01\x00\x66\x0f\x7f\x44\x24\x50\x48\x89\x44\x24\x60\xff\x15\x79\xee\x00\x00\x48\x8d\x4c\x24\x20\x48\x89\x44\x24\x68\xff\x15\x59\xee\x00\x00\x48\x83\xc4\x78\xc3\xcc\xcc\xcc\xcc\x40\x53\x48\x83\xec\x60\x33\xc0\x4c\x8d\x05\x6d\x69\x01\x00\x48\x89\x44\x24\x58\x48\x8d\x15\x65\x69\x01\x00\x48\x89\x4c\x24\x50\x41\xb9\x00\x00\xcf\x00\x48\x89\x44\x24\x48\x33\xc9\x48\x89\x44\x24\x40\x89\x44\x24\x38\xc7\x44\x24\x30\x00\x00\x00\x80\x89\x44\x24\x28\xc7\x44\x24\x20\x00\x00\x00\x80\xff\x15\xf8\xed\x00\x00\x48\x8b\xd8\x48\x85\xc0\x75\x06\x48\x83\xc4\x60\x5b\xc3\x33\xd2\x48\x8b\xc8\xff\x15\xd7\xed\x00\x00\x48\x8b\xcb\xff\x15\x26\xee\x00\x00\x48\x8b\xc3\x48\x83\xc4\x60\x5b\xc3\xcc\xcc\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x81\xec\x80\x00\x00\x00\x48\x8b\xf9\x48\x89\x15\x59\xa5\x01\x00\x33\xc9\xff\x15\x41\xeb\x00\x00\x48\x8b\xc8\x48\x8b\xd8\xe8\xc6\xfe\xff\xff\x48\x8b\xcb\xe8\x4e\xff\xff\xff\x48\x89\x05\x3f\xa5\x01\x00\x48\x85\xc0\x0f\x84\xdf\x00\x00\x00\xff\x15\x70\xed\x00\x00\x48\x8d\x54\x24\x20\xc7\x44\x24\x20\x28\x00\x00\x00\x48\x8b\xc8\x48\x89\x05\xf1\xa8\x01\x00\xc7\x44\x24\x24\x10\x00\x00\x80\xc7\x44\x24\x28\x00\x00\x00\x08\xff\x15\x3b\xed\x00\x00\x85\xc0\x0f\x84\xa4\x00\x00\x00\x48\x8b\x05\xf4\xa4\x01\x00\x48\x8d\x15\xf5\xa4\x01\x00\x33\xc9\x48\x89\x05\xf4\xa4\x01\x00\xc7\x05\xe2\xa4\x01\x00\xd0\x03\x00\x00\xc7\x05\xe8\xa4\x01\x00\x64\x00\x00\x00\xc7\x05\xe6\xa4\x01\x00\x01\x04\x00\x00\xc7\x05\xd8\xa4\x01\x00\x01\x00\x00\x00\xff\x15\xa6\xec\x00\x00\x85\xc0\x74\x5b\x33\xc9\xff\xd7\x45\x33\xc9\x48\x8d\x4c\x24\x48\x45\x33\xc0\x33\xd2\xff\x15\xcb\xec\x00\x00\x85\xc0\x74\x2d\x48\x8d\x4c\x24\x48\xff\x15\xb4\xec\x00\x00\x48\x8d\x4c\x24\x48\xff\x15\xa1\xec\x00\x00\x45\x33\xc9\x48\x8d\x4c\x24\x48\x45\x33\xc0\x33\xd2\xff\x15\x9e\xec\x00\x00\x85\xc0\x75\xd3\x33\xc0\x48\x8b\x9c\x24\x90\x00\x00\x00\x48\x81\xc4\x80\x00\x00\x00\x5f\xc3\xb8\x01\x00\x00\x00\x48\x8b\x9c\x24\x90\x00\x00\x00\x48\x81\xc4\x80\x00\x00\x00\x5f\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x83\xec\x48\x41\xb9\x40\x00\x00\x00\xc7\x44\x24\x28\x10\x00\x00\x00\x48\x8b\xd1\xc7\x44\x24\x20\x40\x00\x00\x00\x33\xc9\x45\x8d\x41\xc1\xff\x15\x27\xec\x00\x00\x48\x85\xc0\x75\x52\x48\x89\x5c\x24\x40\xff\x15\xdf\xeb\x00\x00\x45\x33\xc9\x33\xd2\x8b\xd8\xb9\x00\x31\x00\x00\x33\xc0\x44\x8b\xc3\x48\x89\x44\x24\x30\x89\x44\x24\x28\x48\x89\x44\x24\x20\xff\x15\xca\xe9\x00\x00\x45\x33\xc9\x48\x8d\x15\x78\x67\x01\x00\x44\x8b\xc3\x48\x8d\x0d\xfe\x66\x01\x00\x48\x8b\x5c\x24\x40\x48\x83\xc4\x48\xe9\x50\x02\x00\x00\x48\x8d\x15\xb9\xa3\x01\x00\x48\x89\x05\xd2\xa3\x01\x00\xb9\x01\x00\x00\x00\xc7\x05\xb7\xa3\x01\x00\x02\x00\x00\x00\x48\x83\xc4\x48\x48\xff\x25\x80\xeb\x00\x00\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x83\xec\x28\x41\xb9\x80\x00\x00\x00\x4c\x8b\xc1\x41\x8b\xd1\x48\x8d\x0d\xa1\xa3\x01\x00\xe8\x68\x37\x00\x00\x48\x8d\x15\x6d\xa3\x01\x00\xc7\x05\x77\xa3\x01\x00\x04\x00\x00\x00\xb9\x01\x00\x00\x00\x48\x83\xc4\x28\x48\xff\x25\x3b\xeb\x00\x00\xcc\xcc\xcc\x48\x8b\xc4\x48\x81\xec\xe8\x00\x00\x00\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x4c\x89\x70\xf8\x45\x33\xf6\xc7\x44\x24\x40\x50\x00\x00\x00\x48\xc7\x44\x24\x44\x61\x01\x00\x00\x48\x89\x50\x90\x48\x83\xc8\xff\x48\x63\xe9\x0f\x1f\x80\x00\x00\x00\x00\x48\xff\xc0\x66\x44\x39\x34\x42\x75\xf6\xff\xc0\x48\x89\x6c\x24\x70\x89\x84\x24\x80\x00\x00\x00\x66\x41\x83\xf9\x01\x41\x8b\xc6\xb9\x03\x00\x00\x00\x0f\x44\xc1\x66\x83\xbc\x24\x10\x01\x00\x00\x01\x89\x44\x24\x4c\x75\x07\x83\xc8\x08\x89\x44\x24\x4c\x48\x8b\x0d\x9b\xa6\x01\x00\xff\x15\xcd\xea\x00\x00\x8b\xf0\x41\x8b\xfe\x85\xc0\x0f\x8e\xc2\x00\x00\x00\x48\x89\x9c\x24\xf0\x00\x00\x00\x48\x8b\x0d\x79\xa6\x01\x00\x4c\x8d\x8c\x24\x90\x00\x00\x00\x41\xb8\x01\x00\x00\x00\xc7\x84\x24\x90\x00\x00\x00\x50\x00\x00\x00\x8b\xd7\xc7\x84\x24\x94\x00\x00\x00\x20\x00\x00\x00\xff\x15\xf5\xea\x00\x00\x85\xc0\x75\x45\xff\x15\x4b\xea\x00\x00\x4c\x89\x74\x24\x30\x45\x33\xc9\x44\x8b\xc0\x44\x89\x74\x24\x28\x33\xd2\x4c\x89\x74\x24\x20\xb9\x00\x31\x00\x00\x8b\xd8\xff\x15\x37\xe8\x00\x00\x45\x33\xc9\x48\x8d\x15\xad\x65\x01\x00\x44\x8b\xc3\x48\x8d\x0d\x6b\x65\x01\x00\xe8\xc6\x00\x00\x00\xeb\x10\x8b\x84\x24\xc0\x00\x00\x00\x83\xf8\xff\x74\x04\x3b\xe8\x74\x0c\xff\xc7\x3b\xfe\x0f\x8c\x6a\xff\xff\xff\xeb\x1a\x48\x8b\x0d\xe1\xa5\x01\x00\x4c\x8d\x4c\x24\x40\x41\xb8\x01\x00\x00\x00\x8b\xd7\xff\x15\xfe\xe9\x00\x00\x48\x8b\x9c\x24\xf0\x00\x00\x00\x4c\x8b\xb4\x24\xe0\x00\x00\x00\x3b\xfe\x48\x8b\xbc\x24\x08\x01\x00\x00\x48\x8b\xb4\x24\x00\x01\x00\x00\x48\x8b\xac\x24\xf8\x00\x00\x00\x75\x1b\x48\x8b\x0d\x9b\xa5\x01\x00\x4c\x8d\x4c\x24\x40\x41\xb8\x01\x00\x00\x00\x83\xca\xff\xff\x15\xaf\xe9\x00\x00\x48\x81\xc4\xe8\x00\x00\x00\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x8d\x15\x99\xa1\x01\x00\xb9\x02\x00\x00\x00\x48\xff\x25\x75\xe9\x00\x00\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x8d\x05\x51\xa5\x01\x00\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x89\x4c\x24\x08\x48\x89\x54\x24\x10\x4c\x89\x44\x24\x18\x4c\x89\x4c\x24\x20\x53\x56\x57\x48\x83\xec\x30\x48\x8b\xf9\x48\x8d\x74\x24\x58\xb9\x01\x00\x00\x00\xe8\x97\x1e\x00\x00\x48\x8b\xd8\xe8\xbb\xff\xff\xff\x45\x33\xc9\x48\x89\x74\x24\x20\x4c\x8b\xc7\x48\x8b\xd3\x48\x8b\x08\xe8\x8d\x34\x00\x00\x48\x83\xc4\x30\x5f\x5e\x5b\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x3b\x0d\xc9\x86\x01\x00\xf2\x75\x12\x48\xc1\xc1\x10\x66\xf7\xc1\xff\xff\xf2\x75\x02\xf2\xc3\x48\xc1\xc9\x10\xe9\xd3\x03\x00\x00\xcc\xcc\xcc\x48\x83\xec\x28\x85\xd2\x74\x39\x83\xea\x01\x74\x28\x83\xea\x01\x74\x16\x83\xfa\x01\x74\x0a\xb8\x01\x00\x00\x00\x48\x83\xc4\x28\xc3\xe8\x8e\x05\x00\x00\xeb\x05\xe8\x5f\x05\x00\x00\x0f\xb6\xc0\x48\x83\xc4\x28\xc3\x49\x8b\xd0\x48\x83\xc4\x28\xe9\x0f\x00\x00\x00\x4d\x85\xc0\x0f\x95\xc1\x48\x83\xc4\x28\xe9\x2c\x01\x00\x00\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7c\x24\x20\x41\x56\x48\x83\xec\x20\x48\x8b\xf2\x4c\x8b\xf1\x33\xc9\xe8\x02\x06\x00\x00\x84\xc0\x75\x07\x33\xc0\xe9\xe8\x00\x00\x00\xe8\x96\x04\x00\x00\x8a\xd8\x88\x44\x24\x40\x40\xb7\x01\x83\x3d\x2a\x95\x01\x00\x00\x74\x0a\xb9\x07\x00\x00\x00\xe8\x3e\x09\x00\x00\xc7\x05\x14\x95\x01\x00\x01\x00\x00\x00\xe8\xc7\x04\x00\x00\x84\xc0\x74\x67\xe8\x6e\x0a\x00\x00\x48\x8d\x0d\xb3\x0a\x00\x00\xe8\x06\x08\x00\x00\xe8\xc5\x08\x00\x00\x48\x8d\x0d\xce\x08\x00\x00\xe8\xf5\x07\x00\x00\xe8\xd8\x08\x00\x00\x48\x8d\x15\xe5\xe8\x00\x00\x48\x8d\x0d\xbe\xe8\x00\x00\xe8\x41\x35\x00\x00\x85\xc0\x75\x29\xe8\x60\x04\x00\x00\x84\xc0\x74\x20\x48\x8d\x15\x9d\xe8\x00\x00\x48\x8d\x0d\x8e\xe8\x00\x00\xe8\xa9\x34\x00\x00\xc7\x05\xa7\x94\x01\x00\x02\x00\x00\x00\x40\x32\xff\x8a\xcb\xe8\x09\x07\x00\x00\x40\x84\xff\x0f\x85\x4e\xff\xff\xff\xe8\x9f\x08\x00\x00\x48\x8b\xd8\x48\x83\x38\x00\x74\x24\x48\x8b\xc8\xe8\x4e\x06\x00\x00\x84\xc0\x74\x18\x48\x8b\x1b\x48\x8b\xcb\xe8\x6f\x0a\x00\x00\x4c\x8b\xc6\xba\x02\x00\x00\x00\x49\x8b\xce\xff\xd3\xff\x05\xdc\x8e\x01\x00\xb8\x01\x00\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x8b\x7c\x24\x48\x48\x83\xc4\x20\x41\x5e\xc3\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x40\x8a\xf1\x8b\x05\xa8\x8e\x01\x00\x33\xdb\x85\xc0\x7f\x04\x33\xc0\xeb\x50\xff\xc8\x89\x05\x96\x8e\x01\x00\xe8\x6d\x03\x00\x00\x40\x8a\xf8\x88\x44\x24\x38\x83\x3d\x03\x94\x01\x00\x02\x74\x0a\xb9\x07\x00\x00\x00\xe8\x17\x08\x00\x00\xe8\x66\x04\x00\x00\x89\x1d\xec\x93\x01\x00\xe8\x8b\x04\x00\x00\x40\x8a\xcf\xe8\x4b\x06\x00\x00\x33\xd2\x40\x8a\xce\xe8\x65\x06\x00\x00\x84\xc0\x0f\x95\xc3\x8b\xc3\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x48\x8b\xc4\x48\x89\x58\x20\x4c\x89\x40\x18\x89\x50\x10\x48\x89\x48\x08\x56\x57\x41\x56\x48\x83\xec\x40\x4d\x8b\xf0\x8b\xfa\x48\x8b\xf1\x8d\x42\xff\x83\xf8\x01\x77\x2e\xe8\xd9\x00\x00\x00\x8b\xd8\x89\x44\x24\x30\x85\xc0\x0f\x84\xb3\x00\x00\x00\x4d\x8b\xc6\x8b\xd7\x48\x8b\xce\xe8\xb6\xfd\xff\xff\x8b\xd8\x89\x44\x24\x30\x85\xc0\x0f\x84\x98\x00\x00\x00\x83\xff\x01\x75\x08\x48\x8b\xce\xe8\x3b\x0b\x00\x00\x4d\x8b\xc6\x8b\xd7\x48\x8b\xce\xe8\x1a\xf6\xff\xff\x8b\xd8\x89\x44\x24\x30\x83\xff\x01\x75\x34\x85\xc0\x75\x27\x4d\x8b\xc6\x33\xd2\x48\x8b\xce\xe8\xfe\xf5\xff\xff\x4d\x8b\xc6\x33\xd2\x48\x8b\xce\xe8\x65\xfd\xff\xff\x4d\x8b\xc6\x33\xd2\x48\x8b\xce\xe8\x60\x00\x00\x00\x83\xff\x01\x75\x04\x85\xdb\x74\x04\x85\xff\x75\x0c\x48\x8b\xce\xe8\xfb\x0b\x00\x00\x85\xff\x74\x05\x83\xff\x03\x75\x2a\x4d\x8b\xc6\x8b\xd7\x48\x8b\xce\xe8\x2d\xfd\xff\xff\x8b\xd8\x89\x44\x24\x30\x85\xc0\x74\x13\x4d\x8b\xc6\x8b\xd7\x48\x8b\xce\xe8\x1e\x00\x00\x00\x8b\xd8\x89\x44\x24\x30\xeb\x06\x33\xdb\x89\x5c\x24\x30\x8b\xc3\x48\x8b\x5c\x24\x78\x48\x83\xc4\x40\x41\x5e\x5f\x5e\xc3\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x48\x8b\x1d\xe9\xe6\x00\x00\x49\x8b\xf8\x8b\xf2\x48\x8b\xe9\x48\x85\xdb\x75\x05\x8d\x43\x01\xeb\x12\x48\x8b\xcb\xe8\x7f\x08\x00\x00\x4c\x8b\xc7\x8b\xd6\x48\x8b\xcd\xff\xd3\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x49\x8b\xf8\x8b\xda\x48\x8b\xf1\x83\xfa\x01\x75\x05\xe8\x63\x05\x00\x00\x4c\x8b\xc7\x8b\xd3\x48\x8b\xce\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xe9\x67\xfe\xff\xff\xcc\xcc\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\xd9\x33\xc9\xff\x15\xbf\xe3\x00\x00\x48\x8b\xcb\xff\x15\xae\xe3\x00\x00\xff\x15\xb8\xe3\x00\x00\x48\x8b\xc8\xba\x09\x04\x00\xc0\x48\x83\xc4\x20\x5b\x48\xff\x25\xac\xe3\x00\x00\x48\x89\x4c\x24\x08\x48\x83\xec\x38\xb9\x17\x00\x00\x00\xe8\x97\xd3\x00\x00\x85\xc0\x74\x07\xb9\x02\x00\x00\x00\xcd\x29\x48\x8d\x0d\xf7\x8c\x01\x00\xe8\xaa\x00\x00\x00\x48\x8b\x44\x24\x38\x48\x89\x05\xde\x8d\x01\x00\x48\x8d\x44\x24\x38\x48\x83\xc0\x08\x48\x89\x05\x6e\x8d\x01\x00\x48\x8b\x05\xc7\x8d\x01\x00\x48\x89\x05\x38\x8c\x01\x00\x48\x8b\x44\x24\x40\x48\x89\x05\x3c\x8d\x01\x00\xc7\x05\x12\x8c\x01\x00\x09\x04\x00\xc0\xc7\x05\x0c\x8c\x01\x00\x01\x00\x00\x00\xc7\x05\x16\x8c\x01\x00\x01\x00\x00\x00\xb8\x08\x00\x00\x00\x48\x6b\xc0\x00\x48\x8d\x0d\x0e\x8c\x01\x00\x48\xc7\x04\x01\x02\x00\x00\x00\xb8\x08\x00\x00\x00\x48\x6b\xc0\x00\x48\x8b\x0d\x36\x82\x01\x00\x48\x89\x4c\x04\x20\xb8\x08\x00\x00\x00\x48\x6b\xc0\x01\x48\x8b\x0d\x29\x82\x01\x00\x48\x89\x4c\x04\x20\x48\x8d\x0d\x7d\xe5\x00\x00\xe8\x00\xff\xff\xff\x48\x83\xc4\x38\xc3\xcc\xcc\xcc\x40\x53\x56\x57\x48\x83\xec\x40\x48\x8b\xd9\xff\x15\x97\xe2\x00\x00\x48\x8b\xb3\xf8\x00\x00\x00\x33\xff\x45\x33\xc0\x48\x8d\x54\x24\x60\x48\x8b\xce\xff\x15\x85\xe2\x00\x00\x48\x85\xc0\x74\x39\x48\x83\x64\x24\x38\x00\x48\x8d\x4c\x24\x68\x48\x8b\x54\x24\x60\x4c\x8b\xc8\x48\x89\x4c\x24\x30\x4c\x8b\xc6\x48\x8d\x4c\x24\x70\x48\x89\x4c\x24\x28\x33\xc9\x48\x89\x5c\x24\x20\xff\x15\x56\xe2\x00\x00\xff\xc7\x83\xff\x02\x7c\xb1\x48\x83\xc4\x40\x5f\x5e\x5b\xc3\xcc\xcc\xcc\x48\x83\xec\x28\xe8\x67\x08\x00\x00\x85\xc0\x74\x21\x65\x48\x8b\x04\x25\x30\x00\x00\x00\x48\x8b\x48\x08\xeb\x05\x48\x3b\xc8\x74\x14\x33\xc0\xf0\x48\x0f\xb1\x0d\x80\x90\x01\x00\x75\xee\x32\xc0\x48\x83\xc4\x28\xc3\xb0\x01\xeb\xf7\xcc\xcc\xcc\x48\x83\xec\x28\xe8\x2b\x08\x00\x00\x85\xc0\x74\x07\xe8\x5e\x06\x00\x00\xeb\x05\xe8\x27\x37\x00\x00\xb0\x01\x48\x83\xc4\x28\xc3\x48\x83\xec\x28\x33\xc9\xe8\x41\x01\x00\x00\x84\xc0\x0f\x95\xc0\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\x48\x83\xec\x28\xe8\x97\x0c\x00\x00\x84\xc0\x75\x04\x32\xc0\xeb\x12\xe8\xd2\x3c\x00\x00\x84\xc0\x75\x07\xe8\x95\x0c\x00\x00\xeb\xec\xb0\x01\x48\x83\xc4\x28\xc3\x48\x83\xec\x28\xe8\xcb\x3c\x00\x00\xe8\x7e\x0c\x00\x00\xb0\x01\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x49\x8b\xf9\x49\x8b\xf0\x8b\xda\x48\x8b\xe9\xe8\x98\x07\x00\x00\x85\xc0\x75\x17\x83\xfb\x01\x75\x12\x48\x8b\xcf\xe8\xbb\x05\x00\x00\x4c\x8b\xc6\x33\xd2\x48\x8b\xcd\xff\xd7\x48\x8b\x54\x24\x58\x8b\x4c\x24\x50\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xe9\x4b\x30\x00\x00\xcc\xcc\xcc\x48\x83\xec\x28\xe8\x4f\x07\x00\x00\x85\xc0\x74\x10\x48\x8d\x0d\x88\x8f\x01\x00\x48\x83\xc4\x28\xe9\x17\x3a\x00\x00\xe8\x1e\x34\x00\x00\x85\xc0\x75\x05\xe8\xf9\x33\x00\x00\x48\x83\xc4\x28\xc3\x48\x83\xec\x28\x33\xc9\xe8\x41\x3c\x00\x00\x48\x83\xc4\x28\xe9\x0c\x0c\x00\x00\x40\x53\x48\x83\xec\x20\x0f\xb6\x05\x7b\x8f\x01\x00\x85\xc9\xbb\x01\x00\x00\x00\x0f\x44\xc3\x88\x05\x6b\x8f\x01\x00\xe8\x2e\x05\x00\x00\xe8\x59\x0b\x00\x00\x84\xc0\x75\x04\x32\xc0\xeb\x14\xe8\xb8\x3b\x00\x00\x84\xc0\x75\x09\x33\xc9\xe8\xa1\x0b\x00\x00\xeb\xea\x8a\xc3\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x55\x48\x8b\xec\x48\x83\xec\x40\x8b\xd9\x83\xf9\x01\x0f\x87\xa6\x00\x00\x00\xe8\xab\x06\x00\x00\x85\xc0\x74\x2b\x85\xdb\x75\x27\x48\x8d\x0d\xe0\x8e\x01\x00\xe8\xaf\x39\x00\x00\x85\xc0\x74\x04\x32\xc0\xeb\x7a\x48\x8d\x0d\xe4\x8e\x01\x00\xe8\x9b\x39\x00\x00\x85\xc0\x0f\x94\xc0\xeb\x67\x48\x8b\x15\x99\x7f\x01\x00\x49\x83\xc8\xff\x8b\xc2\xb9\x40\x00\x00\x00\x83\xe0\x3f\x2b\xc8\xb0\x01\x49\xd3\xc8\x4c\x33\xc2\x4c\x89\x45\xe0\x4c\x89\x45\xe8\x0f\x10\x45\xe0\x4c\x89\x45\xf0\xf2\x0f\x10\x4d\xf0\x0f\x11\x05\x85\x8e\x01\x00\x4c\x89\x45\xe0\x4c\x89\x45\xe8\x0f\x10\x45\xe0\x4c\x89\x45\xf0\xf2\x0f\x11\x0d\x7d\x8e\x01\x00\xf2\x0f\x10\x4d\xf0\x0f\x11\x05\x79\x8e\x01\x00\xf2\x0f\x11\x0d\x81\x8e\x01\x00\x48\x8b\x5c\x24\x50\x48\x83\xc4\x40\x5d\xc3\xb9\x05\x00\x00\x00\xe8\x54\x02\x00\x00\xcc\xcc\xcc\xcc\x48\x83\xec\x18\x4c\x8b\xc1\xb8\x4d\x5a\x00\x00\x66\x39\x05\x0d\xdf\xff\xff\x75\x7c\x48\x63\x05\x40\xdf\xff\xff\x48\x8d\x15\xfd\xde\xff\xff\x48\x8d\x0c\x10\x81\x39\x50\x45\x00\x00\x75\x62\xb8\x0b\x02\x00\x00\x66\x39\x41\x18\x75\x57\x4c\x2b\xc2\x0f\xb7\x41\x14\x48\x8d\x51\x18\x48\x03\xd0\x0f\xb7\x41\x06\x48\x8d\x0c\x80\x4c\x8d\x0c\xca\x48\x89\x14\x24\x49\x3b\xd1\x74\x18\x8b\x4a\x0c\x4c\x3b\xc1\x72\x0a\x8b\x42\x08\x03\xc1\x4c\x3b\xc0\x72\x08\x48\x83\xc2\x28\xeb\xdf\x33\xd2\x48\x85\xd2\x75\x04\x32\xc0\xeb\x17\xf7\x42\x24\x00\x00\x00\x80\x74\x04\x32\xc0\xeb\x0a\xb0\x01\xeb\x06\x32\xc0\xeb\x02\x32\xc0\x48\x83\xc4\x18\xc3\x40\x53\x48\x83\xec\x20\x8a\xd9\xe8\x53\x05\x00\x00\x33\xd2\x85\xc0\x74\x0b\x84\xdb\x75\x07\x48\x87\x15\x7e\x8d\x01\x00\x48\x83\xc4\x20\x5b\xc3\x40\x53\x48\x83\xec\x20\x80\x3d\xa3\x8d\x01\x00\x00\x8a\xd9\x74\x04\x84\xd2\x75\x0e\x8a\xcb\xe8\x30\x3a\x00\x00\x8a\xcb\xe8\xe5\x09\x00\x00\xb0\x01\x48\x83\xc4\x20\x5b\xc3\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\x15\x27\x7e\x01\x00\x48\x8b\xd9\x8b\xca\x48\x33\x15\x3b\x8d\x01\x00\x83\xe1\x3f\x48\xd3\xca\x48\x83\xfa\xff\x75\x0a\x48\x8b\xcb\xe8\xaf\x37\x00\x00\xeb\x0f\x48\x8b\xd3\x48\x8d\x0d\x1b\x8d\x01\x00\xe8\x2a\x38\x00\x00\x33\xc9\x85\xc0\x48\x0f\x44\xcb\x48\x8b\xc1\x48\x83\xc4\x20\x5b\xc3\xcc\x48\x83\xec\x28\xe8\xa7\xff\xff\xff\x48\xf7\xd8\x1b\xc0\xf7\xd8\xff\xc8\x48\x83\xc4\x28\xc3\xcc\x48\x89\x5c\x24\x20\x55\x48\x8b\xec\x48\x83\xec\x20\x48\x83\x65\x18\x00\x48\xbb\x32\xa2\xdf\x2d\x99\x2b\x00\x00\x48\x8b\x05\xa9\x7d\x01\x00\x48\x3b\xc3\x75\x6f\x48\x8d\x4d\x18\xff\x15\x92\xde\x00\x00\x48\x8b\x45\x18\x48\x89\x45\x10\xff\x15\x7c\xde\x00\x00\x8b\xc0\x48\x31\x45\x10\xff\x15\x68\xde\x00\x00\x8b\xc0\x48\x8d\x4d\x20\x48\x31\x45\x10\xff\x15\x50\xde\x00\x00\x8b\x45\x20\x48\x8d\x4d\x10\x48\xc1\xe0\x20\x48\x33\x45\x20\x48\x33\x45\x10\x48\x33\xc1\x48\xb9\xff\xff\xff\xff\xff\xff\x00\x00\x48\x23\xc1\x48\xb9\x33\xa2\xdf\x2d\x99\x2b\x00\x00\x48\x3b\xc3\x48\x0f\x44\xc1\x48\x89\x05\x35\x7d\x01\x00\x48\x8b\x5c\x24\x48\x48\xf7\xd0\x48\x89\x05\x2e\x7d\x01\x00\x48\x83\xc4\x20\x5d\xc3\x48\x8d\x0d\x79\x8c\x01\x00\x48\xff\x25\x12\xde\x00\x00\xcc\xcc\x48\x8d\x0d\x69\x8c\x01\x00\xe9\xe8\x08\x00\x00\x48\x8d\x05\x6d\x8c\x01\x00\xc3\x48\x83\xec\x28\xe8\xa3\xf5\xff\xff\x48\x83\x08\x04\xe8\xe6\xff\xff\xff\x48\x83\x08\x02\x48\x83\xc4\x28\xc3\xcc\x48\x8d\x05\xf1\x9a\x01\x00\xc3\x83\x25\x49\x8c\x01\x00\x00\xc3\x48\x89\x5c\x24\x08\x55\x48\x8d\xac\x24\x40\xfb\xff\xff\x48\x81\xec\xc0\x05\x00\x00\x8b\xd9\xb9\x17\x00\x00\x00\xe8\x7d\xcd\x00\x00\x85\xc0\x74\x04\x8b\xcb\xcd\x29\x83\x25\x18\x8c\x01\x00\x00\x48\x8d\x4d\xf0\x33\xd2\x41\xb8\xd0\x04\x00\x00\xe8\xaf\x08\x00\x00\x48\x8d\x4d\xf0\xff\x15\x25\xdd\x00\x00\x48\x8b\x9d\xe8\x00\x00\x00\x48\x8d\x95\xd8\x04\x00\x00\x48\x8b\xcb\x45\x33\xc0\xff\x15\x13\xdd\x00\x00\x48\x85\xc0\x74\x3c\x48\x83\x64\x24\x38\x00\x48\x8d\x8d\xe0\x04\x00\x00\x48\x8b\x95\xd8\x04\x00\x00\x4c\x8b\xc8\x48\x89\x4c\x24\x30\x4c\x8b\xc3\x48\x8d\x8d\xe8\x04\x00\x00\x48\x89\x4c\x24\x28\x48\x8d\x4d\xf0\x48\x89\x4c\x24\x20\x33\xc9\xff\x15\xda\xdc\x00\x00\x48\x8b\x85\xc8\x04\x00\x00\x48\x8d\x4c\x24\x50\x48\x89\x85\xe8\x00\x00\x00\x33\xd2\x48\x8d\x85\xc8\x04\x00\x00\x41\xb8\x98\x00\x00\x00\x48\x83\xc0\x08\x48\x89\x85\x88\x00\x00\x00\xe8\x18\x08\x00\x00\x48\x8b\x85\xc8\x04\x00\x00\x48\x89\x44\x24\x60\xc7\x44\x24\x50\x15\x00\x00\x40\xc7\x44\x24\x54\x01\x00\x00\x00\xff\x15\xde\xdc\x00\x00\x83\xf8\x01\x48\x8d\x44\x24\x50\x48\x89\x44\x24\x40\x48\x8d\x45\xf0\x0f\x94\xc3\x48\x89\x44\x24\x48\x33\xc9\xff\x15\x75\xdc\x00\x00\x48\x8d\x4c\x24\x40\xff\x15\x62\xdc\x00\x00\x85\xc0\x75\x0a\xf6\xdb\x1b\xc0\x21\x05\x14\x8b\x01\x00\x48\x8b\x9c\x24\xd0\x05\x00\x00\x48\x81\xc4\xc0\x05\x00\x00\x5d\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8d\x1d\xba\x5e\x01\x00\x48\x8d\x35\xb3\x5e\x01\x00\xeb\x16\x48\x8b\x3b\x48\x85\xff\x74\x0a\x48\x8b\xcf\xe8\x69\x00\x00\x00\xff\xd7\x48\x83\xc3\x08\x48\x3b\xde\x72\xe5\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8d\x1d\x7e\x5e\x01\x00\x48\x8d\x35\x77\x5e\x01\x00\xeb\x16\x48\x8b\x3b\x48\x85\xff\x74\x0a\x48\x8b\xcf\xe8\x1d\x00\x00\x00\xff\xd7\x48\x83\xc3\x08\x48\x3b\xde\x72\xe5\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x48\xff\x25\xc1\xdd\x00\x00\xcc\x48\x89\x5c\x24\x10\x55\x48\x8b\xec\x48\x83\xec\x20\x83\x65\xe8\x00\x33\xc9\x33\xc0\xc7\x05\xe5\x7a\x01\x00\x02\x00\x00\x00\x0f\xa2\x44\x8b\xc1\xc7\x05\xd2\x7a\x01\x00\x01\x00\x00\x00\x41\x81\xf0\x6e\x74\x65\x6c\x44\x8b\xca\x41\x81\xf1\x69\x6e\x65\x49\x44\x8b\xd2\x45\x0b\xc8\x8b\xd3\x81\xf2\x47\x65\x6e\x75\x44\x8b\xd8\x44\x0b\xca\xb8\x01\x00\x00\x00\x41\x0f\x94\xc0\x81\xf1\x63\x41\x4d\x44\x81\xf3\x41\x75\x74\x68\x41\x81\xf2\x65\x6e\x74\x69\x41\x0b\xda\x0b\xd9\x41\x0f\x94\xc2\x33\xc9\x0f\xa2\x44\x8b\xc9\x89\x45\xf0\x45\x84\xc0\x44\x89\x4d\xf8\x44\x8b\x05\xd4\x89\x01\x00\x8b\xc8\x89\x5d\xf4\x89\x55\xfc\x74\x52\x48\x83\x0d\x66\x7a\x01\x00\xff\x41\x83\xc8\x04\x25\xf0\x3f\xff\x0f\x44\x89\x05\xb2\x89\x01\x00\x3d\xc0\x06\x01\x00\x74\x28\x3d\x60\x06\x02\x00\x74\x21\x3d\x70\x06\x02\x00\x74\x1a\x05\xb0\xf9\xfc\xff\x83\xf8\x20\x77\x1b\x48\xbb\x01\x00\x01\x00\x01\x00\x00\x00\x48\x0f\xa3\xc3\x73\x0b\x41\x83\xc8\x01\x44\x89\x05\x78\x89\x01\x00\x45\x84\xd2\x74\x19\x81\xe1\x00\x0f\xf0\x0f\x81\xf9\x00\x0f\x60\x00\x7c\x0b\x41\x83\xc8\x04\x44\x89\x05\x5a\x89\x01\x00\xb8\x07\x00\x00\x00\x89\x55\xe0\x44\x89\x4d\xe4\x44\x3b\xd8\x7c\x24\x33\xc9\x0f\xa2\x89\x45\xf0\x89\x5d\xf4\x89\x4d\xf8\x89\x55\xfc\x89\x5d\xe8\x0f\xba\xe3\x09\x73\x0b\x41\x83\xc8\x02\x44\x89\x05\x25\x89\x01\x00\x41\x0f\xba\xe1\x14\x73\x6e\xc7\x05\xb0\x79\x01\x00\x02\x00\x00\x00\xc7\x05\xaa\x79\x01\x00\x06\x00\x00\x00\x41\x0f\xba\xe1\x1b\x73\x53\x41\x0f\xba\xe1\x1c\x73\x4c\x33\xc9\x0f\x01\xd0\x48\xc1\xe2\x20\x48\x0b\xd0\x48\x89\x55\x10\x48\x8b\x45\x10\x24\x06\x3c\x06\x75\x32\x8b\x05\x7c\x79\x01\x00\x83\xc8\x08\xc7\x05\x6b\x79\x01\x00\x03\x00\x00\x00\xf6\x45\xe8\x20\x89\x05\x65\x79\x01\x00\x74\x13\x83\xc8\x20\xc7\x05\x52\x79\x01\x00\x05\x00\x00\x00\x89\x05\x50\x79\x01\x00\x33\xc0\x48\x8b\x5c\x24\x38\x48\x83\xc4\x20\x5d\xc3\xcc\xcc\xcc\x33\xc0\x39\x05\x2c\x97\x01\x00\x0f\x95\xc0\xc3\xc2\x00\x00\xcc\xcc\xcc\xcc\xcc\x66\x90\xc3\xcc\x48\x89\x5c\x24\x10\x55\x48\x8d\xac\x24\x70\xfe\xff\xff\x48\x81\xec\x90\x02\x00\x00\x48\x8b\x05\xf0\x78\x01\x00\x48\x33\xc4\x48\x89\x85\x80\x01\x00\x00\x41\xb8\x04\x01\x00\x00\x48\x8d\x54\x24\x70\xff\x15\xed\xd9\x00\x00\x33\xdb\x85\xc0\x75\x05\x66\x89\x5c\x24\x70\x3d\x04\x01\x00\x00\x75\x11\xff\x15\xc5\xda\x00\x00\x85\xc0\x75\x07\x66\x89\x9d\x76\x01\x00\x00\x83\x3d\xdb\x78\x01\x00\x05\x0f\x86\x91\x00\x00\x00\x48\xba\x00\x00\x00\x00\x00\x20\x00\x00\x48\x85\x15\xd4\x78\x01\x00\x74\x7e\x48\x8b\x05\xd3\x78\x01\x00\x48\x23\xc2\x48\x3b\x05\xc9\x78\x01\x00\x75\x6b\x48\x8d\x05\x00\xdc\x00\x00\x48\xc7\x44\x24\x58\x0e\x00\x00\x00\x48\x89\x44\x24\x50\x48\x8d\x4c\x24\x70\x48\x83\xc8\xff\x48\xff\xc0\x66\x39\x1c\x41\x75\xf7\x48\x8d\x4c\x24\x70\x89\x5c\x24\x6c\x8d\x04\x45\x02\x00\x00\x00\x48\x89\x4c\x24\x60\x89\x44\x24\x68\x48\x8d\x44\x24\x30\x45\x33\xc9\x48\x89\x44\x24\x28\x48\x8d\x15\x34\x57\x01\x00\x45\x33\xc0\xc7\x44\x24\x20\x04\x00\x00\x00\x48\x8d\x0d\x49\x78\x01\x00\xe8\x54\xe9\xff\xff\x48\x8b\x8d\x80\x01\x00\x00\x48\x33\xcc\xe8\x35\xf1\xff\xff\x48\x8b\x9c\x24\xa8\x02\x00\x00\x48\x81\xc4\x90\x02\x00\x00\x5d\xc3\x48\x89\x5c\x24\x10\x55\x48\x8d\xac\x24\x70\xfe\xff\xff\x48\x81\xec\x90\x02\x00\x00\x48\x8b\x05\xd8\x77\x01\x00\x48\x33\xc4\x48\x89\x85\x80\x01\x00\x00\x41\xb8\x04\x01\x00\x00\x48\x8d\x54\x24\x70\xff\x15\xd5\xd8\x00\x00\x33\xdb\x85\xc0\x75\x05\x66\x89\x5c\x24\x70\x3d\x04\x01\x00\x00\x75\x11\xff\x15\xad\xd9\x00\x00\x85\xc0\x75\x07\x66\x89\x9d\x76\x01\x00\x00\x83\x3d\xc3\x77\x01\x00\x05\x0f\x86\x91\x00\x00\x00\x48\xba\x00\x00\x00\x00\x00\x20\x00\x00\x48\x85\x15\xbc\x77\x01\x00\x74\x7e\x48\x8b\x05\xbb\x77\x01\x00\x48\x23\xc2\x48\x3b\x05\xb1\x77\x01\x00\x75\x6b\x48\x8d\x05\xf8\xda\x00\x00\x48\xc7\x44\x24\x58\x0f\x00\x00\x00\x48\x89\x44\x24\x50\x48\x8d\x4c\x24\x70\x48\x83\xc8\xff\x48\xff\xc0\x66\x39\x1c\x41\x75\xf7\x48\x8d\x4c\x24\x70\x89\x5c\x24\x6c\x8d\x04\x45\x02\x00\x00\x00\x48\x89\x4c\x24\x60\x89\x44\x24\x68\x48\x8d\x44\x24\x30\x45\x33\xc9\x48\x89\x44\x24\x28\x48\x8d\x15\x58\x56\x01\x00\x45\x33\xc0\xc7\x44\x24\x20\x04\x00\x00\x00\x48\x8d\x0d\x31\x77\x01\x00\xe8\x3c\xe8\xff\xff\x48\x8b\x8d\x80\x01\x00\x00\x48\x33\xcc\xe8\x1d\xf0\xff\xff\x48\x8b\x9c\x24\xa8\x02\x00\x00\x48\x81\xc4\x90\x02\x00\x00\x5d\xc3\x45\x33\xc9\x48\x8d\x0d\x02\x77\x01\x00\x45\x33\xc0\x33\xd2\xe9\xc8\xe6\xff\xff\x48\x83\xec\x28\x48\x8b\x0d\x0d\x77\x01\x00\xe8\x48\x07\x00\x00\x48\x83\x25\x00\x77\x01\x00\x00\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x40\x4d\x8b\x61\x08\x48\x8b\xe9\x4d\x8b\x39\x49\x8b\xc8\x49\x8b\x59\x38\x4d\x2b\xfc\x4d\x8b\xf1\x49\x8b\xf8\x4c\x8b\xea\xe8\x52\xfd\xff\xff\xf6\x45\x04\x66\x0f\x85\xe0\x00\x00\x00\x41\x8b\x76\x48\x48\x89\x6c\x24\x30\x48\x89\x7c\x24\x38\x3b\x33\x0f\x83\x6d\x01\x00\x00\x8b\xfe\x48\x03\xff\x8b\x44\xfb\x04\x4c\x3b\xf8\x0f\x82\xaa\x00\x00\x00\x8b\x44\xfb\x08\x4c\x3b\xf8\x0f\x83\x9d\x00\x00\x00\x83\x7c\xfb\x10\x00\x0f\x84\x92\x00\x00\x00\x83\x7c\xfb\x0c\x01\x74\x17\x8b\x44\xfb\x0c\x48\x8d\x4c\x24\x30\x49\x03\xc4\x49\x8b\xd5\xff\xd0\x85\xc0\x78\x7d\x7e\x74\x81\x7d\x00\x63\x73\x6d\xe0\x75\x28\x48\x83\x3d\x11\x94\x01\x00\x00\x74\x1e\x48\x8d\x0d\x08\x94\x01\x00\xe8\x93\xc7\x00\x00\x85\xc0\x74\x0e\xba\x01\x00\x00\x00\x48\x8b\xcd\xff\x15\xf1\x93\x01\x00\x8b\x4c\xfb\x10\x41\xb8\x01\x00\x00\x00\x49\x03\xcc\x49\x8b\xd5\xe8\xcc\x09\x00\x00\x49\x8b\x46\x40\x4c\x8b\xc5\x8b\x54\xfb\x10\x49\x8b\xcd\x44\x8b\x4d\x00\x49\x03\xd4\x48\x89\x44\x24\x28\x49\x8b\x46\x28\x48\x89\x44\x24\x20\xff\x15\xb3\xd6\x00\x00\xe8\xce\x09\x00\x00\xff\xc6\xe9\x35\xff\xff\xff\x33\xc0\xe9\xa8\x00\x00\x00\x49\x8b\x76\x20\x41\x8b\x7e\x48\x49\x2b\xf4\xe9\x89\x00\x00\x00\x8b\xcf\x48\x03\xc9\x8b\x44\xcb\x04\x4c\x3b\xf8\x72\x79\x8b\x44\xcb\x08\x4c\x3b\xf8\x73\x70\xf6\x45\x04\x20\x74\x44\x45\x33\xc9\x85\xd2\x74\x38\x45\x8b\xc1\x4d\x03\xc0\x42\x8b\x44\xc3\x04\x48\x3b\xf0\x72\x20\x42\x8b\x44\xc3\x08\x48\x3b\xf0\x73\x16\x8b\x44\xcb\x10\x42\x39\x44\xc3\x10\x75\x0b\x8b\x44\xcb\x0c\x42\x39\x44\xc3\x0c\x74\x08\x41\xff\xc1\x44\x3b\xca\x72\xc8\x44\x3b\xca\x75\x32\x8b\x44\xcb\x10\x85\xc0\x74\x07\x48\x3b\xf0\x74\x25\xeb\x17\x8d\x47\x01\x49\x8b\xd5\x41\x89\x46\x48\x44\x8b\x44\xcb\x0c\xb1\x01\x4d\x03\xc4\x41\xff\xd0\xff\xc7\x8b\x13\x3b\xfa\x0f\x82\x6d\xff\xff\xff\xb8\x01\x00\x00\x00\x4c\x8d\x5c\x24\x40\x49\x8b\x5b\x30\x49\x8b\x6b\x38\x49\x8b\x73\x40\x49\x8b\xe3\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\xc3\xcc\xcc\x48\x83\xec\x28\xe8\xef\x0a\x00\x00\xe8\x02\x08\x00\x00\xe8\x65\x0a\x00\x00\x84\xc0\x75\x04\x32\xc0\xeb\x17\xe8\xf4\x09\x00\x00\x84\xc0\x75\x07\xe8\x97\x0a\x00\x00\xeb\xec\xe8\xac\xfd\xff\xff\xb0\x01\x48\x83\xc4\x28\xc3\xcc\x48\x83\xec\x28\xe8\x2b\x09\x00\x00\x48\x85\xc0\x0f\x95\xc0\x48\x83\xc4\x28\xc3\x48\x83\xec\x28\x33\xc9\xe8\xc5\x08\x00\x00\xb0\x01\x48\x83\xc4\x28\xc3\xcc\xcc\x40\x53\x48\x83\xec\x20\x8a\xd9\xe8\x83\xfd\xff\xff\x84\xdb\x75\x11\xe8\xde\x09\x00\x00\xe8\x45\x0a\x00\x00\x33\xc9\xe8\xc6\x07\x00\x00\xb0\x01\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\x48\x83\xec\x28\xe8\xbf\x09\x00\x00\xb0\x01\x48\x83\xc4\x28\xc3\x40\x53\x48\x83\xec\x20\xff\x15\x38\xd5\x00\x00\x48\x85\xc0\x74\x13\x48\x8b\x18\x48\x8b\xc8\xe8\x38\x30\x00\x00\x48\x8b\xc3\x48\x85\xdb\x75\xed\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x4c\x8b\xd9\x0f\xb6\xd2\x49\xb9\x01\x01\x01\x01\x01\x01\x01\x01\x4c\x0f\xaf\xca\x49\x83\xf8\x10\x0f\x86\x02\x01\x00\x00\x66\x49\x0f\x6e\xc1\x66\x0f\x60\xc0\x49\x81\xf8\x80\x00\x00\x00\x0f\x86\x7c\x00\x00\x00\x0f\xba\x25\x20\x83\x01\x00\x01\x73\x22\x8b\xc2\x48\x8b\xd7\x48\x8b\xf9\x49\x8b\xc8\xf3\xaa\x48\x8b\xfa\x49\x8b\xc3\xc3\x66\x66\x66\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x11\x01\x4c\x03\xc1\x48\x83\xc1\x10\x48\x83\xe1\xf0\x4c\x2b\xc1\x4d\x8b\xc8\x49\xc1\xe9\x07\x74\x36\x66\x0f\x1f\x44\x00\x00\x0f\x29\x01\x0f\x29\x41\x10\x48\x81\xc1\x80\x00\x00\x00\x0f\x29\x41\xa0\x0f\x29\x41\xb0\x49\xff\xc9\x0f\x29\x41\xc0\x0f\x29\x41\xd0\x0f\x29\x41\xe0\x66\x0f\x29\x41\xf0\x75\xd4\x49\x83\xe0\x7f\x4d\x8b\xc8\x49\xc1\xe9\x04\x74\x13\x0f\x1f\x80\x00\x00\x00\x00\x0f\x11\x01\x48\x83\xc1\x10\x49\xff\xc9\x75\xf4\x49\x83\xe0\x0f\x74\x06\x41\x0f\x11\x44\x08\xf0\x49\x8b\xc3\xc3\x6e\x2d\x00\x00\x6b\x2d\x00\x00\x97\x2d\x00\x00\x67\x2d\x00\x00\x74\x2d\x00\x00\x84\x2d\x00\x00\x94\x2d\x00\x00\x64\x2d\x00\x00\x9c\x2d\x00\x00\x78\x2d\x00\x00\xb0\x2d\x00\x00\xa0\x2d\x00\x00\x70\x2d\x00\x00\x80\x2d\x00\x00\x90\x2d\x00\x00\x60\x2d\x00\x00\xb8\x2d\x00\x00\x49\x8b\xd1\x4c\x8d\x0d\xb6\xd2\xff\xff\x43\x8b\x84\x81\xfc\x2c\x00\x00\x4c\x03\xc8\x49\x03\xc8\x49\x8b\xc3\x41\xff\xe1\x66\x90\x48\x89\x51\xf1\x89\x51\xf9\x66\x89\x51\xfd\x88\x51\xff\xc3\x90\x48\x89\x51\xf4\x89\x51\xfc\xc3\x48\x89\x51\xf7\x88\x51\xff\xc3\x48\x89\x51\xf3\x89\x51\xfb\x88\x51\xff\xc3\x0f\x1f\x44\x00\x00\x48\x89\x51\xf2\x89\x51\xfa\x66\x89\x51\xfe\xc3\x48\x89\x10\xc3\x48\x89\x10\x66\x89\x50\x08\x88\x50\x0a\xc3\x0f\x1f\x44\x00\x00\x48\x89\x10\x66\x89\x50\x08\xc3\x48\x89\x10\x48\x89\x50\x08\xc3\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x20\x45\x33\xff\x44\x8b\xf1\x4d\x8b\xe1\x33\xc0\x49\x8b\xe8\x4c\x8d\x0d\x0f\xd2\xff\xff\x4c\x8b\xea\xf0\x4f\x0f\xb1\xbc\xf1\xa0\xaf\x01\x00\x4c\x8b\x05\xfb\x71\x01\x00\x48\x83\xcf\xff\x41\x8b\xc8\x49\x8b\xd0\x83\xe1\x3f\x48\x33\xd0\x48\xd3\xca\x48\x3b\xd7\x0f\x84\x48\x01\x00\x00\x48\x85\xd2\x74\x08\x48\x8b\xc2\xe9\x3d\x01\x00\x00\x49\x3b\xec\x0f\x84\xbe\x00\x00\x00\x8b\x75\x00\x33\xc0\xf0\x4d\x0f\xb1\xbc\xf1\x80\xaf\x01\x00\x48\x8b\xd8\x74\x0e\x48\x3b\xc7\x0f\x84\x8d\x00\x00\x00\xe9\x83\x00\x00\x00\x4d\x8b\xbc\xf1\xa8\x03\x01\x00\x33\xd2\x49\x8b\xcf\x41\xb8\x00\x08\x00\x00\xff\x15\xf6\xd2\x00\x00\x48\x8b\xd8\x48\x85\xc0\x74\x05\x45\x33\xff\xeb\x24\xff\x15\x83\xd3\x00\x00\x83\xf8\x57\x75\x13\x45\x33\xc0\x33\xd2\x49\x8b\xcf\xff\x15\xd0\xd2\x00\x00\x48\x8b\xd8\xeb\xdd\x45\x33\xff\x41\x8b\xdf\x4c\x8d\x0d\x56\xd1\xff\xff\x48\x85\xdb\x75\x0d\x48\x8b\xc7\x49\x87\x84\xf1\x80\xaf\x01\x00\xeb\x25\x48\x8b\xc3\x49\x87\x84\xf1\x80\xaf\x01\x00\x48\x85\xc0\x74\x10\x48\x8b\xcb\xff\x15\x83\xd2\x00\x00\x4c\x8d\x0d\x24\xd1\xff\xff\x48\x85\xdb\x75\x5d\x48\x83\xc5\x04\x49\x3b\xec\x0f\x85\x49\xff\xff\xff\x4c\x8b\x05\x0b\x71\x01\x00\x49\x8b\xdf\x48\x85\xdb\x74\x4a\x49\x8b\xd5\x48\x8b\xcb\xff\x15\x57\xd2\x00\x00\x4c\x8b\x05\xf0\x70\x01\x00\x48\x85\xc0\x74\x32\x41\x8b\xc8\xba\x40\x00\x00\x00\x83\xe1\x3f\x2b\xd1\x8a\xca\x48\x8b\xd0\x48\xd3\xca\x48\x8d\x0d\xcf\xd0\xff\xff\x49\x33\xd0\x4a\x87\x94\xf1\xa0\xaf\x01\x00\xeb\x2d\x4c\x8b\x05\xbb\x70\x01\x00\xeb\xb1\xb9\x40\x00\x00\x00\x41\x8b\xc0\x83\xe0\x3f\x2b\xc8\x48\xd3\xcf\x48\x8d\x0d\xa2\xd0\xff\xff\x49\x33\xf8\x4a\x87\xbc\xf1\xa0\xaf\x01\x00\x33\xc0\x48\x8b\x5c\x24\x50\x48\x8b\x6c\x24\x58\x48\x8b\x74\x24\x60\x48\x83\xc4\x20\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\xc3\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x20\x49\x8b\xf9\x49\x8b\xf0\x48\x8b\xea\x4c\x8d\x0d\xc7\xd4\x00\x00\x4c\x8b\xf1\x4c\x8d\x05\xb9\xd4\x00\x00\x48\x8d\x15\xb6\xd4\x00\x00\x33\xc9\xe8\xf7\xfd\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x18\x48\x8b\xc8\xe8\x37\xf5\xff\xff\x4c\x8b\xcf\x4c\x8b\xc6\x48\x8b\xd5\x49\x8b\xce\xff\xd3\xeb\x05\xb8\x32\x00\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x8b\x7c\x24\x48\x48\x83\xc4\x20\x41\x5e\xc3\xcc\xcc\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x20\x41\x8b\xf9\x49\x8b\xf0\x8b\xea\x4c\x8d\x0d\x58\xd4\x00\x00\x4c\x8b\xf1\x4c\x8d\x05\x4a\xd4\x00\x00\x48\x8d\x15\x4b\xd4\x00\x00\xb9\x01\x00\x00\x00\xe8\x71\xfd\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x17\x48\x8b\xc8\xe8\xb1\xf4\xff\xff\x44\x8b\xcf\x4c\x8b\xc6\x8b\xd5\x49\x8b\xce\xff\xd3\xeb\x05\xb8\x32\x00\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x8b\x7c\x24\x48\x48\x83\xc4\x20\x41\x5e\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xf9\x4c\x8d\x0d\x04\xd4\x00\x00\xb9\x02\x00\x00\x00\x4c\x8d\x05\xf4\xd3\x00\x00\x48\x8d\x15\xf1\xd3\x00\x00\xe8\x04\xfd\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x0f\x48\x8b\xc8\xe8\x44\xf4\xff\xff\x48\x8b\xcf\xff\xd3\xeb\x05\xb8\x32\x00\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x30\x49\x8b\xf9\x49\x8b\xf0\x48\x8b\xea\x4c\x8d\x0d\xaf\xd3\x00\x00\x4c\x8b\xf1\x4c\x8d\x05\xa1\xd3\x00\x00\x48\x8d\x15\xa2\xd3\x00\x00\xb9\x03\x00\x00\x00\xe8\x98\xfc\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x2a\x48\x8b\xc8\xe8\xd8\xf3\xff\xff\x48\x8b\x4c\x24\x68\x4c\x8b\xcf\x48\x89\x4c\x24\x28\x4c\x8b\xc6\x8b\x4c\x24\x60\x48\x8b\xd5\x89\x4c\x24\x20\x49\x8b\xce\xff\xd3\xeb\x05\xb8\x32\x00\x00\x00\x48\x8b\x5c\x24\x40\x48\x8b\x6c\x24\x48\x48\x8b\x74\x24\x50\x48\x8b\x7c\x24\x58\x48\x83\xc4\x30\x41\x5e\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xf9\x4c\x8d\x0d\x50\xd3\x00\x00\xb9\x04\x00\x00\x00\x4c\x8d\x05\x3c\xd3\x00\x00\x48\x8d\x15\x3d\xd3\x00\x00\xe8\x18\xfc\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x0f\x48\x8b\xc8\xe8\x58\xf3\xff\xff\x48\x8b\xcf\xff\xd3\xeb\x06\xff\x15\x73\xcf\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x8b\xd9\x4c\x8d\x0d\x15\xd3\x00\x00\xb9\x05\x00\x00\x00\x4c\x8d\x05\x01\xd3\x00\x00\x48\x8d\x15\x02\xd3\x00\x00\xe8\xc5\xfb\xff\xff\x48\x8b\xf8\x48\x85\xc0\x74\x0e\x48\x8b\xc8\xe8\x05\xf3\xff\xff\x8b\xcb\xff\xd7\xeb\x08\x8b\xcb\xff\x15\x37\xcf\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x8b\xd9\x4c\x8d\x0d\xd1\xd2\x00\x00\xb9\x06\x00\x00\x00\x4c\x8d\x05\xbd\xd2\x00\x00\x48\x8d\x15\xbe\xd2\x00\x00\xe8\x71\xfb\xff\xff\x48\x8b\xf8\x48\x85\xc0\x74\x0e\x48\x8b\xc8\xe8\xb1\xf2\xff\xff\x8b\xcb\xff\xd7\xeb\x08\x8b\xcb\xff\x15\xd3\xce\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8b\xda\x4c\x8d\x0d\x8f\xd2\x00\x00\x8b\xf9\x48\x8d\x15\x86\xd2\x00\x00\xb9\x07\x00\x00\x00\x4c\x8d\x05\x72\xd2\x00\x00\xe8\x15\xfb\xff\xff\x48\x8b\xf0\x48\x85\xc0\x74\x11\x48\x8b\xc8\xe8\x55\xf2\xff\xff\x48\x8b\xd3\x8b\xcf\xff\xd6\xeb\x0b\x48\x8b\xd3\x8b\xcf\xff\x15\x79\xce\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x41\x8b\xe8\x4c\x8d\x0d\x3a\xd2\x00\x00\x8b\xda\x4c\x8d\x05\x29\xd2\x00\x00\x48\x8b\xf9\x48\x8d\x15\x27\xd2\x00\x00\xb9\x08\x00\x00\x00\xe8\xa5\xfa\xff\xff\x48\x8b\xf0\x48\x85\xc0\x74\x14\x48\x8b\xc8\xe8\xe5\xf1\xff\xff\x44\x8b\xc5\x8b\xd3\x48\x8b\xcf\xff\xd6\xeb\x0b\x8b\xd3\x48\x8b\xcf\xff\x15\xee\xcd\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x7c\x24\x08\x48\x8b\x15\x9c\x6c\x01\x00\x48\x8d\x3d\x35\x7c\x01\x00\x8b\xc2\xb9\x40\x00\x00\x00\x83\xe0\x3f\x2b\xc8\x33\xc0\x48\xd3\xc8\xb9\x09\x00\x00\x00\x48\x33\xc2\xf3\x48\xab\x48\x8b\x7c\x24\x08\xc3\xcc\xcc\xcc\x84\xc9\x75\x39\x53\x48\x83\xec\x20\x48\x8d\x1d\xe0\x7b\x01\x00\x48\x8b\x0b\x48\x85\xc9\x74\x10\x48\x83\xf9\xff\x74\x06\xff\x15\xa4\xcd\x00\x00\x48\x83\x23\x00\x48\x83\xc3\x08\x48\x8d\x05\xdd\x7b\x01\x00\x48\x3b\xd8\x75\xd8\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x81\xec\xd8\x04\x00\x00\x4d\x33\xc0\x4d\x33\xc9\x48\x89\x64\x24\x20\x4c\x89\x44\x24\x28\xe8\xd8\xbc\x00\x00\x48\x81\xc4\xd8\x04\x00\x00\xc3\xcc\xcc\xcc\xcc\xcc\xcc\x66\x0f\x1f\x44\x00\x00\x48\x89\x4c\x24\x08\x48\x89\x54\x24\x18\x44\x89\x44\x24\x10\x49\xc7\xc1\x20\x05\x93\x19\xeb\x08\xcc\xcc\xcc\xcc\xcc\xcc\x66\x90\xc3\xcc\xcc\xcc\xcc\xcc\xcc\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\xc3\xcc\xcc\xcc\x48\x83\xec\x28\x48\x85\xc9\x74\x11\x48\x8d\x05\x9c\x7b\x01\x00\x48\x3b\xc8\x74\x05\xe8\xda\x27\x00\x00\x48\x83\xc4\x28\xc3\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\xd9\x8b\x0d\x0d\x6c\x01\x00\x83\xf9\xff\x74\x33\x48\x85\xdb\x75\x0e\xe8\xa2\xfd\xff\xff\x8b\x0d\xf8\x6b\x01\x00\x48\x8b\xd8\x33\xd2\xe8\xe6\xfd\xff\xff\x48\x85\xdb\x74\x14\x48\x8d\x05\x52\x7b\x01\x00\x48\x3b\xd8\x74\x08\x48\x8b\xcb\xe8\x8d\x27\x00\x00\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x83\x3d\xb6\x6b\x01\x00\xff\x75\x04\x33\xc0\xeb\x79\xff\x15\x32\xcd\x00\x00\x8b\x0d\xa4\x6b\x01\x00\x8b\xf0\xe8\x41\xfd\xff\xff\x33\xff\x48\x8b\xd8\x48\x85\xc0\x74\x0d\x8b\xce\xff\x15\x7b\xcc\x00\x00\x48\x8b\xc3\xeb\x4f\xba\x78\x00\x00\x00\x8d\x4a\x89\xe8\x89\x28\x00\x00\x48\x8b\xd8\x48\x85\xc0\x75\x04\x8b\xce\xeb\x14\x8b\x0d\x67\x6b\x01\x00\x48\x8b\xd0\xe8\x57\xfd\xff\xff\x8b\xce\x85\xc0\x75\x08\xff\x15\x43\xcc\x00\x00\xeb\x0f\xff\x15\x3b\xcc\x00\x00\x48\x8b\xcb\x48\x8b\xdf\x48\x8b\xf9\x48\x8b\xcb\xe8\xf2\x26\x00\x00\x48\x8b\xc7\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x83\xec\x28\x48\x8d\x0d\xdd\xfe\xff\xff\xe8\x10\xfc\xff\xff\x89\x05\x0e\x6b\x01\x00\x83\xf8\xff\x75\x04\x32\xc0\xeb\x1b\x48\x8d\x15\x6e\x7a\x01\x00\x8b\xc8\xe8\xef\xfc\xff\xff\x85\xc0\x75\x07\xe8\x0a\x00\x00\x00\xeb\xe3\xb0\x01\x48\x83\xc4\x28\xc3\xcc\x48\x83\xec\x28\x8b\x0d\xda\x6a\x01\x00\x83\xf9\xff\x74\x0c\xe8\x20\xfc\xff\xff\x83\x0d\xc9\x6a\x01\x00\xff\xb0\x01\x48\x83\xc4\x28\xc3\xcc\xcc\x40\x53\x48\x83\xec\x20\x33\xdb\x48\x8d\x15\x99\x7a\x01\x00\x45\x33\xc0\x48\x8d\x0c\x9b\x48\x8d\x0c\xca\xba\xa0\x0f\x00\x00\xe8\xfc\xfc\xff\xff\x85\xc0\x74\x11\xff\x05\xa2\x7a\x01\x00\xff\xc3\x83\xfb\x01\x72\xd3\xb0\x01\xeb\x07\xe8\x0a\x00\x00\x00\x32\xc0\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\x40\x53\x48\x83\xec\x20\x8b\x1d\x7c\x7a\x01\x00\xeb\x1d\x48\x8d\x05\x4b\x7a\x01\x00\xff\xcb\x48\x8d\x0c\x9b\x48\x8d\x0c\xc8\xff\x15\x5b\xcb\x00\x00\xff\x0d\x5d\x7a\x01\x00\x85\xdb\x75\xdf\xb0\x01\x48\x83\xc4\x20\x5b\xc3\xcc\x48\x8b\x15\xb9\x69\x01\x00\xb9\x40\x00\x00\x00\x8b\xc2\x83\xe0\x3f\x2b\xc8\x33\xc0\x48\xd3\xc8\x48\x33\xc2\x48\x89\x05\x36\x7a\x01\x00\xc3\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x20\x8b\x05\x8d\x7a\x01\x00\x33\xdb\xbf\x03\x00\x00\x00\x85\xc0\x75\x07\xb8\x00\x02\x00\x00\xeb\x05\x3b\xc7\x0f\x4c\xc7\x48\x63\xc8\xba\x08\x00\x00\x00\x89\x05\x68\x7a\x01\x00\xe8\xe3\x26\x00\x00\x33\xc9\x48\x89\x05\x62\x7a\x01\x00\xe8\x7d\x25\x00\x00\x48\x39\x1d\x56\x7a\x01\x00\x75\x2f\xba\x08\x00\x00\x00\x89\x3d\x41\x7a\x01\x00\x48\x8b\xcf\xe8\xb9\x26\x00\x00\x33\xc9\x48\x89\x05\x38\x7a\x01\x00\xe8\x53\x25\x00\x00\x48\x39\x1d\x2c\x7a\x01\x00\x75\x05\x83\xc8\xff\xeb\x75\x4c\x8b\xf3\x48\x8d\x35\xab\x69\x01\x00\x48\x8d\x2d\x8c\x69\x01\x00\x48\x8d\x4d\x30\x45\x33\xc0\xba\xa0\x0f\x00\x00\xe8\x8f\x30\x00\x00\x48\x8b\x05\xfc\x79\x01\x00\x48\x8d\x15\x1d\x7c\x01\x00\x48\x8b\xcb\x83\xe1\x3f\x48\xc1\xe1\x06\x49\x89\x2c\x06\x48\x8b\xc3\x48\xc1\xf8\x06\x48\x8b\x04\xc2\x48\x8b\x4c\x08\x28\x48\x83\xc1\x02\x48\x83\xf9\x02\x77\x06\xc7\x06\xfe\xff\xff\xff\x48\xff\xc3\x48\x83\xc5\x58\x49\x83\xc6\x08\x48\x83\xc6\x58\x48\x83\xef\x01\x75\x9e\x33\xc0\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x8b\x7c\x24\x48\x48\x83\xc4\x20\x41\x5e\xc3\xcc\x8b\xc1\x48\x8d\x0d\x03\x69\x01\x00\x48\x6b\xc0\x58\x48\x03\xc1\xc3\xcc\xcc\xcc\x40\x53\x48\x83\xec\x20\xe8\x4d\x34\x00\x00\xe8\xd0\x32\x00\x00\x33\xdb\x48\x8b\x0d\x67\x79\x01\x00\x48\x8b\x0c\x0b\xe8\x26\x35\x00\x00\x48\x8b\x05\x57\x79\x01\x00\x48\x8b\x0c\x03\x48\x83\xc1\x30\xff\x15\xb9\xc9\x00\x00\x48\x83\xc3\x08\x48\x83\xfb\x18\x75\xd1\x48\x8b\x0d\x38\x79\x01\x00\xe8\x53\x24\x00\x00\x48\x83\x25\x2b\x79\x01\x00\x00\x48\x83\xc4\x20\x5b\xc3\xcc\x48\x83\xc1\x30\x48\xff\x25\x79\xc9\x00\x00\xcc\x48\x83\xc1\x30\x48\xff\x25\x75\xc9\x00\x00\xcc\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xd9\x49\x8b\xf8\x48\x8b\x0a\xe8\xcb\xff\xff\xff\x90\x48\x8b\xcf\xe8\xbe\x03\x00\x00\x8b\xf8\x48\x8b\x0b\xe8\xc4\xff\xff\xff\x8b\xc7\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x48\x83\xc8\xff\x48\x8b\xf2\x33\xd2\x48\x8b\xe9\x48\xf7\xf6\x48\x83\xe0\xfe\x48\x83\xf8\x02\x73\x0f\xe8\xf6\x2b\x00\x00\xc7\x00\x0c\x00\x00\x00\x32\xc0\xeb\x5b\x48\x03\xf6\x33\xff\x48\x39\xb9\x08\x04\x00\x00\x75\x0d\x48\x81\xfe\x00\x04\x00\x00\x77\x04\xb0\x01\xeb\x40\x48\x3b\xb1\x00\x04\x00\x00\x76\xf3\x48\x8b\xce\xe8\xc4\x23\x00\x00\x48\x8b\xd8\x48\x85\xc0\x74\x1d\x48\x8b\x8d\x08\x04\x00\x00\xe8\x70\x23\x00\x00\x48\x89\x9d\x08\x04\x00\x00\x40\xb7\x01\x48\x89\xb5\x00\x04\x00\x00\x33\xc9\xe8\x58\x23\x00\x00\x40\x8a\xc7\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\x41\x8b\xc8\x83\xe9\x02\x74\x24\x83\xe9\x01\x74\x1c\x83\xf9\x09\x74\x17\x41\x83\xf8\x0d\x74\x14\x80\xea\x63\xf6\xc2\xef\x0f\x94\xc1\x33\xc0\x84\xc9\x0f\x94\xc0\xc3\xb0\x01\xc3\x32\xc0\xc3\xcc\x48\x89\x5c\x24\x08\x48\x8d\x41\x58\x4c\x8b\xd1\x48\x8b\x88\x08\x04\x00\x00\x41\x8b\xd8\x48\x85\xc9\x44\x8b\xda\x48\x0f\x44\xc8\x48\x83\xb8\x08\x04\x00\x00\x00\x75\x07\xb8\x00\x02\x00\x00\xeb\x0a\x48\x8b\x80\x00\x04\x00\x00\x48\xd1\xe8\x4c\x8d\x41\xff\x4c\x03\xc0\x4d\x89\x42\x48\x41\x8b\x42\x38\x85\xc0\x7f\x05\x45\x85\xdb\x74\x36\xff\xc8\x33\xd2\x41\x89\x42\x38\x41\x8b\xc3\xf7\xf3\x80\xc2\x30\x44\x8b\xd8\x80\xfa\x39\x7e\x12\x41\x8a\xc1\xf6\xd8\x1a\xc9\x80\xe1\xe0\x80\xc1\x61\x80\xe9\x3a\x02\xd1\x49\x8b\x42\x48\x88\x10\x49\xff\x4a\x48\xeb\xbd\x45\x2b\x42\x48\x49\xff\x42\x48\x48\x8b\x5c\x24\x08\x45\x89\x42\x50\xc3\xcc\x48\x89\x5c\x24\x08\x48\x8d\x41\x58\x41\x8b\xd8\x4c\x8b\xd1\x4c\x8b\xda\x48\x8b\x88\x08\x04\x00\x00\x48\x85\xc9\x48\x0f\x44\xc8\x48\x83\xb8\x08\x04\x00\x00\x00\x75\x07\xb8\x00\x02\x00\x00\xeb\x0a\x48\x8b\x80\x00\x04\x00\x00\x48\xd1\xe8\x4c\x8d\x41\xff\x4c\x03\xc0\x4d\x89\x42\x48\x41\x8b\x42\x38\x85\xc0\x7f\x05\x4d\x85\xdb\x74\x37\xff\xc8\x33\xd2\x41\x89\x42\x38\x49\x8b\xc3\x48\xf7\xf3\x80\xc2\x30\x4c\x8b\xd8\x80\xfa\x39\x7e\x12\x41\x8a\xc1\xf6\xd8\x1a\xc9\x80\xe1\xe0\x80\xc1\x61\x80\xe9\x3a\x02\xd1\x49\x8b\x42\x48\x88\x10\x49\xff\x4a\x48\xeb\xbc\x45\x2b\x42\x48\x49\xff\x42\x48\x48\x8b\x5c\x24\x08\x45\x89\x42\x50\xc3\x45\x85\xc0\x7e\x7e\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x20\x49\x8b\xd9\x41\x8b\xe8\x44\x8a\xf2\x48\x8b\xf1\x33\xff\x48\x8b\x06\x8b\x48\x14\xc1\xe9\x0c\xf6\xc1\x01\x74\x0a\x48\x8b\x06\x48\x83\x78\x08\x00\x74\x11\x48\x8b\x16\x41\x0f\xbe\xce\xe8\xd8\x4f\x00\x00\x83\xf8\xff\x74\x11\xff\x03\x8b\x03\x83\xf8\xff\x74\x0b\xff\xc7\x3b\xfd\x7d\x05\xeb\xc6\x83\x0b\xff\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x8b\x7c\x24\x48\x48\x83\xc4\x20\x41\x5e\xc3\x40\x53\x48\x83\xec\x20\x48\x8b\xd9\x33\xc9\x48\x89\x0b\x48\x89\x4b\x08\x48\x89\x4b\x18\x48\x89\x4b\x20\x48\x89\x4b\x10\x48\x89\x4b\x28\x48\x89\x4b\x30\x89\x4b\x38\x66\x89\x4b\x40\x89\x4b\x50\x88\x4b\x54\x48\x89\x8b\x58\x04\x00\x00\x48\x89\x8b\x60\x04\x00\x00\x48\x8b\x02\x48\x89\x83\x68\x04\x00\x00\x48\x8b\x44\x24\x50\x48\x89\x43\x08\x48\x8b\x44\x24\x58\x48\x89\x43\x20\x4c\x89\x03\x4c\x89\x4b\x18\x89\x8b\x70\x04\x00\x00\xe8\x21\x29\x00\x00\x48\x89\x43\x10\x48\x8b\xc3\x48\x83\xc4\x20\x5b\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\xc6\x41\x18\x00\x48\x8b\xf9\x48\x85\xd2\x74\x05\x0f\x10\x02\xeb\x11\x8b\x05\xdf\x7b\x01\x00\x85\xc0\x75\x0e\x0f\x10\x05\xcc\x67\x01\x00\xf3\x0f\x7f\x41\x08\xeb\x4f\xe8\x50\x40\x00\x00\x48\x89\x07\x48\x8d\x57\x08\x48\x8b\x88\x90\x00\x00\x00\x48\x89\x0a\x48\x8b\x88\x88\x00\x00\x00\x48\x89\x4f\x10\x48\x8b\xc8\xe8\xc0\x41\x00\x00\x48\x8b\x0f\x48\x8d\x57\x10\xe8\xe8\x41\x00\x00\x48\x8b\x0f\x8b\x81\xa8\x03\x00\x00\xa8\x02\x75\x0d\x83\xc8\x02\x89\x81\xa8\x03\x00\x00\xc6\x47\x18\x01\x48\x8b\xc7\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x81\xec\xf0\x04\x00\x00\x48\x8b\x05\xf7\x63\x01\x00\x48\x33\xc4\x48\x89\x84\x24\xe0\x04\x00\x00\x48\x8b\x01\x48\x8b\xd9\x48\x8b\x38\x48\x8b\xcf\xe8\x93\x4e\x00\x00\x48\x8b\x53\x08\x48\x8d\x4c\x24\x38\x40\x8a\xf0\x48\x8b\x12\xe8\x27\xff\xff\xff\x48\x8b\x13\x48\x8d\x44\x24\x40\x48\x8b\x4b\x20\x4c\x8b\x4b\x18\x4c\x8b\x02\x48\x8d\x54\x24\x30\x48\x8b\x09\x4d\x8b\x09\x4c\x89\x44\x24\x30\x4c\x8b\x43\x10\x48\x89\x4c\x24\x28\x48\x8d\x4c\x24\x60\x48\x89\x44\x24\x20\x4d\x8b\x00\xe8\x6d\xfe\xff\xff\x48\x8d\x4c\x24\x60\xe8\x53\x01\x00\x00\x48\x8b\x8c\x24\xc0\x04\x00\x00\x8b\xd8\xe8\xa8\x1f\x00\x00\x48\x83\xa4\x24\xc0\x04\x00\x00\x00\x80\x7c\x24\x50\x00\x74\x0c\x48\x8b\x4c\x24\x38\x83\xa1\xa8\x03\x00\x00\xfd\x48\x8b\xd7\x40\x8a\xce\xe8\xd1\x4e\x00\x00\x8b\xc3\x48\x8b\x8c\x24\xe0\x04\x00\x00\x48\x33\xcc\xe8\x67\xdc\xff\xff\x4c\x8d\x9c\x24\xf0\x04\x00\x00\x49\x8b\x5b\x18\x49\x8b\x73\x20\x49\x8b\xe3\x5f\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xd9\x48\x8b\xfa\x0f\xbe\x09\xe8\x90\x34\x00\x00\x83\xf8\x65\x74\x0f\x48\xff\xc3\x0f\xb6\x0b\xe8\x7c\x32\x00\x00\x85\xc0\x75\xf1\x0f\xbe\x0b\xe8\x74\x34\x00\x00\x83\xf8\x78\x75\x04\x48\x83\xc3\x02\x48\x8b\x07\x8a\x13\x48\x8b\x88\xf8\x00\x00\x00\x48\x8b\x01\x8a\x08\x88\x0b\x48\xff\xc3\x8a\x03\x88\x13\x8a\xd0\x8a\x03\x48\xff\xc3\x84\xc0\x75\xf1\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x8b\xc4\x48\x89\x58\x10\x48\x89\x68\x18\x56\x57\x41\x56\x48\x83\xec\x20\x48\x8b\x71\x10\x48\x8b\xf9\xbd\x01\x00\x00\x00\x48\x8b\xda\x48\x8d\x50\x08\x44\x8b\x36\x83\x26\x00\x44\x8d\x45\x09\x48\x8b\x49\x18\x48\x83\x60\x08\x00\x48\x2b\xcd\xe8\x37\x34\x00\x00\x89\x03\x48\x8b\x47\x10\x83\x38\x22\x74\x11\x48\x8b\x44\x24\x40\x48\x3b\x47\x18\x72\x06\x48\x89\x47\x18\xeb\x03\x40\x32\xed\x83\x3e\x00\x75\x08\x45\x85\xf6\x74\x03\x44\x89\x36\x48\x8b\x5c\x24\x48\x40\x8a\xc5\x48\x8b\x6c\x24\x50\x48\x83\xc4\x20\x41\x5e\x5f\x5e\xc3\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x57\x48\x83\xec\x20\x48\x8b\xd9\x48\x8b\x89\x68\x04\x00\x00\x48\x85\xc9\x75\x12\xe8\x7d\x26\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x52\x25\x00\x00\xeb\x09\xe8\x33\x0d\x00\x00\x84\xc0\x75\x08\x83\xc8\xff\xe9\xaa\x01\x00\x00\x48\x83\x7b\x18\x00\x74\xd6\xff\x83\x70\x04\x00\x00\x83\xbb\x70\x04\x00\x00\x02\x0f\x84\x8d\x01\x00\x00\x83\xcf\xff\x48\x8d\x2d\xa7\xd0\x00\x00\x83\x63\x50\x00\x83\x63\x2c\x00\xe9\x4e\x01\x00\x00\x48\xff\x43\x18\x83\x7b\x28\x00\x0f\x8c\x55\x01\x00\x00\x8a\x43\x41\x8b\x53\x2c\x2c\x20\x3c\x5a\x77\x0f\x48\x0f\xbe\x43\x41\x0f\xb6\x4c\x28\xe0\x83\xe1\x0f\xeb\x02\x33\xc9\x8d\x04\xca\x0f\xb6\x04\x28\xc1\xe8\x04\x89\x43\x2c\x83\xf8\x08\x0f\x84\x48\x01\x00\x00\x85\xc0\x0f\x84\xf9\x00\x00\x00\x83\xe8\x01\x0f\x84\xd7\x00\x00\x00\x83\xe8\x01\x0f\x84\x99\x00\x00\x00\x83\xe8\x01\x74\x68\x83\xe8\x01\x74\x5a\x83\xe8\x01\x74\x28\x83\xe8\x01\x74\x16\x83\xf8\x01\x0f\x85\x21\x01\x00\x00\x48\x8b\xcb\xe8\x9e\x03\x00\x00\xe9\xc5\x00\x00\x00\x48\x8b\xcb\xe8\x15\x02\x00\x00\xe9\xb8\x00\x00\x00\x80\x7b\x41\x2a\x74\x11\x48\x8d\x53\x38\x48\x8b\xcb\xe8\x66\xfe\xff\xff\xe9\xa1\x00\x00\x00\x48\x83\x43\x20\x08\x48\x8b\x43\x20\x8b\x48\xf8\x85\xc9\x0f\x48\xcf\x89\x4b\x38\xeb\x31\x83\x63\x38\x00\xe9\x86\x00\x00\x00\x80\x7b\x41\x2a\x74\x06\x48\x8d\x53\x34\xeb\xc8\x48\x83\x43\x20\x08\x48\x8b\x43\x20\x8b\x48\xf8\x89\x4b\x34\x85\xc9\x79\x09\x83\x4b\x30\x04\xf7\xd9\x89\x4b\x34\xb0\x01\xeb\x56\x8a\x43\x41\x3c\x20\x74\x28\x3c\x23\x74\x1e\x3c\x2b\x74\x14\x3c\x2d\x74\x0a\x3c\x30\x75\x43\x83\x4b\x30\x08\xeb\x3d\x83\x4b\x30\x04\xeb\x37\x83\x4b\x30\x01\xeb\x31\x83\x4b\x30\x20\xeb\x2b\x83\x4b\x30\x02\xeb\x25\x83\x63\x34\x00\x83\x63\x30\x00\x83\x63\x3c\x00\xc6\x43\x40\x00\x89\x7b\x38\xc6\x43\x54\x00\xeb\x0c\x48\x8b\xcb\xe8\x54\x00\x00\x00\x84\xc0\x74\x4b\x48\x8b\x43\x18\x8a\x08\x88\x4b\x41\x84\xc9\x0f\x85\xa1\xfe\xff\xff\x48\xff\x43\x18\xff\x83\x70\x04\x00\x00\x83\xbb\x70\x04\x00\x00\x02\x0f\x85\x7d\xfe\xff\xff\x8b\x43\x28\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x83\xc4\x20\x5f\xc3\xe8\xa0\x24\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x75\x23\x00\x00\x8b\xc7\xeb\xdc\xcc\x40\x53\x48\x83\xec\x20\x33\xd2\x48\x8b\xd9\xe8\x60\x00\x00\x00\x84\xc0\x74\x43\x48\x8b\x83\x68\x04\x00\x00\x8a\x53\x41\x8b\x48\x14\xc1\xe9\x0c\xf6\xc1\x01\x74\x0e\x48\x8b\x83\x68\x04\x00\x00\x48\x83\x78\x08\x00\x74\x19\x0f\xbe\xca\x48\x8b\x93\x68\x04\x00\x00\xe8\x5e\x4a\x00\x00\x83\xf8\xff\x75\x05\x09\x43\x28\xeb\x03\xff\x43\x28\xb0\x01\xeb\x12\xe8\x34\x24\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x09\x23\x00\x00\x32\xc0\x48\x83\xc4\x20\x5b\xc3\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\x41\x08\x48\x8b\xd9\x0f\xb6\x51\x41\xc6\x41\x54\x00\xb9\x00\x80\x00\x00\x48\x8b\x00\x48\x8b\x00\x66\x85\x0c\x50\x74\x64\x48\x8b\x83\x68\x04\x00\x00\x8b\x48\x14\xc1\xe9\x0c\xf6\xc1\x01\x74\x0e\x48\x8b\x83\x68\x04\x00\x00\x48\x83\x78\x08\x00\x74\x19\x0f\xbe\xca\x48\x8b\x93\x68\x04\x00\x00\xe8\xdf\x49\x00\x00\x83\xf8\xff\x75\x05\x09\x43\x28\xeb\x03\xff\x43\x28\x48\x8b\x43\x18\x8a\x08\x48\xff\xc0\x88\x4b\x41\x48\x89\x43\x18\x84\xc9\x75\x14\xe8\xa5\x23\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x7a\x22\x00\x00\x32\xc0\xeb\x02\xb0\x01\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\x48\x83\xec\x28\x8a\x41\x41\x3c\x46\x75\x19\xf6\x01\x08\x0f\x85\x60\x01\x00\x00\xc7\x41\x2c\x07\x00\x00\x00\x48\x83\xc4\x28\xe9\x58\x01\x00\x00\x3c\x4e\x75\x27\xf6\x01\x08\x0f\x85\x43\x01\x00\x00\xc7\x41\x2c\x08\x00\x00\x00\xe8\x4f\x23\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x24\x22\x00\x00\x32\xc0\xe9\x27\x01\x00\x00\x83\x79\x3c\x00\x75\xe3\x3c\x49\x0f\x84\xba\x00\x00\x00\x3c\x4c\x0f\x84\xa9\x00\x00\x00\x3c\x54\x0f\x84\x98\x00\x00\x00\x3c\x68\x74\x72\x3c\x6a\x74\x62\x3c\x6c\x74\x36\x3c\x74\x74\x26\x3c\x77\x74\x16\x3c\x7a\xb0\x01\x0f\x85\xeb\x00\x00\x00\xc7\x41\x3c\x06\x00\x00\x00\xe9\xdf\x00\x00\x00\xc7\x41\x3c\x0c\x00\x00\x00\xe9\xd1\x00\x00\x00\xc7\x41\x3c\x07\x00\x00\x00\xe9\xc5\x00\x00\x00\x48\x8b\x41\x18\x80\x38\x6c\x75\x13\x48\xff\xc0\xc7\x41\x3c\x04\x00\x00\x00\x48\x89\x41\x18\xe9\xa9\x00\x00\x00\xc7\x41\x3c\x03\x00\x00\x00\xe9\x9d\x00\x00\x00\xc7\x41\x3c\x05\x00\x00\x00\xe9\x91\x00\x00\x00\x48\x8b\x41\x18\x80\x38\x68\x75\x10\x48\xff\xc0\xc7\x41\x3c\x01\x00\x00\x00\x48\x89\x41\x18\xeb\x78\xc7\x41\x3c\x02\x00\x00\x00\xeb\x6f\xc7\x41\x3c\x0d\x00\x00\x00\xeb\x66\xc7\x41\x3c\x08\x00\x00\x00\xeb\x5d\x48\x8b\x51\x18\x8a\x02\x3c\x33\x75\x17\x80\x7a\x01\x32\x75\x11\x48\x8d\x42\x02\xc7\x41\x3c\x0a\x00\x00\x00\x48\x89\x41\x18\xeb\x3c\x3c\x36\x75\x17\x80\x7a\x01\x34\x75\x11\x48\x8d\x42\x02\xc7\x41\x3c\x0b\x00\x00\x00\x48\x89\x41\x18\xeb\x21\x2c\x58\x3c\x20\x77\x1b\x48\x0f\xbe\xc0\x48\xba\x01\x10\x82\x20\x01\x00\x00\x00\x48\x0f\xa3\xc2\x73\x07\xc7\x41\x3c\x09\x00\x00\x00\xb0\x01\x48\x83\xc4\x28\xc3\xcc\x48\x89\x5c\x24\x10\x48\x89\x6c\x24\x18\x48\x89\x74\x24\x20\x57\x41\x56\x41\x57\x48\x83\xec\x30\x0f\xbe\x41\x41\x48\x8b\xd9\x41\xbf\x01\x00\x00\x00\x83\xf8\x64\x7f\x5d\x0f\x84\xc8\x00\x00\x00\x83\xf8\x41\x0f\x84\xd2\x00\x00\x00\x83\xf8\x43\x74\x33\x83\xf8\x44\x0f\x8e\xcd\x00\x00\x00\x83\xf8\x47\x0f\x8e\xbb\x00\x00\x00\x83\xf8\x53\x74\x5f\x83\xf8\x58\x74\x6f\x83\xf8\x5a\x74\x1e\x83\xf8\x61\x0f\x84\xa3\x00\x00\x00\x83\xf8\x63\x0f\x85\xa3\x00\x00\x00\x33\xd2\xe8\xa0\x04\x00\x00\xe9\x93\x00\x00\x00\xe8\xfa\x01\x00\x00\xe9\x89\x00\x00\x00\x83\xf8\x67\x7e\x7f\x83\xf8\x69\x74\x67\x83\xf8\x6e\x74\x5b\x83\xf8\x6f\x74\x38\x83\xf8\x70\x74\x1b\x83\xf8\x73\x74\x0f\x83\xf8\x75\x74\x52\x83\xf8\x78\x75\x65\x8d\x50\x98\xeb\x4d\xe8\x8f\x07\x00\x00\xeb\x55\xc7\x41\x38\x10\x00\x00\x00\xc7\x41\x3c\x0b\x00\x00\x00\x45\x8a\xc7\xba\x10\x00\x00\x00\xeb\x31\x8b\x49\x30\x8b\xc1\xc1\xe8\x05\x41\x84\xc7\x74\x07\x0f\xba\xe9\x07\x89\x4b\x30\xba\x08\x00\x00\x00\x48\x8b\xcb\xeb\x10\xe8\x76\x06\x00\x00\xeb\x18\x83\x49\x30\x10\xba\x0a\x00\x00\x00\x45\x33\xc0\xe8\xc3\x04\x00\x00\xeb\x05\xe8\xec\x01\x00\x00\x84\xc0\x75\x07\x32\xc0\xe9\x45\x01\x00\x00\x80\x7b\x40\x00\x0f\x85\x38\x01\x00\x00\x8b\x53\x30\x33\xc0\x66\x89\x44\x24\x50\x33\xff\x88\x44\x24\x52\x8b\xc2\xc1\xe8\x04\x41\x84\xc7\x74\x2e\x8b\xc2\xc1\xe8\x06\x41\x84\xc7\x74\x07\xc6\x44\x24\x50\x2d\xeb\x1a\x41\x84\xd7\x74\x07\xc6\x44\x24\x50\x2b\xeb\x0e\x8b\xc2\xd1\xe8\x41\x84\xc7\x74\x08\xc6\x44\x24\x50\x20\x49\x8b\xff\x8a\x4b\x41\x8d\x41\xa8\xa8\xdf\x75\x0f\x8b\xc2\xc1\xe8\x05\x41\x84\xc7\x74\x05\x45\x8a\xc7\xeb\x03\x45\x32\xc0\x8d\x41\xbf\xa8\xdf\x0f\x94\xc0\x45\x84\xc0\x75\x04\x84\xc0\x74\x2a\xc6\x44\x3c\x50\x30\x49\x03\xff\x80\xf9\x58\x74\x09\x80\xf9\x41\x74\x04\x32\xc0\xeb\x03\x41\x8a\xc7\xf6\xd8\x1a\xc0\x24\xe0\x04\x61\x04\x17\x88\x44\x3c\x50\x49\x03\xff\x8b\x73\x34\x2b\x73\x50\x2b\xf7\xf6\xc2\x0c\x75\x15\x4c\x8d\x4b\x28\x44\x8b\xc6\x48\x8d\x8b\x68\x04\x00\x00\xb2\x20\xe8\x16\xf6\xff\xff\x48\x8b\x43\x10\x48\x8d\x6b\x28\x4c\x8d\xb3\x68\x04\x00\x00\x48\x89\x44\x24\x20\x4c\x8b\xcd\x48\x8d\x54\x24\x50\x49\x8b\xce\x44\x8b\xc7\xe8\x2f\x08\x00\x00\x8b\x4b\x30\x8b\xc1\xc1\xe8\x03\x41\x84\xc7\x74\x18\xc1\xe9\x02\x41\x84\xcf\x75\x10\x4c\x8b\xcd\x44\x8b\xc6\xb2\x30\x49\x8b\xce\xe8\xca\xf5\xff\xff\x33\xd2\x48\x8b\xcb\xe8\x28\x07\x00\x00\x83\x7d\x00\x00\x7c\x1b\x8b\x43\x30\xc1\xe8\x02\x41\x84\xc7\x74\x10\x4c\x8b\xcd\x44\x8b\xc6\xb2\x20\x49\x8b\xce\xe8\x9f\xf5\xff\xff\x41\x8a\xc7\x48\x8b\x5c\x24\x58\x48\x8b\x6c\x24\x60\x48\x8b\x74\x24\x68\x48\x83\xc4\x30\x41\x5f\x41\x5e\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x83\x41\x20\x08\x48\x8b\xd9\x48\x8b\x41\x20\x48\x8b\x78\xf8\x48\x85\xff\x74\x33\x48\x8b\x77\x08\x48\x85\xf6\x74\x2a\x44\x8b\x41\x3c\x8a\x51\x41\x48\x8b\x09\xe8\xdc\xf3\xff\xff\x84\xc0\x48\x89\x73\x48\x0f\xb7\x07\x74\x0b\xd1\xe8\x89\x43\x50\xc6\x43\x54\x01\xeb\x1b\x89\x43\x50\xeb\x12\x48\x8d\x0d\xfe\xc9\x00\x00\xc7\x43\x50\x06\x00\x00\x00\x48\x89\x4b\x48\xc6\x43\x54\x00\x48\x8b\x5c\x24\x30\xb0\x01\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x5c\x24\x10\x57\x48\x83\xec\x50\x83\x49\x30\x10\x48\x8b\xd9\x8b\x41\x38\x85\xc0\x79\x16\x8a\x41\x41\x2c\x41\x24\xdf\xf6\xd8\x1b\xc0\x83\xe0\xf9\x83\xc0\x0d\x89\x41\x38\xeb\x12\x75\x10\x8a\x41\x41\x2c\x47\xa8\xdf\x75\x07\xc7\x41\x38\x01\x00\x00\x00\x8b\x41\x38\x48\x8d\x79\x58\x05\x5d\x01\x00\x00\x48\x8b\xcf\x48\x63\xd0\xe8\x95\xf2\xff\xff\x41\xb8\x00\x02\x00\x00\x84\xc0\x75\x21\x48\x83\xbf\x08\x04\x00\x00\x00\x75\x05\x41\x8b\xc0\xeb\x0a\x48\x8b\x87\x00\x04\x00\x00\x48\xd1\xe8\x05\xa3\xfe\xff\xff\x89\x43\x38\x48\x8b\x87\x08\x04\x00\x00\x48\x85\xc0\x48\x0f\x44\xc7\x48\x89\x43\x48\x33\xc0\x48\x83\x43\x20\x08\x48\x83\xbf\x08\x04\x00\x00\x00\x48\x89\x44\x24\x60\x48\x8b\x43\x20\xf2\x0f\x10\x40\xf8\xf2\x0f\x11\x44\x24\x60\x75\x05\x4d\x8b\xc8\xeb\x0a\x4c\x8b\x8f\x00\x04\x00\x00\x49\xd1\xe9\x48\x8b\x8f\x08\x04\x00\x00\x48\x85\xc9\x75\x09\x4c\x8d\x97\x00\x02\x00\x00\xeb\x0d\x4c\x8b\x97\x00\x04\x00\x00\x49\xd1\xea\x4c\x03\xd1\x48\x83\xf9\x00\x74\x0a\x4c\x8b\x87\x00\x04\x00\x00\x49\xd1\xe8\x48\x8b\x43\x08\x48\x8b\xd1\x48\x89\x44\x24\x40\x48\x85\xc9\x48\x8b\x03\x0f\xbe\x4b\x41\x48\x0f\x44\xd7\x48\x89\x44\x24\x38\x8b\x43\x38\x89\x44\x24\x30\x89\x4c\x24\x28\x48\x8d\x4c\x24\x60\x4c\x89\x4c\x24\x20\x4d\x8b\xca\xe8\x86\x41\x00\x00\x8b\x43\x30\xc1\xe8\x05\xa8\x01\x74\x13\x83\x7b\x38\x00\x75\x0d\x48\x8b\x53\x08\x48\x8b\x4b\x48\xe8\x2d\xf6\xff\xff\x8a\x43\x41\x2c\x47\xa8\xdf\x75\x6d\x8b\x43\x30\xc1\xe8\x05\xa8\x01\x75\x63\x48\x8b\x43\x08\x48\x8b\x53\x48\x48\x8b\x08\x48\x8b\x81\xf8\x00\x00\x00\x48\x8b\x08\x44\x8a\x01\xeb\x08\x41\x3a\xc0\x74\x09\x48\xff\xc2\x8a\x02\x84\xc0\x75\xf2\x8a\x02\x48\xff\xc2\x84\xc0\x74\x32\xeb\x09\x2c\x45\xa8\xdf\x74\x09\x48\xff\xc2\x8a\x02\x84\xc0\x75\xf1\x48\x8b\xca\x48\xff\xca\x80\x3a\x30\x74\xf8\x44\x38\x02\x75\x03\x48\xff\xca\x8a\x01\x48\xff\xc2\x48\xff\xc1\x88\x02\x84\xc0\x75\xf2\x48\x8b\x43\x48\x80\x38\x2d\x75\x0b\x83\x4b\x30\x40\x48\xff\xc0\x48\x89\x43\x48\x48\x8b\x53\x48\x8a\x02\x2c\x49\x3c\x25\x77\x14\x48\xb9\x21\x00\x00\x00\x21\x00\x00\x00\x48\x0f\xa3\xc1\x73\x04\xc6\x43\x41\x73\x48\x83\xc9\xff\x48\xff\xc1\x80\x3c\x0a\x00\x75\xf7\x89\x4b\x50\xb0\x01\x48\x8b\x5c\x24\x68\x48\x83\xc4\x50\x5f\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x44\x8b\x41\x3c\x48\x8b\xd9\x8a\x51\x41\x48\x8b\x09\xe8\x60\xf1\xff\xff\x48\x8d\x7b\x58\x84\xc0\x74\x4b\x48\x83\x43\x20\x08\x48\x83\xbf\x08\x04\x00\x00\x00\x48\x8b\x43\x20\x75\x08\x41\xb8\x00\x02\x00\x00\xeb\x0a\x4c\x8b\x87\x00\x04\x00\x00\x49\xd1\xe8\x48\x8b\x97\x08\x04\x00\x00\x48\x8d\x4b\x50\x44\x0f\xb7\x48\xf8\x48\x85\xd2\x48\x0f\x44\xd7\xe8\xeb\x2c\x00\x00\x85\xc0\x74\x2a\xc6\x43\x40\x01\xeb\x24\x4c\x8b\x87\x08\x04\x00\x00\x4d\x85\xc0\x4c\x0f\x44\xc7\x48\x83\x43\x20\x08\x48\x8b\x4b\x20\x8a\x51\xf8\x41\x88\x10\xc7\x43\x50\x01\x00\x00\x00\x48\x8b\x8f\x08\x04\x00\x00\xb0\x01\x48\x85\xc9\x48\x0f\x44\xcf\x48\x89\x4b\x48\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x40\x53\x48\x83\xec\x20\x41\xbb\x08\x00\x00\x00\x48\x8b\xd9\x8b\x49\x3c\x45\x8a\xc8\x44\x8b\xd2\x45\x8d\x43\xfc\x83\xf9\x05\x7f\x65\x74\x18\x85\xc9\x74\x4c\x83\xe9\x01\x74\x53\x83\xe9\x01\x74\x47\x83\xe9\x01\x74\x3d\x83\xf9\x01\x75\x5c\x49\x8b\xd3\x48\x8b\xc2\x48\x83\xe8\x01\x0f\x84\xa2\x00\x00\x00\x48\x83\xe8\x01\x74\x7d\x48\x83\xe8\x02\x74\x5a\x49\x3b\xc0\x74\x3f\xe8\xe3\x1b\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\xb8\x1a\x00\x00\x32\xc0\xe9\x26\x01\x00\x00\x49\x8b\xd0\xeb\xc6\xba\x02\x00\x00\x00\xeb\xbf\xba\x01\x00\x00\x00\xeb\xb8\x83\xe9\x06\x74\xb0\x83\xe9\x01\x74\xab\x83\xe9\x02\x74\xa6\xeb\x9a\x33\xd2\xeb\xa3\x8b\x43\x30\x4c\x01\x5b\x20\xc1\xe8\x04\xa8\x01\x48\x8b\x43\x20\x48\x8b\x48\xf8\xeb\x59\x8b\x43\x30\x4c\x01\x5b\x20\xc1\xe8\x04\xa8\x01\x48\x8b\x43\x20\x74\x06\x48\x63\x48\xf8\xeb\x41\x8b\x48\xf8\xeb\x3c\x8b\x43\x30\x4c\x01\x5b\x20\xc1\xe8\x04\xa8\x01\x48\x8b\x43\x20\x74\x07\x48\x0f\xbf\x48\xf8\xeb\x23\x0f\xb7\x48\xf8\xeb\x1d\x8b\x43\x30\x4c\x01\x5b\x20\xc1\xe8\x04\xa8\x01\x48\x8b\x43\x20\x74\x07\x48\x0f\xbe\x48\xf8\xeb\x04\x0f\xb6\x48\xf8\x44\x8b\x43\x30\x41\x8b\xc0\xc1\xe8\x04\xa8\x01\x74\x10\x48\x85\xc9\x79\x0b\x48\xf7\xd9\x41\x83\xc8\x40\x44\x89\x43\x30\x83\x7b\x38\x00\x7d\x09\xc7\x43\x38\x01\x00\x00\x00\xeb\x11\x83\x63\x30\xf7\xb8\x00\x02\x00\x00\x39\x43\x38\x7e\x03\x89\x43\x38\x48\x85\xc9\x75\x04\x83\x63\x30\xdf\x45\x8b\xc2\x49\x3b\xd3\x75\x0d\x48\x8b\xd1\x48\x8b\xcb\xe8\x30\xf0\xff\xff\xeb\x0a\x8b\xd1\x48\x8b\xcb\xe8\x88\xef\xff\xff\x8b\x43\x30\xc1\xe8\x07\xa8\x01\x74\x1d\x83\x7b\x50\x00\x74\x09\x48\x8b\x4b\x48\x80\x39\x30\x74\x0e\x48\xff\x4b\x48\x48\x8b\x4b\x48\xc6\x01\x30\xff\x43\x50\xb0\x01\x48\x83\xc4\x20\x5b\xc3\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\xbb\x08\x00\x00\x00\x48\x8b\xf9\x48\x01\x59\x20\x48\x8b\x41\x20\x48\x8b\x70\xf8\xe8\xa8\x40\x00\x00\x85\xc0\x75\x17\xe8\x73\x1a\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x48\x19\x00\x00\x32\xc0\xe9\x88\x00\x00\x00\x8b\x4f\x3c\xba\x04\x00\x00\x00\x83\xf9\x05\x7f\x2c\x74\x3e\x85\xc9\x74\x37\x83\xe9\x01\x74\x1a\x83\xe9\x01\x74\x0e\x83\xe9\x01\x74\x28\x83\xf9\x01\x74\x26\x33\xdb\xeb\x22\xbb\x02\x00\x00\x00\xeb\x1b\xbb\x01\x00\x00\x00\xeb\x14\x83\xe9\x06\x74\x0f\x83\xe9\x01\x74\x0a\x83\xe9\x02\x74\x05\xeb\xd3\x48\x8b\xda\x48\x83\xeb\x01\x74\x2a\x48\x83\xeb\x01\x74\x1b\x48\x83\xeb\x02\x74\x0e\x48\x3b\xda\x75\x85\x48\x63\x47\x28\x48\x89\x06\xeb\x15\x8b\x47\x28\x89\x06\xeb\x0e\x0f\xb7\x47\x28\x66\x89\x06\xeb\x05\x8a\x4f\x28\x88\x0e\xc6\x47\x40\x01\xb0\x01\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x83\x41\x20\x08\x48\x8b\xd9\x48\x8b\x41\x20\x8b\x71\x38\x83\xfe\xff\x44\x8b\x41\x3c\x8a\x51\x41\x48\x8b\x78\xf8\xb8\xff\xff\xff\x7f\x48\x89\x79\x48\x0f\x44\xf0\x48\x8b\x09\xe8\x0c\xee\xff\xff\x48\x63\xd6\x84\xc0\x74\x1d\x48\x85\xff\xc6\x43\x54\x01\x48\x8d\x0d\x47\xc4\x00\x00\x48\x0f\x45\xcf\x48\x89\x4b\x48\xe8\x2e\x2b\x00\x00\xeb\x17\x48\x85\xff\x48\x8d\x0d\x22\xc4\x00\x00\x48\x0f\x45\xcf\x48\x89\x4b\x48\xe8\xb9\x29\x00\x00\x48\x8b\x74\x24\x38\x89\x43\x50\xb0\x01\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x83\xec\x28\x8b\x41\x14\xc1\xe8\x0c\xa8\x01\x75\x77\xe8\x11\x3f\x00\x00\x4c\x63\xc0\x48\x8d\x0d\x57\x56\x01\x00\x4c\x8d\x0d\xe0\x67\x01\x00\x41\x8d\x40\x02\x83\xf8\x01\x76\x17\x49\x8b\xd0\x49\x8b\xc0\x83\xe2\x3f\x48\xc1\xf8\x06\x48\xc1\xe2\x06\x49\x03\x14\xc1\xeb\x03\x48\x8b\xd1\x80\x7a\x39\x00\x75\x24\x41\x8d\x40\x02\x83\xf8\x01\x76\x15\x49\x8b\xc8\x49\x8b\xc0\x83\xe1\x3f\x48\xc1\xf8\x06\x48\xc1\xe1\x06\x49\x03\x0c\xc1\xf6\x41\x3d\x01\x74\x14\xe8\xc2\x18\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x97\x17\x00\x00\x32\xc0\xeb\x02\xb0\x01\x48\x83\xc4\x28\xc3\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x50\x48\x8b\x05\x22\x54\x01\x00\x48\x33\xc4\x48\x89\x44\x24\x40\x80\x79\x54\x00\x48\x8b\xd9\x74\x6e\x8b\x41\x50\x85\xc0\x7e\x67\x48\x8b\x71\x48\x33\xff\x85\xc0\x74\x7e\x44\x0f\xb7\x0e\x48\x8d\x54\x24\x34\x83\x64\x24\x30\x00\x48\x8d\x4c\x24\x30\x41\xb8\x06\x00\x00\x00\x48\x8d\x76\x02\xe8\xaa\x28\x00\x00\x85\xc0\x75\x31\x44\x8b\x44\x24\x30\x45\x85\xc0\x74\x27\x48\x8b\x43\x10\x4c\x8d\x4b\x28\x48\x8d\x8b\x68\x04\x00\x00\x48\x89\x44\x24\x20\x48\x8d\x54\x24\x34\xe8\x52\x00\x00\x00\xff\xc7\x3b\x7b\x50\x75\xab\xeb\x27\x83\x4b\x28\xff\xeb\x21\x48\x8b\x43\x10\x4c\x8d\x49\x28\x44\x8b\x43\x50\x48\x81\xc1\x68\x04\x00\x00\x48\x8b\x53\x48\x48\x89\x44\x24\x20\xe8\x22\x00\x00\x00\xb0\x01\x48\x8b\x4c\x24\x40\x48\x33\xcc\xe8\xa3\xcc\xff\xff\x48\x8b\x5c\x24\x68\x48\x8b\x74\x24\x70\x48\x83\xc4\x50\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x83\xec\x20\x48\x8b\x01\x49\x8b\xd9\x4c\x8b\xf2\x48\x8b\xf1\x44\x8b\x50\x14\x41\xc1\xea\x0c\x41\xf6\xc2\x01\x74\x12\x48\x8b\x01\x48\x83\x78\x08\x00\x75\x08\x45\x01\x01\xe9\x98\x00\x00\x00\x48\x8b\x7c\x24\x60\x49\x63\xe8\x48\x03\xea\x44\x8b\x3f\x83\x27\x00\x48\x3b\xd5\x74\x75\x48\x8b\x06\x41\x8a\x16\x8b\x48\x14\xc1\xe9\x0c\xf6\xc1\x01\x74\x0a\x48\x8b\x06\x48\x83\x78\x08\x00\x74\x14\x0f\xbe\xca\x48\x8b\x16\xe8\x68\x3d\x00\x00\x83\xf8\xff\x75\x04\x09\x03\xeb\x09\xff\x03\x8b\x03\x83\xf8\xff\x75\x35\x83\x3f\x2a\x75\x38\x48\x8b\x06\x8b\x48\x14\xc1\xe9\x0c\xf6\xc1\x01\x74\x0a\x48\x8b\x06\x48\x83\x78\x08\x00\x74\x16\x48\x8b\x16\xb9\x3f\x00\x00\x00\xe8\x2c\x3d\x00\x00\x83\xf8\xff\x75\x04\x09\x03\xeb\x02\xff\x03\x49\xff\xc6\x4c\x3b\xf5\x75\x8b\x83\x3f\x00\x75\x08\x45\x85\xff\x74\x03\x44\x89\x3f\x48\x8b\x5c\x24\x40\x48\x8b\x6c\x24\x48\x48\x8b\x74\x24\x50\x48\x83\xc4\x20\x41\x5f\x41\x5e\x5f\xc3\xcc\xcc\xcc\x40\x55\x48\x8b\xec\x48\x83\xec\x60\x48\x8b\x45\x30\x48\x89\x45\xc0\x4c\x89\x4d\x18\x4c\x89\x45\x28\x48\x89\x55\x10\x48\x89\x4d\x20\x48\x85\xd2\x75\x15\xe8\xb1\x16\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x86\x15\x00\x00\x83\xc8\xff\xeb\x4a\x4d\x85\xc0\x74\xe6\x48\x8d\x45\x10\x48\x89\x55\xc8\x48\x89\x45\xd8\x4c\x8d\x4d\xc8\x48\x8d\x45\x18\x48\x89\x55\xd0\x48\x89\x45\xe0\x4c\x8d\x45\xd8\x48\x8d\x45\x20\x48\x89\x45\xe8\x48\x8d\x55\xd0\x48\x8d\x45\x28\x48\x89\x45\xf0\x48\x8d\x4d\x30\x48\x8d\x45\xc0\x48\x89\x45\xf8\xe8\xef\xe9\xff\xff\x48\x83\xc4\x60\x5d\xc3\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x45\x33\xd2\x4c\x8b\xda\x4d\x85\xc9\x75\x2c\x48\x85\xc9\x75\x2c\x48\x85\xd2\x74\x14\xe8\x2c\x16\x00\x00\xbb\x16\x00\x00\x00\x89\x18\xe8\x00\x15\x00\x00\x44\x8b\xd3\x41\x8b\xc2\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x85\xc9\x74\xd9\x48\x85\xd2\x74\xd4\x4d\x85\xc9\x75\x06\x66\x44\x89\x11\xeb\xdd\x4d\x85\xc0\x75\x06\x66\x44\x89\x11\xeb\xbe\x4c\x2b\xc1\x48\x8b\xd1\x49\x8b\xdb\x49\x8b\xf9\x49\x83\xf9\xff\x75\x19\x41\x0f\xb7\x04\x10\x66\x89\x02\x48\x8d\x52\x02\x66\x85\xc0\x74\x2e\x48\x83\xeb\x01\x75\xe9\xeb\x26\x41\x0f\xb7\x04\x10\x66\x89\x02\x48\x8d\x52\x02\x66\x85\xc0\x74\x0c\x48\x83\xeb\x01\x74\x06\x48\x83\xef\x01\x75\xe3\x48\x85\xff\x75\x04\x66\x44\x89\x12\x48\x85\xdb\x0f\x85\x78\xff\xff\xff\x49\x83\xf9\xff\x75\x0f\x66\x46\x89\x54\x59\xfe\x44\x8d\x53\x50\xe9\x63\xff\xff\xff\x66\x44\x89\x11\xe8\x77\x15\x00\x00\xbb\x22\x00\x00\x00\xe9\x46\xff\xff\xff\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x20\x45\x33\xf6\x48\x8b\xfa\x48\x2b\xf9\x48\x8b\xd9\x48\x83\xc7\x07\x41\x8b\xee\x48\xc1\xef\x03\x48\x3b\xca\x49\x0f\x47\xfe\x48\x85\xff\x74\x1f\x48\x8b\x33\x48\x85\xf6\x74\x0b\x48\x8b\xce\xff\x15\x83\xb3\x00\x00\xff\xd6\x48\x83\xc3\x08\x48\xff\xc5\x48\x3b\xef\x75\xe1\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x8b\x7c\x24\x48\x48\x83\xc4\x20\x41\x5e\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8b\xf2\x48\x8b\xd9\x48\x3b\xca\x74\x20\x48\x8b\x3b\x48\x85\xff\x74\x0f\x48\x8b\xcf\xff\x15\x2d\xb3\x00\x00\xff\xd7\x85\xc0\x75\x0b\x48\x83\xc3\x08\x48\x3b\xde\xeb\xde\x33\xc0\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xb8\x63\x73\x6d\xe0\x3b\xc8\x74\x03\x33\xc0\xc3\x8b\xc8\xe9\x01\x00\x00\x00\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x48\x8b\xf2\x8b\xf9\xe8\x7e\x2c\x00\x00\x45\x33\xc0\x48\x8b\xd8\x48\x85\xc0\x75\x07\x33\xc0\xe9\x48\x01\x00\x00\x48\x8b\x08\x48\x8b\xc1\x48\x8d\x91\xc0\x00\x00\x00\x48\x3b\xca\x74\x0d\x39\x38\x74\x0c\x48\x83\xc0\x10\x48\x3b\xc2\x75\xf3\x49\x8b\xc0\x48\x85\xc0\x74\xd2\x48\x8b\x78\x08\x48\x85\xff\x74\xc9\x48\x83\xff\x05\x75\x0c\x4c\x89\x40\x08\x8d\x47\xfc\xe9\x06\x01\x00\x00\x48\x83\xff\x01\x0f\x84\xf9\x00\x00\x00\x48\x8b\x6b\x08\x48\x89\x73\x08\x8b\x70\x04\x83\xfe\x08\x0f\x85\xd0\x00\x00\x00\x48\x83\xc1\x30\x48\x8d\x91\x90\x00\x00\x00\xeb\x08\x4c\x89\x41\x08\x48\x83\xc1\x10\x48\x3b\xca\x75\xf3\x81\x38\x8d\x00\x00\xc0\x8b\x73\x10\x0f\x84\x88\x00\x00\x00\x81\x38\x8e\x00\x00\xc0\x74\x77\x81\x38\x8f\x00\x00\xc0\x74\x66\x81\x38\x90\x00\x00\xc0\x74\x55\x81\x38\x91\x00\x00\xc0\x74\x44\x81\x38\x92\x00\x00\xc0\x74\x33\x81\x38\x93\x00\x00\xc0\x74\x22\x81\x38\xb4\x02\x00\xc0\x74\x11\x81\x38\xb5\x02\x00\xc0\x75\x4f\xc7\x43\x10\x8d\x00\x00\x00\xeb\x46\xc7\x43\x10\x8e\x00\x00\x00\xeb\x3d\xc7\x43\x10\x85\x00\x00\x00\xeb\x34\xc7\x43\x10\x8a\x00\x00\x00\xeb\x2b\xc7\x43\x10\x84\x00\x00\x00\xeb\x22\xc7\x43\x10\x81\x00\x00\x00\xeb\x19\xc7\x43\x10\x86\x00\x00\x00\xeb\x10\xc7\x43\x10\x83\x00\x00\x00\xeb\x07\xc7\x43\x10\x82\x00\x00\x00\x48\x8b\xcf\xff\x15\xa7\xb1\x00\x00\x8b\x53\x10\xb9\x08\x00\x00\x00\xff\xd7\x89\x73\x10\xeb\x11\x48\x8b\xcf\x4c\x89\x40\x08\xff\x15\x8b\xb1\x00\x00\x8b\xce\xff\xd7\x48\x89\x6b\x08\x83\xc8\xff\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x33\xc0\x81\xf9\x63\x73\x6d\xe0\x0f\x94\xc0\xc3\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x70\x10\x48\x89\x78\x18\x4c\x89\x70\x20\x41\x57\x48\x83\xec\x20\x41\x8b\xf0\x8b\xda\x44\x8b\xf1\x45\x85\xc0\x75\x4a\x33\xc9\xff\x15\x66\xae\x00\x00\x48\x85\xc0\x74\x3d\xb9\x4d\x5a\x00\x00\x66\x39\x08\x75\x33\x48\x63\x48\x3c\x48\x03\xc8\x81\x39\x50\x45\x00\x00\x75\x24\xb8\x0b\x02\x00\x00\x66\x39\x41\x18\x75\x19\x83\xb9\x84\x00\x00\x00\x0e\x76\x10\x39\xb1\xf8\x00\x00\x00\x74\x08\x41\x8b\xce\xe8\x48\x01\x00\x00\xb9\x02\x00\x00\x00\xe8\x6a\x3a\x00\x00\x90\x80\x3d\x32\x5f\x01\x00\x00\x0f\x85\xb2\x00\x00\x00\x41\xbf\x01\x00\x00\x00\x41\x8b\xc7\x87\x05\x11\x5f\x01\x00\x85\xdb\x75\x48\x48\x8b\x3d\xe2\x4d\x01\x00\x8b\xd7\x83\xe2\x3f\x8d\x4b\x40\x2b\xca\x33\xc0\x48\xd3\xc8\x48\x33\xc7\x48\x8b\x0d\xf1\x5e\x01\x00\x48\x3b\xc8\x74\x1a\x48\x33\xf9\x8b\xca\x48\xd3\xcf\x48\x8b\xcf\xff\x15\x8b\xb0\x00\x00\x45\x33\xc0\x33\xd2\x33\xc9\xff\xd7\x48\x8d\x0d\xfb\x5e\x01\x00\xeb\x0c\x41\x3b\xdf\x75\x0d\x48\x8d\x0d\x05\x5f\x01\x00\xe8\x48\x07\x00\x00\x90\x85\xdb\x75\x13\x48\x8d\x15\xc4\xb0\x00\x00\x48\x8d\x0d\x9d\xb0\x00\x00\xe8\x80\xfc\xff\xff\x48\x8d\x15\xc1\xb0\x00\x00\x48\x8d\x0d\xb2\xb0\x00\x00\xe8\x6d\xfc\xff\xff\x0f\xb6\x05\x8e\x5e\x01\x00\x85\xf6\x41\x0f\x44\xc7\x88\x05\x82\x5e\x01\x00\xeb\x06\xe8\x5b\x09\x00\x00\x90\xb9\x02\x00\x00\x00\xe8\xf4\x39\x00\x00\x85\xf6\x75\x09\x41\x8b\xce\xe8\x1c\x00\x00\x00\xcc\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x8b\x7c\x24\x40\x4c\x8b\x74\x24\x48\x48\x83\xc4\x20\x41\x5f\xc3\x40\x53\x48\x83\xec\x20\x8b\xd9\xe8\xb7\x16\x00\x00\x84\xc0\x74\x28\x65\x48\x8b\x04\x25\x60\x00\x00\x00\x8b\x90\xbc\x00\x00\x00\xc1\xea\x08\xf6\xc2\x01\x75\x11\xff\x15\xb2\xad\x00\x00\x48\x8b\xc8\x8b\xd3\xff\x15\xaf\xad\x00\x00\x8b\xcb\xe8\x0c\x00\x00\x00\x8b\xcb\xff\x15\x60\xae\x00\x00\xcc\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x83\x64\x24\x38\x00\x4c\x8d\x44\x24\x38\x8b\xf9\x48\x8d\x15\xe6\xbc\x00\x00\x33\xc9\xff\x15\x3e\xae\x00\x00\x85\xc0\x74\x27\x48\x8b\x4c\x24\x38\x48\x8d\x15\xe6\xbc\x00\x00\xff\x15\xf0\xad\x00\x00\x48\x8b\xd8\x48\x85\xc0\x74\x0d\x48\x8b\xc8\xff\x15\x57\xaf\x00\x00\x8b\xcf\xff\xd3\x48\x8b\x4c\x24\x38\x48\x85\xc9\x74\x06\xff\x15\xc3\xad\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x89\x0d\x81\x5d\x01\x00\xc3\x33\xd2\x33\xc9\x44\x8d\x42\x01\xe9\xc7\xfd\xff\xff\xcc\xcc\xcc\x45\x33\xc0\x41\x8d\x50\x02\xe9\xb8\xfd\xff\xff\x8b\x05\x5a\x5d\x01\x00\xc3\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x33\xff\x48\x39\x3d\x59\x5d\x01\x00\x74\x04\x33\xc0\xeb\x48\xe8\xe2\x3f\x00\x00\xe8\x6d\x43\x00\x00\x48\x8b\xd8\x48\x85\xc0\x75\x05\x83\xcf\xff\xeb\x27\x48\x8b\xc8\xe8\x34\x00\x00\x00\x48\x85\xc0\x75\x05\x83\xcf\xff\xeb\x0e\x48\x89\x05\x3b\x5d\x01\x00\x48\x89\x05\x1c\x5d\x01\x00\x33\xc9\xe8\x15\x08\x00\x00\x48\x8b\xcb\xe8\x0d\x08\x00\x00\x8b\xc7\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x83\xec\x30\x33\xf6\x4c\x8b\xf1\x8b\xd6\xeb\x1a\x3c\x3d\x74\x03\x48\xff\xc2\x48\x83\xc8\xff\x48\xff\xc0\x40\x38\x34\x01\x75\xf7\x48\xff\xc1\x48\x03\xc8\x8a\x01\x84\xc0\x75\xe0\x48\x8d\x4a\x01\xba\x08\x00\x00\x00\xe8\x09\x09\x00\x00\x48\x8b\xd8\x48\x85\xc0\x74\x6c\x4c\x8b\xf8\x41\x38\x36\x74\x61\x48\x83\xcd\xff\x48\xff\xc5\x41\x38\x34\x2e\x75\xf7\x48\xff\xc5\x41\x80\x3e\x3d\x74\x35\xba\x01\x00\x00\x00\x48\x8b\xcd\xe8\xd6\x08\x00\x00\x48\x8b\xf8\x48\x85\xc0\x74\x25\x4d\x8b\xc6\x48\x8b\xd5\x48\x8b\xc8\xe8\x08\x08\x00\x00\x33\xc9\x85\xc0\x75\x48\x49\x89\x3f\x49\x83\xc7\x08\xe8\x56\x07\x00\x00\x4c\x03\xf5\xeb\xab\x48\x8b\xcb\xe8\x45\x00\x00\x00\x33\xc9\xe8\x42\x07\x00\x00\xeb\x03\x48\x8b\xf3\x33\xc9\xe8\x36\x07\x00\x00\x48\x8b\x5c\x24\x50\x48\x8b\xc6\x48\x8b\x74\x24\x60\x48\x8b\x6c\x24\x58\x48\x83\xc4\x30\x41\x5f\x41\x5e\x5f\xc3\x45\x33\xc9\x48\x89\x74\x24\x20\x45\x33\xc0\x33\xd2\xe8\x44\x0e\x00\x00\xcc\xcc\xcc\xcc\x48\x85\xc9\x74\x3b\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\x01\x48\x8b\xd9\x48\x8b\xf9\xeb\x0f\x48\x8b\xc8\xe8\xe2\x06\x00\x00\x48\x8d\x7f\x08\x48\x8b\x07\x48\x85\xc0\x75\xec\x48\x8b\xcb\xe8\xce\x06\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x83\xec\x28\x48\x8b\x09\x48\x3b\x0d\xca\x5b\x01\x00\x74\x05\xe8\xa7\xff\xff\xff\x48\x83\xc4\x28\xc3\xcc\xcc\x48\x83\xec\x28\x48\x8b\x09\x48\x3b\x0d\xa6\x5b\x01\x00\x74\x05\xe8\x8b\xff\xff\xff\x48\x83\xc4\x28\xc3\xcc\xcc\x48\x83\xec\x28\x48\x8d\x0d\x7d\x5b\x01\x00\xe8\xb8\xff\xff\xff\x48\x8d\x0d\x79\x5b\x01\x00\xe8\xc8\xff\xff\xff\x48\x8b\x0d\x7d\x5b\x01\x00\xe8\x5c\xff\xff\xff\x48\x8b\x0d\x69\x5b\x01\x00\x48\x83\xc4\x28\xe9\x4c\xff\xff\xff\xe9\xdf\xfd\xff\xff\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xd9\x49\x8b\xf8\x8b\x0a\xe8\x54\x36\x00\x00\x90\x48\x8b\xcf\xe8\xb7\x01\x00\x00\x8b\xf8\x8b\x0b\xe8\x96\x36\x00\x00\x8b\xc7\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x4c\x89\x4c\x24\x20\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x40\x49\x8b\xf9\x4d\x8b\xf8\x8b\x0a\xe8\x0b\x36\x00\x00\x90\x49\x8b\x07\x48\x8b\x10\x48\x85\xd2\x75\x09\x48\x83\xcb\xff\xe9\x40\x01\x00\x00\x48\x8b\x35\x8f\x49\x01\x00\x44\x8b\xc6\x41\x83\xe0\x3f\x48\x8b\xfe\x48\x33\x3a\x41\x8b\xc8\x48\xd3\xcf\x48\x89\x7c\x24\x30\x48\x8b\xde\x48\x33\x5a\x08\x48\xd3\xcb\x48\x89\x5c\x24\x20\x48\x8d\x47\xff\x48\x83\xf8\xfd\x0f\x87\xfa\x00\x00\x00\x4c\x8b\xe7\x48\x89\x7c\x24\x28\x4c\x8b\xf3\x48\x89\x5c\x24\x38\x41\xbd\x40\x00\x00\x00\x41\x8b\xcd\x41\x2b\xc8\x33\xc0\x48\xd3\xc8\x48\x33\xc6\x48\x83\xeb\x08\x48\x89\x5c\x24\x20\x48\x3b\xdf\x72\x0c\x48\x39\x03\x75\x02\xeb\xeb\x48\x3b\xdf\x73\x4a\x48\x83\xcb\xff\x48\x3b\xfb\x74\x0f\x48\x8b\xcf\xe8\x43\x05\x00\x00\x48\x8b\x35\x04\x49\x01\x00\x8b\xc6\x83\xe0\x3f\x44\x2b\xe8\x41\x8b\xcd\x33\xd2\x48\xd3\xca\x48\x33\xd6\x49\x8b\x07\x48\x8b\x08\x48\x89\x11\x49\x8b\x07\x48\x8b\x08\x48\x89\x51\x08\x49\x8b\x07\x48\x8b\x08\x48\x89\x51\x10\xeb\x72\x8b\xce\x83\xe1\x3f\x48\x33\x33\x48\xd3\xce\x48\x89\x03\x48\x8b\xce\xff\x15\x93\xab\x00\x00\xff\xd6\x49\x8b\x07\x48\x8b\x10\x48\x8b\x35\xac\x48\x01\x00\x44\x8b\xc6\x41\x83\xe0\x3f\x4c\x8b\xce\x4c\x33\x0a\x41\x8b\xc8\x49\xd3\xc9\x48\x8b\x42\x08\x48\x33\xc6\x48\xd3\xc8\x4d\x3b\xcc\x75\x05\x49\x3b\xc6\x74\x20\x4d\x8b\xe1\x4c\x89\x4c\x24\x28\x49\x8b\xf9\x4c\x89\x4c\x24\x30\x4c\x8b\xf0\x48\x89\x44\x24\x38\x48\x8b\xd8\x48\x89\x44\x24\x20\xe9\x1c\xff\xff\xff\x48\x8b\xbc\x24\x88\x00\x00\x00\x33\xdb\x8b\x0f\xe8\x03\x35\x00\x00\x8b\xc3\x48\x8b\x5c\x24\x70\x48\x8b\x74\x24\x78\x48\x83\xc4\x40\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\xc3\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x54\x41\x56\x41\x57\x48\x83\xec\x20\x48\x8b\x01\x33\xf6\x4c\x8b\xf9\x48\x8b\x18\x48\x85\xdb\x75\x08\x83\xc8\xff\xe9\x86\x01\x00\x00\x4c\x8b\x05\xf8\x47\x01\x00\x41\xbc\x40\x00\x00\x00\x48\x8b\x2b\x41\x8b\xc8\x4c\x8b\x4b\x08\x83\xe1\x3f\x48\x8b\x5b\x10\x49\x33\xe8\x4d\x33\xc8\x48\xd3\xcd\x49\x33\xd8\x49\xd3\xc9\x48\xd3\xcb\x4c\x3b\xcb\x0f\x85\xc7\x00\x00\x00\x48\x2b\xdd\xb8\x00\x02\x00\x00\x48\xc1\xfb\x03\x48\x3b\xd8\x48\x8b\xfb\x48\x0f\x47\xf8\x41\x8d\x44\x24\xe0\x48\x03\xfb\x48\x0f\x44\xf8\x48\x3b\xfb\x72\x1f\x45\x8d\x44\x24\xc8\x48\x8b\xd7\x48\x8b\xcd\xe8\xef\x3f\x00\x00\x33\xc9\x4c\x8b\xf0\xe8\xbd\x03\x00\x00\x4d\x85\xf6\x75\x28\x48\x8d\x7b\x04\x41\xb8\x08\x00\x00\x00\x48\x8b\xd7\x48\x8b\xcd\xe8\xcb\x3f\x00\x00\x33\xc9\x4c\x8b\xf0\xe8\x99\x03\x00\x00\x4d\x85\xf6\x0f\x84\x51\xff\xff\xff\x4c\x8b\x05\x51\x47\x01\x00\x4d\x8d\x0c\xde\x41\x8b\xc0\x49\x8d\x1c\xfe\x83\xe0\x3f\x41\x8b\xcc\x2b\xc8\x48\x8b\xd6\x48\xd3\xca\x48\x8b\xc3\x49\x2b\xc1\x49\x33\xd0\x48\x83\xc0\x07\x49\x8b\xee\x48\xc1\xe8\x03\x49\x8b\xc9\x4c\x3b\xcb\x48\x0f\x47\xc6\x48\x85\xc0\x74\x16\x48\xff\xc6\x48\x89\x11\x48\x8d\x49\x08\x48\x3b\xf0\x75\xf1\x4c\x8b\x05\xff\x46\x01\x00\x41\x8b\xc0\x41\x8b\xcc\x83\xe0\x3f\x2b\xc8\x49\x8b\x47\x08\x48\x8b\x10\x41\x8b\xc4\x48\xd3\xca\x49\x33\xd0\x4d\x8d\x41\x08\x49\x89\x11\x48\x8b\x15\xd6\x46\x01\x00\x8b\xca\x83\xe1\x3f\x2b\xc1\x8a\xc8\x49\x8b\x07\x48\xd3\xcd\x48\x33\xea\x48\x8b\x08\x48\x89\x29\x41\x8b\xcc\x48\x8b\x15\xb4\x46\x01\x00\x8b\xc2\x83\xe0\x3f\x2b\xc8\x49\x8b\x07\x49\xd3\xc8\x4c\x33\xc2\x48\x8b\x10\x4c\x89\x42\x08\x48\x8b\x15\x96\x46\x01\x00\x8b\xc2\x83\xe0\x3f\x44\x2b\xe0\x49\x8b\x07\x41\x8a\xcc\x48\xd3\xcb\x48\x33\xda\x48\x8b\x08\x33\xc0\x48\x89\x59\x10\x48\x8b\x5c\x24\x40\x48\x8b\x6c\x24\x48\x48\x8b\x74\x24\x50\x48\x8b\x7c\x24\x58\x48\x83\xc4\x20\x41\x5f\x41\x5e\x41\x5c\xc3\xcc\xcc\x48\x8b\xd1\x48\x8d\x0d\xa6\x57\x01\x00\xe9\x7d\x00\x00\x00\xcc\x4c\x8b\xdc\x49\x89\x4b\x08\x48\x83\xec\x38\x49\x8d\x43\x08\x49\x89\x43\xe8\x4d\x8d\x4b\x18\xb8\x02\x00\x00\x00\x4d\x8d\x43\xe8\x49\x8d\x53\x20\x89\x44\x24\x50\x49\x8d\x4b\x10\x89\x44\x24\x58\xe8\x3f\xfc\xff\xff\x48\x83\xc4\x38\xc3\xcc\xcc\x45\x33\xc9\x4c\x8b\xc1\x48\x85\xc9\x75\x04\x83\xc8\xff\xc3\x48\x8b\x41\x10\x48\x39\x01\x75\x24\x48\x8b\x15\xed\x45\x01\x00\xb9\x40\x00\x00\x00\x8b\xc2\x83\xe0\x3f\x2b\xc8\x49\xd3\xc9\x4c\x33\xca\x4d\x89\x08\x4d\x89\x48\x08\x4d\x89\x48\x10\x33\xc0\xc3\xcc\x48\x89\x54\x24\x10\x48\x89\x4c\x24\x08\x55\x48\x8b\xec\x48\x83\xec\x40\x48\x8d\x45\x10\x48\x89\x45\xe8\x4c\x8d\x4d\x28\x48\x8d\x45\x18\x48\x89\x45\xf0\x4c\x8d\x45\xe8\xb8\x02\x00\x00\x00\x48\x8d\x55\xe0\x48\x8d\x4d\x20\x89\x45\x28\x89\x45\xe0\xe8\x7a\xfb\xff\xff\x48\x83\xc4\x40\x5d\xc3\x48\x8d\x05\x7d\x47\x01\x00\x48\x89\x05\xde\x5c\x01\x00\xb0\x01\xc3\xcc\xcc\xcc\x48\x83\xec\x28\x48\x8d\x0d\xbd\x56\x01\x00\xe8\x54\xff\xff\xff\x48\x8d\x0d\xc9\x56\x01\x00\xe8\x48\xff\xff\xff\xb0\x01\x48\x83\xc4\x28\xc3\xcc\x48\x83\xec\x28\xe8\xf3\xfa\xff\xff\xb0\x01\x48\x83\xc4\x28\xc3\x40\x53\x48\x83\xec\x20\x48\x8b\x15\x2f\x45\x01\x00\xb9\x40\x00\x00\x00\x8b\xc2\x33\xdb\x83\xe0\x3f\x2b\xc8\x48\xd3\xcb\x48\x33\xda\x48\x8b\xcb\xe8\xb7\x07\x00\x00\x48\x8b\xcb\xe8\x3f\x3f\x00\x00\x48\x8b\xcb\xe8\x2b\x40\x00\x00\x48\x8b\xcb\xe8\xff\x42\x00\x00\x48\x8b\xcb\xe8\x93\xf8\xff\xff\xb0\x01\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x33\xc9\xe9\x89\xd0\xff\xff\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\x0d\x6b\x4a\x01\x00\x83\xc8\xff\xf0\x0f\xc1\x01\x83\xf8\x01\x75\x1f\x48\x8b\x0d\x58\x4a\x01\x00\x48\x8d\x1d\x29\x48\x01\x00\x48\x3b\xcb\x74\x0c\xe8\xe7\x00\x00\x00\x48\x89\x1d\x40\x4a\x01\x00\x48\x8b\x0d\xf1\x5b\x01\x00\xe8\xd4\x00\x00\x00\x48\x8b\x0d\xed\x5b\x01\x00\x33\xdb\x48\x89\x1d\xdc\x5b\x01\x00\xe8\xbf\x00\x00\x00\x48\x8b\x0d\x30\x5e\x01\x00\x48\x89\x1d\xd1\x5b\x01\x00\xe8\xac\x00\x00\x00\x48\x8b\x0d\x25\x5e\x01\x00\x48\x89\x1d\x16\x5e\x01\x00\xe8\x99\x00\x00\x00\xb0\x01\x48\x89\x1d\x10\x5e\x01\x00\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xb0\x01\xc3\xcc\x48\x8d\x15\x95\xb5\x00\x00\x48\x8d\x0d\x9e\xb4\x00\x00\xe9\x89\x3d\x00\x00\xcc\x48\x83\xec\x28\xe8\xab\x20\x00\x00\x48\x85\xc0\x0f\x95\xc0\x48\x83\xc4\x28\xc3\x48\x83\xec\x28\xe8\xbf\x1f\x00\x00\xb0\x01\x48\x83\xc4\x28\xc3\x48\x8d\x15\x5d\xb5\x00\x00\x48\x8d\x0d\x66\xb4\x00\x00\xe9\xe5\x3d\x00\x00\xcc\x48\x83\xec\x28\xe8\x4f\x21\x00\x00\xb0\x01\x48\x83\xc4\x28\xc3\x40\x53\x48\x83\xec\x20\xe8\xcd\x1f\x00\x00\x48\x8b\x58\x18\x48\x85\xdb\x74\x0d\x48\x8b\xcb\xff\x15\xab\xa6\x00\x00\xff\xd3\xeb\x00\xe8\x02\x01\x00\x00\x90\xcc\x48\x85\xc9\x74\x37\x53\x48\x83\xec\x20\x4c\x8b\xc1\x33\xd2\x48\x8b\x0d\x5a\x5d\x01\x00\xff\x15\x5c\xa5\x00\x00\x85\xc0\x75\x17\xe8\x17\x08\x00\x00\x48\x8b\xd8\xff\x15\xa2\xa5\x00\x00\x8b\xc8\xe8\x4f\x07\x00\x00\x89\x03\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\xd9\x48\x83\xf9\xe0\x77\x3c\x48\x85\xc9\xb8\x01\x00\x00\x00\x48\x0f\x44\xd8\xeb\x15\xe8\xba\x41\x00\x00\x85\xc0\x74\x25\x48\x8b\xcb\xe8\x96\x3d\x00\x00\x85\xc0\x74\x19\x48\x8b\x0d\xf7\x5c\x01\x00\x4c\x8b\xc3\x33\xd2\xff\x15\xfc\xa4\x00\x00\x48\x85\xc0\x74\xd4\xeb\x0d\xe8\xac\x07\x00\x00\xc7\x00\x0c\x00\x00\x00\x33\xc0\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\x40\x53\x48\x83\xec\x20\x33\xdb\x48\x85\xc9\x74\x0c\x48\x85\xd2\x74\x07\x4d\x85\xc0\x75\x1b\x88\x19\xe8\x7e\x07\x00\x00\xbb\x16\x00\x00\x00\x89\x18\xe8\x52\x06\x00\x00\x8b\xc3\x48\x83\xc4\x20\x5b\xc3\x4c\x8b\xc9\x4c\x2b\xc1\x43\x8a\x04\x08\x41\x88\x01\x49\xff\xc1\x84\xc0\x74\x06\x48\x83\xea\x01\x75\xec\x48\x85\xd2\x75\xd9\x88\x19\xe8\x44\x07\x00\x00\xbb\x22\x00\x00\x00\xeb\xc4\xcc\x48\x83\xec\x28\xe8\xb7\x3d\x00\x00\x48\x85\xc0\x74\x0a\xb9\x16\x00\x00\x00\xe8\xf8\x3d\x00\x00\xf6\x05\x41\x44\x01\x00\x02\x74\x29\xb9\x17\x00\x00\x00\xe8\x6b\x93\x00\x00\x85\xc0\x74\x07\xb9\x07\x00\x00\x00\xcd\x29\x41\xb8\x01\x00\x00\x00\xba\x15\x00\x00\x40\x41\x8d\x48\x02\xe8\xc6\x03\x00\x00\xb9\x03\x00\x00\x00\xe8\x2c\xf6\xff\xff\xcc\xcc\xcc\xcc\x40\x53\x48\x83\xec\x20\x4c\x8b\xc2\x48\x8b\xd9\x48\x85\xc9\x74\x0e\x33\xd2\x48\x8d\x42\xe0\x48\xf7\xf3\x49\x3b\xc0\x72\x43\x49\x0f\xaf\xd8\xb8\x01\x00\x00\x00\x48\x85\xdb\x48\x0f\x44\xd8\xeb\x15\xe8\x8e\x40\x00\x00\x85\xc0\x74\x28\x48\x8b\xcb\xe8\x6a\x3c\x00\x00\x85\xc0\x74\x1c\x48\x8b\x0d\xcb\x5b\x01\x00\x4c\x8b\xc3\xba\x08\x00\x00\x00\xff\x15\xcd\xa3\x00\x00\x48\x85\xc0\x74\xd1\xeb\x0d\xe8\x7d\x06\x00\x00\xc7\x00\x0c\x00\x00\x00\x33\xc0\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\xf6\xc1\x04\x74\x03\xb0\x01\xc3\xf6\xc1\x01\x74\x19\x83\xe1\x02\x74\x08\x81\xfa\x00\x00\x00\x80\x77\xeb\x85\xc9\x75\x08\x81\xfa\xff\xff\xff\x7f\x77\xdf\x32\xc0\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x18\x48\x89\x7c\x24\x20\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8b\xec\x48\x83\xec\x40\x48\x83\x3a\x00\x45\x8a\xe1\x45\x8b\xf8\x48\x8b\xda\x75\x26\xe8\x0d\x06\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\xe2\x04\x00\x00\x48\x8b\x4b\x08\x48\x85\xc9\x74\x06\x48\x8b\x03\x48\x89\x01\x33\xc0\xe9\xa1\x02\x00\x00\x45\x85\xc0\x74\x09\x41\x8d\x40\xfe\x83\xf8\x22\x77\xcc\x48\x8b\xd1\x48\x8d\x4d\xe0\xe8\xbe\xdc\xff\xff\x4c\x8b\x2b\x33\xf6\x48\x8b\x55\xe8\x4c\x89\x6d\x38\x41\x8a\x7d\x00\x49\x8d\x45\x01\x44\x8d\x6e\x08\x48\x89\x03\x83\x7a\x08\x01\x40\x0f\xb6\xc7\x7e\x14\x4c\x8d\x45\xe8\x41\x8b\xd5\x8b\xc8\xe8\xb6\x3f\x00\x00\x48\x8b\x55\xe8\xeb\x0d\x48\x8b\xc8\x48\x8b\x02\x0f\xb7\x04\x48\x41\x23\xc5\x85\xc0\x74\x0b\x48\x8b\x03\x40\x8a\x38\x48\xff\xc0\xeb\xc3\x45\x33\xf6\x45\x84\xe4\x41\x0f\x95\xc6\x40\x80\xff\x2d\x75\x06\x41\x83\xce\x02\xeb\x06\x40\x80\xff\x2b\x75\x0c\x48\x8b\x03\x40\x8a\x38\x48\xff\xc0\x48\x89\x03\x4c\x8b\x6d\x38\x41\x83\xcc\xff\x41\xf7\xc7\xef\xff\xff\xff\x0f\x85\x80\x00\x00\x00\x8d\x47\xd0\x3c\x09\x77\x09\x40\x0f\xbe\xc7\x83\xc0\xd0\xeb\x23\x8d\x47\x9f\x3c\x19\x77\x09\x40\x0f\xbe\xc7\x83\xc0\xa9\xeb\x13\x8d\x47\xbf\x3c\x19\x77\x09\x40\x0f\xbe\xc7\x83\xc0\xc9\xeb\x03\x41\x8b\xc4\x41\xb9\x08\x00\x00\x00\x85\xc0\x74\x0b\x45\x85\xff\x75\x44\x45\x8d\x79\x02\xeb\x3e\x48\x8b\x03\x8a\x10\x48\x8d\x48\x01\x48\x89\x0b\x8d\x42\xa8\xa8\xdf\x74\x47\x45\x85\xff\x45\x0f\x44\xf9\x48\xff\xc9\x48\x89\x0b\x84\xd2\x74\x1a\x38\x11\x74\x16\xe8\xca\x04\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\x9f\x03\x00\x00\x41\xb9\x08\x00\x00\x00\x33\xd2\x41\x8b\xc4\x41\xf7\xf7\x44\x8b\xc0\x8d\x4f\xd0\x80\xf9\x09\x77\x21\x40\x0f\xbe\xcf\x83\xc1\xd0\xeb\x3b\x40\x8a\x39\xb8\x10\x00\x00\x00\x45\x85\xff\x44\x0f\x44\xf8\x48\x8d\x41\x01\x48\x89\x03\xeb\xcc\x8d\x47\x9f\x3c\x19\x77\x09\x40\x0f\xbe\xcf\x83\xc1\xa9\xeb\x13\x8d\x47\xbf\x3c\x19\x77\x09\x40\x0f\xbe\xcf\x83\xc1\xc9\xeb\x03\x41\x8b\xcc\x41\x3b\xcc\x74\x2d\x41\x3b\xcf\x73\x28\x45\x0b\xf1\x41\x3b\xf0\x72\x0c\x75\x04\x3b\xca\x76\x06\x41\x83\xce\x04\xeb\x06\x41\x0f\xaf\xf7\x03\xf1\x48\x8b\x03\x40\x8a\x38\x48\xff\xc0\x48\x89\x03\xeb\x82\x48\xff\x0b\x48\x8b\x03\x40\x84\xff\x74\x15\x40\x38\x38\x74\x10\xe8\x1b\x04\x00\x00\xc7\x00\x16\x00\x00\x00\xe8\xf0\x02\x00\x00\x41\xf6\xc6\x08\x75\x1d\x80\x7d\xf8\x00\x4c\x89\x2b\x0f\x84\xfb\xfd\xff\xff\x48\x8b\x45\xe0\x83\xa0\xa8\x03\x00\x00\xfd\xe9\xeb\xfd\xff\xff\x8b\xd6\x41\x8b\xce\xe8\x77\xfd\xff\xff\x84\xc0\x74\x6a\xe8\xda\x03\x00\x00\xc7\x00\x22\x00\x00\x00\x41\xf6\xc6\x01\x75\x05\x41\x8b\xf4\xeb\x5c\x41\xf6\xc6\x02\x74\x27\x80\x7d\xf8\x00\x74\x0b\x48\x8b\x45\xe0\x83\xa0\xa8\x03\x00\x00\xfd\x48\x8b\x4b\x08\x48\x85\xc9\x74\x06\x48\x8b\x03\x48\x89\x01\xb8\x00\x00\x00\x80\xeb\x51\x80\x7d\xf8\x00\x74\x0b\x48\x8b\x45\xe0\x83\xa0\xa8\x03\x00\x00\xfd\x48\x8b\x4b\x08\x48\x85\xc9\x74\x06\x48\x8b\x03\x48\x89\x01\xb8\xff\xff\xff\x7f\xeb\x2a\x41\xf6\xc6\x02\x74\x02\xf7\xde\x80\x7d\xf8\x00\x74\x0b\x48\x8b\x4d\xe0\x83\xa1\xa8\x03\x00\x00\xfd\x48\x8b\x43\x08\x48\x85\xc0\x74\x06\x48\x8b\x0b\x48\x89\x08\x8b\xc6\x4c\x8d\x5c\x24\x40\x49\x8b\x5b\x30\x49\x8b\x73\x40\x49\x8b\x7b\x48\x49\x8b\xe3\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5d\xc3\xcc\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x18\x55\x57\x41\x56\x48\x8d\xac\x24\x10\xfb\xff\xff\x48\x81\xec\xf0\x05\x00\x00\x48\x8b\x05\x94\x3e\x01\x00\x48\x33\xc4\x48\x89\x85\xe0\x04\x00\x00\x41\x8b\xf8\x8b\xf2\x8b\xd9\x83\xf9\xff\x74\x05\xe8\xa1\xc1\xff\xff\x33\xd2\x48\x8d\x4c\x24\x70\x41\xb8\x98\x00\x00\x00\xe8\x87\xca\xff\xff\x33\xd2\x48\x8d\x4d\x10\x41\xb8\xd0\x04\x00\x00\xe8\x76\xca\xff\xff\x48\x8d\x44\x24\x70\x48\x89\x44\x24\x48\x48\x8d\x4d\x10\x48\x8d\x45\x10\x48\x89\x44\x24\x50\xff\x15\xd9\x9e\x00\x00\x4c\x8b\xb5\x08\x01\x00\x00\x48\x8d\x54\x24\x40\x49\x8b\xce\x45\x33\xc0\xff\x15\xc9\x9e\x00\x00\x48\x85\xc0\x74\x36\x48\x83\x64\x24\x38\x00\x48\x8d\x4c\x24\x60\x48\x8b\x54\x24\x40\x4c\x8b\xc8\x48\x89\x4c\x24\x30\x4d\x8b\xc6\x48\x8d\x4c\x24\x58\x48\x89\x4c\x24\x28\x48\x8d\x4d\x10\x48\x89\x4c\x24\x20\x33\xc9\xff\x15\x96\x9e\x00\x00\x48\x8b\x85\x08\x05\x00\x00\x48\x89\x85\x08\x01\x00\x00\x48\x8d\x85\x08\x05\x00\x00\x48\x83\xc0\x08\x89\x74\x24\x70\x48\x89\x85\xa8\x00\x00\x00\x48\x8b\x85\x08\x05\x00\x00\x48\x89\x45\x80\x89\x7c\x24\x74\xff\x15\xb5\x9e\x00\x00\x33\xc9\x8b\xf8\xff\x15\x63\x9e\x00\x00\x48\x8d\x4c\x24\x48\xff\x15\x50\x9e\x00\x00\x85\xc0\x75\x10\x85\xff\x75\x0c\x83\xfb\xff\x74\x07\x8b\xcb\xe8\xac\xc0\xff\xff\x48\x8b\x8d\xe0\x04\x00\x00\x48\x33\xcc\xe8\xa5\xb6\xff\xff\x4c\x8d\x9c\x24\xf0\x05\x00\x00\x49\x8b\x5b\x28\x49\x8b\x73\x30\x49\x8b\xe3\x41\x5e\x5f\x5d\xc3\xcc\x48\x89\x0d\xdd\x4e\x01\x00\xc3\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x30\x41\x8b\xf9\x49\x8b\xf0\x48\x8b\xea\x4c\x8b\xf1\xe8\xa6\x19\x00\x00\x48\x85\xc0\x74\x41\x48\x8b\x98\xb8\x03\x00\x00\x48\x85\xdb\x74\x35\x48\x8b\xcb\xff\x15\xe8\x9f\x00\x00\x44\x8b\xcf\x4c\x8b\xc6\x48\x8b\xd5\x49\x8b\xce\x48\x8b\xc3\x48\x8b\x5c\x24\x40\x48\x8b\x6c\x24\x48\x48\x8b\x74\x24\x50\x48\x8b\x7c\x24\x58\x48\x83\xc4\x30\x41\x5e\x48\xff\xe0\x48\x8b\x1d\xdd\x3c\x01\x00\x8b\xcb\x48\x33\x1d\x5c\x4e\x01\x00\x83\xe1\x3f\x48\xd3\xcb\x48\x85\xdb\x75\xb0\x48\x8b\x44\x24\x60\x44\x8b\xcf\x4c\x8b\xc6\x48\x89\x44\x24\x20\x48\x8b\xd5\x49\x8b\xce\xe8\x22\x00\x00\x00\xcc\xcc\x48\x83\xec\x38\x48\x83\x64\x24\x20\x00\x45\x33\xc9\x45\x33\xc0\x33\xd2\x33\xc9\xe8\x3f\xff\xff\xff\x48\x83\xc4\x38\xc3\xcc\xcc\x48\x83\xec\x28\xb9\x17\x00\x00\x00\xe8\x4c\x8d\x00\x00\x85\xc0\x74\x07\xb9\x05\x00\x00\x00\xcd\x29\x41\xb8\x01\x00\x00\x00\xba\x17\x04\x00\xc0\x41\x8d\x48\x01\xe8\xa7\xfd\xff\xff\xff\x15\x21\x9d\x00\x00\x48\x8b\xc8\xba\x17\x04\x00\xc0\x48\x83\xc4\x28\x48\xff\x25\x16\x9d\x00\x00\xcc\xcc\x33\xc0\x4c\x8d\x0d\x8b\xad\x00\x00\x49\x8b\xd1\x44\x8d\x40\x08\x3b\x0a\x74\x2b\xff\xc0\x49\x03\xd0\x83\xf8\x2d\x72\xf2\x8d\x41\xed\x83\xf8\x11\x77\x06\xb8\x0d\x00\x00\x00\xc3\x81\xc1\x44\xff\xff\xff\xb8\x16\x00\x00\x00\x83\xf9\x0e\x41\x0f\x46\xc0\xc3\x41\x8b\x44\xc1\x04\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x8b\xf9\xe8\x67\x18\x00\x00\x48\x85\xc0\x75\x09\x48\x8d\x05\x7f\x3d\x01\x00\xeb\x04\x48\x83\xc0\x24\x89\x38\xe8\x4e\x18\x00\x00\x48\x8d\x1d\x67\x3d\x01\x00\x48\x85\xc0\x74\x04\x48\x8d\x58\x20\x8b\xcf\xe8\x77\xff\xff\xff\x89\x03\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x48\x83\xec\x28\xe8\x1f\x18\x00\x00\x48\x85\xc0\x75\x09\x48\x8d\x05\x37\x3d\x01\x00\xeb\x04\x48\x83\xc0\x24\x48\x83\xc4\x28\xc3\x48\x83\xec\x28\xe8\xff\x17\x00\x00\x48\x85\xc0\x75\x09\x48\x8d\x05\x13\x3d\x01\x00\xeb\x04\x48\x83\xc0\x20\x48\x83\xc4\x28\xc3\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x20\x44\x8b\xf1\x4c\x8d\x3d\x46\x9b\xff\xff\x4d\x8b\xe1\x49\x8b\xe8\x4c\x8b\xea\x4b\x8b\x8c\xf7\x30\xb2\x01\x00\x4c\x8b\x15\x2e\x3b\x01\x00\x48\x83\xcf\xff\x41\x8b\xc2\x49\x8b\xd2\x48\x33\xd1\x83\xe0\x3f\x8a\xc8\x48\xd3\xca\x48\x3b\xd7\x0f\x84\x25\x01\x00\x00\x48\x85\xd2\x74\x08\x48\x8b\xc2\xe9\x1a\x01\x00\x00\x4d\x3b\xc1\x0f\x84\xa3\x00\x00\x00\x8b\x75\x00\x49\x8b\x9c\xf7\x90\xb1\x01\x00\x48\x85\xdb\x74\x07\x48\x3b\xdf\x74\x7a\xeb\x73\x4d\x8b\xbc\xf7\xc0\x12\x01\x00\x33\xd2\x49\x8b\xcf\x41\xb8\x00\x08\x00\x00\xff\x15\x32\x9c\x00\x00\x48\x8b\xd8\x48\x85\xc0\x75\x20\xff\x15\xc4\x9c\x00\x00\x83\xf8\x57\x75\x13\x45\x33\xc0\x33\xd2\x49\x8b\xcf\xff\x15\x11\x9c\x00\x00\x48\x8b\xd8\xeb\x02\x33\xdb\x4c\x8d\x3d\x9b\x9a\xff\xff\x48\x85\xdb\x75\x0d\x48\x8b\xc7\x49\x87\x84\xf7\x90\xb1\x01\x00\xeb\x1e\x48\x8b\xc3\x49\x87\x84\xf7\x90\xb1\x01\x00\x48\x85\xc0\x74\x09\x48\x8b\xcb\xff\x15\xc8\x9b\x00\x00\x48\x85\xdb\x75\x55\x48\x83\xc5\x04\x49\x3b\xec\x0f\x85\x64\xff\xff\xff\x4c\x8b\x15\x57\x3a\x01\x00\x33\xdb\x48\x85\xdb\x74\x4a\x49\x8b\xd5\x48\x8b\xcb\xff\x15\xa4\x9b\x00\x00\x48\x85\xc0\x74\x32\x4c\x8b\x05\x38\x3a\x01\x00\xba\x40\x00\x00\x00\x41\x8b\xc8\x83\xe1\x3f\x2b\xd1\x8a\xca\x48\x8b\xd0\x48\xd3\xca\x49\x33\xd0\x4b\x87\x94\xf7\x30\xb2\x01\x00\xeb\x2d\x4c\x8b\x15\x0f\x3a\x01\x00\xeb\xb8\x4c\x8b\x15\x06\x3a\x01\x00\x41\x8b\xc2\xb9\x40\x00\x00\x00\x83\xe0\x3f\x2b\xc8\x48\xd3\xcf\x49\x33\xfa\x4b\x87\xbc\xf7\x30\xb2\x01\x00\x33\xc0\x48\x8b\x5c\x24\x50\x48\x8b\x6c\x24\x58\x48\x8b\x74\x24\x60\x48\x83\xc4\x20\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xf9\x4c\x8d\x0d\xb0\xb1\x00\x00\xb9\x03\x00\x00\x00\x4c\x8d\x05\x9c\xb1\x00\x00\x48\x8d\x15\x85\x9e\x00\x00\xe8\x34\xfe\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x10\x48\x8b\xc8\xff\x15\x67\x9c\x00\x00\x48\x8b\xcf\xff\xd3\xeb\x06\xff\x15\xba\x9a\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x8b\xd9\x4c\x8d\x0d\x61\xb1\x00\x00\xb9\x04\x00\x00\x00\x4c\x8d\x05\x4d\xb1\x00\x00\x48\x8d\x15\x46\x9e\x00\x00\xe8\xdd\xfd\xff\xff\x48\x8b\xf8\x48\x85\xc0\x74\x0f\x48\x8b\xc8\xff\x15\x10\x9c\x00\x00\x8b\xcb\xff\xd7\xeb\x08\x8b\xcb\xff\x15\x7a\x9a\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x8b\xd9\x4c\x8d\x0d\x11\xb1\x00\x00\xb9\x05\x00\x00\x00\x4c\x8d\x05\xfd\xb0\x00\x00\x48\x8d\x15\xfe\x9d\x00\x00\xe8\x85\xfd\xff\xff\x48\x8b\xf8\x48\x85\xc0\x74\x0f\x48\x8b\xc8\xff\x15\xb8\x9b\x00\x00\x8b\xcb\xff\xd7\xeb\x08\x8b\xcb\xff\x15\x12\x9a\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8b\xda\x4c\x8d\x0d\xbb\xb0\x00\x00\x8b\xf9\x48\x8d\x15\xc2\x9d\x00\x00\xb9\x06\x00\x00\x00\x4c\x8d\x05\x9e\xb0\x00\x00\xe8\x25\xfd\xff\xff\x48\x8b\xf0\x48\x85\xc0\x74\x12\x48\x8b\xc8\xff\x15\x58\x9b\x00\x00\x48\x8b\xd3\x8b\xcf\xff\xd6\xeb\x0b\x48\x8b\xd3\x8b\xcf\xff\x15\xb4\x99\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x41\x8b\xe8\x4c\x8d\x0d\x76\xb0\x00\x00\x8b\xda\x4c\x8d\x05\x65\xb0\x00\x00\x48\x8b\xf9\x48\x8d\x15\x63\x9d\x00\x00\xb9\x14\x00\x00\x00\xe8\xb5\xfc\xff\xff\x48\x8b\xf0\x48\x85\xc0\x74\x15\x48\x8b\xc8\xff\x15\xe8\x9a\x00\x00\x44\x8b\xc5\x8b\xd3\x48\x8b\xcf\xff\xd6\xeb\x0b\x8b\xd3\x48\x8b\xcf\xff\x15\x29\x99\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x50\x41\x8b\xf9\x49\x8b\xf0\x8b\xea\x4c\x8d\x0d\xfc\xaf\x00\x00\x4c\x8b\xf1\x4c\x8d\x05\xea\xaf\x00\x00\x48\x8d\x15\xeb\xaf\x00\x00\xb9\x16\x00\x00\x00\xe8\x35\xfc\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x57\x48\x8b\xc8\xff\x15\x68\x9a\x00\x00\x48\x8b\x8c\x24\xa0\x00\x00\x00\x44\x8b\xcf\x48\x8b\x84\x24\x80\x00\x00\x00\x4c\x8b\xc6\x48\x89\x4c\x24\x40\x8b\xd5\x48\x8b\x8c\x24\x98\x00\x00\x00\x48\x89\x4c\x24\x38\x48\x8b\x8c\x24\x90\x00\x00\x00\x48\x89\x4c\x24\x30\x8b\x8c\x24\x88\x00\x00\x00\x89\x4c\x24\x28\x49\x8b\xce\x48\x89\x44\x24\x20\xff\xd3\xeb\x32\x33\xd2\x49\x8b\xce\xe8\x44\x00\x00\x00\x8b\xc8\x44\x8b\xcf\x8b\x84\x24\x88\x00\x00\x00\x4c\x8b\xc6\x89\x44\x24\x28\x8b\xd5\x48\x8b\x84\x24\x80\x00\x00\x00\x48\x89\x44\x24\x20\xff\x15\xd0\x98\x00\x00\x48\x8b\x5c\x24\x60\x48\x8b\x6c\x24\x68\x48\x8b\x74\x24\x70\x48\x8b\x7c\x24\x78\x48\x83\xc4\x50\x41\x5e\xc3\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x8b\xf2\x4c\x8d\x0d\x34\xaf\x00\x00\x48\x8b\xd9\x48\x8d\x15\x2a\xaf\x00\x00\xb9\x18\x00\x00\x00\x4c\x8d\x05\x16\xaf\x00\x00\xe8\x55\xfb\xff\xff\x48\x8b\xf8\x48\x85\xc0\x74\x12\x48\x8b\xc8\xff\x15\x88\x99\x00\x00\x8b\xd6\x48\x8b\xcb\xff\xd7\xeb\x08\x48\x8b\xcb\xe8\x03\x37\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x89\x7c\x24\x08\x48\x8b\x15\x80\x36\x01\x00\x48\x8d\x3d\xa9\x48\x01\x00\x8b\xc2\xb9\x40\x00\x00\x00\x83\xe0\x3f\x2b\xc8\x33\xc0\x48\xd3\xc8\xb9\x20\x00\x00\x00\x48\x33\xc2\xf3\x48\xab\x48\x8b\x7c\x24\x08\xb0\x01\xc3\xcc\x48\x89\x5c\x24\x10\x57\x48\x83\xec\x20\x8b\x05\x74\x49\x01\x00\x33\xdb\x85\xc0\x74\x08\x83\xf8\x01\x0f\x94\xc0\xeb\x5c\x4c\x8d\x0d\x47\xae\x00\x00\xb9\x08\x00\x00\x00\x4c\x8d\x05\x33\xae\x00\x00\x48\x8d\x15\x34\xae\x00\x00\xe8\xab\xfa\xff\xff\x48\x8b\xf8\x48\x85\xc0\x74\x28\x48\x8b\xc8\x89\x5c\x24\x30\xff\x15\xda\x98\x00\x00\x33\xd2\x48\x8d\x4c\x24\x30\xff\xd7\x83\xf8\x7a\x75\x0d\x8d\x48\x87\xb0\x01\x87\x0d\x19\x49\x01\x00\xeb\x0d\xb8\x02\x00\x00\x00\x87\x05\x0c\x49\x01\x00\x32\xc0\x48\x8b\x5c\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x40\x53\x48\x83\xec\x20\x84\xc9\x75\x2f\x48\x8d\x1d\x4b\x47\x01\x00\x48\x8b\x0b\x48\x85\xc9\x74\x10\x48\x83\xf9\xff\x74\x06\xff\x15\xff\x96\x00\x00\x48\x83\x23\x00\x48\x83\xc3\x08\x48\x8d\x05\xc8\x47\x01\x00\x48\x3b\xd8\x75\xd8\xb0\x01\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x30\x83\x64\x24\x20\x00\xb9\x08\x00\x00\x00\xe8\xcf\x21\x00\x00\x90\xbb\x03\x00\x00\x00\x89\x5c\x24\x24\x3b\x1d\x6f\x46\x01\x00\x74\x6e\x48\x63\xfb\x48\x8b\x05\x6b\x46\x01\x00\x48\x8b\x04\xf8\x48\x85\xc0\x75\x02\xeb\x55\x8b\x48\x14\xc1\xe9\x0d\xf6\xc1\x01\x74\x19\x48\x8b\x0d\x4e\x46\x01\x00\x48\x8b\x0c\xf9\xe8\x49\x36\x00\x00\x83\xf8\xff\x74\x04\xff\x44\x24\x20\x48\x8b\x05\x35\x46\x01\x00\x48\x8b\x0c\xf8\x48\x83\xc1\x30\xff\x15\x97\x96\x00\x00\x48\x8b\x0d\x20\x46\x01\x00\x48\x8b\x0c\xf9\xe8\x37\xf1\xff\xff\x48\x8b\x05\x10\x46\x01\x00\x48\x83\x24\xf8\x00\xff\xc3\xeb\x86\xb9\x08\x00\x00\x00\xe8\x99\x21\x00\x00\x8b\x44\x24\x20\x48\x8b\x5c\x24\x40\x48\x83\xc4\x30\x5f\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8b\xd9\x8b\x41\x14\x24\x03\x3c\x02\x75\x4a\x8b\x41\x14\xa8\xc0\x74\x43\x8b\x39\x2b\x79\x08\x83\x61\x10\x00\x48\x8b\x71\x08\x48\x89\x31\x85\xff\x7e\x2f\xe8\xf9\x1e\x00\x00\x8b\xc8\x44\x8b\xc7\x48\x8b\xd6\xe8\xd4\x3c\x00\x00\x3b\xf8\x74\x0a\xf0\x83\x4b\x14\x10\x83\xc8\xff\xeb\x11\x8b\x43\x14\xc1\xe8\x02\xa8\x01\x74\x05\xf0\x83\x63\x14\xfd\x33\xc0\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\xd9\x48\x85\xc9\x75\x0a\x48\x83\xc4\x20\x5b\xe9\x40\x00\x00\x00\xe8\x6b\xff\xff\xff\x85\xc0\x74\x05\x83\xc8\xff\xeb\x1f\x8b\x43\x14\xc1\xe8\x0b\xa8\x01\x74\x13\x48\x8b\xcb\xe8\x84\x1e\x00\x00\x8b\xc8\xe8\x31\x36\x00\x00\x85\xc0\x75\xde\x33\xc0\x48\x83\xc4\x20\x5b\xc3\xcc\xb9\x01\x00\x00\x00\xe9\x02\x00\x00\x00\xcc\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x70\x18\x57\x41\x56\x41\x57\x48\x83\xec\x40\x8b\xf1\x83\x60\xcc\x00\x83\x60\xc8\x00\xb9\x08\x00\x00\x00\xe8\x3c\x20\x00\x00\x90\x48\x8b\x3d\xec\x44\x01\x00\x48\x63\x05\xdd\x44\x01\x00\x4c\x8d\x34\xc7\x41\x83\xcf\xff\x48\x89\x7c\x24\x28\x49\x3b\xfe\x74\x71\x48\x8b\x1f\x48\x89\x5c\x24\x68\x48\x89\x5c\x24\x30\x48\x85\xdb\x75\x02\xeb\x57\x48\x8b\xcb\xe8\x93\xcb\xff\xff\x90\x8b\x43\x14\xc1\xe8\x0d\xa8\x01\x74\x3c\x83\xfe\x01\x75\x13\x48\x8b\xcb\xe8\x2b\xff\xff\xff\x41\x3b\xc7\x74\x2a\xff\x44\x24\x24\xeb\x24\x85\xf6\x75\x20\x8b\x43\x14\xd1\xe8\xa8\x01\x74\x17\x48\x8b\xcb\xe8\x0b\xff\xff\xff\x8b\x54\x24\x20\x41\x3b\xc7\x41\x0f\x44\xd7\x89\x54\x24\x20\x48\x8b\xcb\xe8\x50\xcb\xff\xff\x48\x83\xc7\x08\xeb\x85\xb9\x08\x00\x00\x00\xe8\xf4\x1f\x00\x00\x8b\x44\x24\x20\x83\xfe\x01\x0f\x44\x44\x24\x24\x48\x8b\x5c\x24\x60\x48\x8b\x74\x24\x70\x48\x83\xc4\x40\x41\x5f\x41\x5e\x5f\xc3\x40\x53\x48\x83\xec\x20\x48\x8b\xd9\x8b\x41\x14\xc1\xe8\x0d\xa8\x01\x74\x27\x8b\x41\x14\xc1\xe8\x06\xa8\x01\x74\x1d\x48\x8b\x49\x08\xe8\x32\xef\xff\xff\xf0\x81\x63\x14\xbf\xfe\xff\xff\x33\xc0\x48\x89\x43\x08\x48\x89\x03\x89\x43\x10\x48\x83\xc4\x20\x5b\xc3\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x81\xec\x90\x00\x00\x00\x48\x8d\x48\x88\xff\x15\xca\x93\x00\x00\x45\x33\xf6\x66\x44\x39\x74\x24\x62\x0f\x84\x98\x00\x00\x00\x48\x8b\x44\x24\x68\x48\x85\xc0\x0f\x84\x8a\x00\x00\x00\x48\x63\x18\x48\x8d\x70\x04\xbf\x00\x20\x00\x00\x48\x03\xde\x39\x38\x0f\x4c\x38\x8b\xcf\xe8\x82\x3f\x00\x00\x3b\x3d\xbc\x49\x01\x00\x0f\x4f\x3d\xb5\x49\x01\x00\x85\xff\x74\x5e\x41\x8b\xee\x48\x83\x3b\xff\x74\x45\x48\x83\x3b\xfe\x74\x3f\xf6\x06\x01\x74\x3a\xf6\x06\x08\x75\x0d\x48\x8b\x0b\xff\x15\x1f\x94\x00\x00\x85\xc0\x74\x28\x48\x8b\xcd\x48\x8d\x15\x81\x45\x01\x00\x83\xe1\x3f\x48\x8b\xc5\x48\xc1\xf8\x06\x48\xc1\xe1\x06\x48\x03\x0c\xc2\x48\x8b\x03\x48\x89\x41\x28\x8a\x06\x88\x41\x38\x48\xff\xc5\x48\xff\xc6\x48\x83\xc3\x08\x48\x83\xef\x01\x75\xa5\x4c\x8d\x9c\x24\x90\x00\x00\x00\x49\x8b\x5b\x10\x49\x8b\x6b\x18\x49\x8b\x73\x20\x49\x8b\x7b\x28\x49\x8b\xe3\x41\x5e\xc3\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7c\x24\x18\x41\x56\x48\x83\xec\x20\x33\xff\x45\x33\xf6\x48\x63\xdf\x48\x8d\x0d\x10\x45\x01\x00\x48\x8b\xc3\x83\xe3\x3f\x48\xc1\xf8\x06\x48\xc1\xe3\x06\x48\x03\x1c\xc1\x48\x8b\x43\x28\x48\x83\xc0\x02\x48\x83\xf8\x01\x76\x09\x80\x4b\x38\x80\xe9\x89\x00\x00\x00\xc6\x43\x38\x81\x8b\xcf\x85\xff\x74\x16\x83\xe9\x01\x74\x0a\x83\xf9\x01\xb9\xf4\xff\xff\xff\xeb\x0c\xb9\xf5\xff\xff\xff\xeb\x05\xb9\xf6\xff\xff\xff\xff\x15\x44\x93\x00\x00\x48\x8b\xf0\x48\x8d\x48\x01\x48\x83\xf9\x01\x76\x0b\x48\x8b\xc8\xff\x15\x36\x93\x00\x00\xeb\x02\x33\xc0\x85\xc0\x74\x1d\x0f\xb6\xc8\x48\x89\x73\x28\x83\xf9\x02\x75\x06\x80\x4b\x38\x40\xeb\x2e\x83\xf9\x03\x75\x29\x80\x4b\x38\x08\xeb\x23\x80\x4b\x38\x40\x48\xc7\x43\x28\xfe\xff\xff\xff\x48\x8b\x05\x46\x42\x01\x00\x48\x85\xc0\x74\x0b\x49\x8b\x04\x06\xc7\x40\x18\xfe\xff\xff\xff\xff\xc7\x49\x83\xc6\x08\x83\xff\x03\x0f\x85\x35\xff\xff\xff\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x8b\x7c\x24\x40\x48\x83\xc4\x20\x41\x5e\xc3\xcc\x40\x53\x48\x83\xec\x20\xb9\x07\x00\x00\x00\xe8\x48\x1d\x00\x00\x33\xdb\x33\xc9\xe8\xdf\x3d\x00\x00\x85\xc0\x75\x0c\xe8\xf6\xfd\xff\xff\xe8\xdd\xfe\xff\xff\xb3\x01\xb9\x07\x00\x00\x00\xe8\x79\x1d\x00\x00\x8a\xc3\x48\x83\xc4\x20\x5b\xc3\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x33\xdb\x48\x8d\x3d\xe9\x43\x01\x00\x48\x8b\x0c\x3b\x48\x85\xc9\x74\x0a\xe8\x4b\x3d\x00\x00\x48\x83\x24\x3b\x00\x48\x83\xc3\x08\x48\x81\xfb\x00\x04\x00\x00\x72\xd9\xb0\x01\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x40\x53\x48\x83\xec\x40\x48\x63\xd9\x8b\x05\xcd\x47\x01\x00\x85\xc0\x74\x4b\x33\xd2\x48\x8d\x4c\x24\x20\xe8\xbd\xcb\xff\xff\x48\x8b\x44\x24\x28\x83\x78\x08\x01\x7e\x15\x4c\x8d\x44\x24\x28\xba\x04\x00\x00\x00\x8b\xcb\xe8\xcd\x2e\x00\x00\x8b\xd0\xeb\x0a\x48\x8b\x00\x0f\xb7\x14\x58\x83\xe2\x04\x80\x7c\x24\x38\x00\x74\x1c\x48\x8b\x44\x24\x20\x83\xa0\xa8\x03\x00\x00\xfd\xeb\x0e\x48\x8b\x05\x17\x32\x01\x00\x0f\xb7\x14\x58\x83\xe2\x04\x8b\xc2\x48\x83\xc4\x40\x5b\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x63\xf9\x48\x85\xd2\x74\x1f\x48\x8b\x02\x83\x78\x08\x01\x7e\x11\x4c\x8b\xc2\x8b\xcf\xba\x01\x00\x00\x00\xe8\x6a\x2e\x00\x00\xeb\x11\x48\x8b\x00\xeb\x05\xe8\x2e\x2e\x00\x00\x0f\xb7\x04\x78\x83\xe0\x01\x48\x8b\x5c\x24\x30\x85\xc0\x0f\x95\xc0\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x20\x55\x48\x8b\xec\x48\x83\xec\x70\x48\x63\xd9\x48\x8d\x4d\xe0\xe8\xfa\xca\xff\xff\x81\xfb\x00\x01\x00\x00\x73\x38\x48\x8d\x55\xe8\x8b\xcb\xe8\x7f\xff\xff\xff\x84\xc0\x74\x0f\x48\x8b\x45\xe8\x48\x8b\x88\x10\x01\x00\x00\x0f\xb6\x1c\x19\x80\x7d\xf8\x00\x0f\x84\xdc\x00\x00\x00\x48\x8b\x45\xe0\x83\xa0\xa8\x03\x00\x00\xfd\xe9\xcc\x00\x00\x00\x33\xc0\x66\x89\x45\x10\x88\x45\x12\x48\x8b\x45\xe8\x83\x78\x08\x01\x7e\x28\x8b\xf3\x48\x8d\x55\xe8\xc1\xfe\x08\x40\x0f\xb6\xce\xe8\x69\x3e\x00\x00\x85\xc0\x74\x12\x40\x88\x75\x10\xb9\x02\x00\x00\x00\x88\x5d\x11\xc6\x45\x12\x00\xeb\x17\xe8\x8e\xf3\xff\xff\xb9\x01\x00\x00\x00\xc7\x00\x2a\x00\x00\x00\x88\x5d\x10\xc6\x45\x11\x00\x48\x8b\x55\xe8\x4c\x8d\x4d\x10\x33\xc0\xc7\x44\x24\x40\x01\x00\x00\x00\x66\x89\x45\x20\x41\xb8\x00\x01\x00\x00\x88\x45\x22\x8b\x42\x0c\x48\x8b\x92\x38\x01\x00\x00\x89\x44\x24\x38\x48\x8d\x45\x20\xc7\x44\x24\x30\x03\x00\x00\x00\x48\x89\x44\x24\x28\x89\x4c\x24\x20\x48\x8d\x4d\xe8\xe8\x8d\x41\x00\x00\x85\xc0\x0f\x84\x41\xff\xff\xff\x0f\xb6\x5d\x20\x83\xf8\x01\x0f\x84\x34\xff\xff\xff\x0f\xb6\x4d\x21\xc1\xe3\x08\x0b\xd9\x80\x7d\xf8\x00\x74\x0b\x48\x8b\x4d\xe0\x83\xa1\xa8\x03\x00\x00\xfd\x4c\x8d\x5c\x24\x70\x8b\xc3\x49\x8b\x5b\x18\x49\x8b\x73\x28\x49\x8b\xe3\x5d\xc3\xcc\xcc\x48\x83\xec\x28\x8b\x05\xce\x45\x01\x00\x85\xc0\x74\x0b\x33\xd2\xe8\xab\xfe\xff\xff\x8b\xc8\xeb\x0b\x8d\x41\xbf\x83\xf8\x19\x77\x03\x83\xc1\x20\x8b\xc1\x48\x83\xc4\x28\xc3\xcc\x48\x89\x11\x4c\x89\x41\x08\x4d\x85\xc0\x74\x03\x49\x89\x10\x48\x8b\xc1\xc3\xcc\x40\x53\x48\x83\xec\x30\x41\x8b\xd8\x4c\x8b\xc2\x48\x8b\xd1\x48\x8d\x4c\x24\x20\xe8\xd3\xff\xff\xff\x48\x8b\xd0\x41\xb1\x01\x44\x8b\xc3\x33\xc9\xe8\x43\xec\xff\xff\x48\x83\xc4\x30\x5b\xc3\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x50\x45\x33\xf6\x49\x8b\xe8\x48\x8b\xf2\x48\x8b\xf9\x48\x85\xd2\x74\x13\x4d\x85\xc0\x74\x0e\x44\x38\x32\x75\x26\x48\x85\xc9\x74\x04\x66\x44\x89\x31\x33\xc0\x48\x8b\x5c\x24\x60\x48\x8b\x6c\x24\x68\x48\x8b\x74\x24\x70\x48\x8b\x7c\x24\x78\x48\x83\xc4\x50\x41\x5e\xc3\x49\x8b\xd1\x48\x8d\x4c\x24\x30\xe8\x01\xc9\xff\xff\x48\x8b\x44\x24\x38\x4c\x39\xb0\x38\x01\x00\x00\x75\x15\x48\x85\xff\x74\x06\x0f\xb6\x06\x66\x89\x07\xbb\x01\x00\x00\x00\xe9\xa4\x00\x00\x00\x0f\xb6\x0e\x48\x8d\x54\x24\x38\xe8\xa5\x3c\x00\x00\xbb\x01\x00\x00\x00\x85\xc0\x74\x51\x48\x8b\x4c\x24\x38\x44\x8b\x49\x08\x44\x3b\xcb\x7e\x2f\x41\x3b\xe9\x7c\x2a\x8b\x49\x0c\x8d\x53\x08\x41\x8b\xc6\x48\x85\xff\x4c\x8b\xc6\x0f\x95\xc0\x89\x44\x24\x28\x48\x89\x7c\x24\x20\xff\x15\xd4\x8e\x00\x00\x48\x8b\x4c\x24\x38\x85\xc0\x75\x0f\x48\x63\x41\x08\x48\x3b\xe8\x72\x3a\x44\x38\x76\x01\x74\x34\x8b\x59\x08\xeb\x3d\x41\x8b\xc6\x48\x85\xff\x44\x8b\xcb\x4c\x8b\xc6\x0f\x95\xc0\xba\x09\x00\x00\x00\x89\x44\x24\x28\x48\x8b\x44\x24\x38\x48\x89\x7c\x24\x20\x8b\x48\x0c\xff\x15\x8c\x8e\x00\x00\x85\xc0\x75\x0e\xe8\x57\xf1\xff\xff\x83\xcb\xff\xc7\x00\x2a\x00\x00\x00\x44\x38\x74\x24\x48\x74\x0c\x48\x8b\x4c\x24\x30\x83\xa1\xa8\x03\x00\x00\xfd\x8b\xc3\xe9\xf7\xfe\xff\xff\x45\x33\xc9\xe9\xb0\xfe\xff\xff\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x18\x66\x44\x89\x4c\x24\x20\x57\x48\x83\xec\x60\x49\x8b\xf8\x48\x8b\xf2\x48\x8b\xd9\x48\x85\xd2\x75\x13\x4d\x85\xc0\x74\x0e\x48\x85\xc9\x74\x02\x21\x11\x33\xc0\xe9\x8f\x00\x00\x00\x48\x85\xc9\x74\x03\x83\x09\xff\x49\x81\xf8\xff\xff\xff\x7f\x76\x13\xe8\xe0\xf0\xff\xff\xbb\x16\x00\x00\x00\x89\x18\xe8\xb4\xef\xff\xff\xeb\x69\x48\x8b\x94\x24\x90\x00\x00\x00\x48\x8d\x4c\x24\x40\xe8\xac\xc7\xff\xff\x48\x8b\x44\x24\x48\x48\x83\xb8\x38\x01\x00\x00\x00\x75\x79\x0f\xb7\x84\x24\x88\x00\x00\x00\xb9\xff\x00\x00\x00\x66\x3b\xc1\x76\x4a\x48\x85\xf6\x74\x12\x48\x85\xff\x74\x0d\x4c\x8b\xc7\x33\xd2\x48\x8b\xce\xe8\x34\xb8\xff\xff\xe8\x83\xf0\xff\xff\xbb\x2a\x00\x00\x00\x89\x18\x80\x7c\x24\x58\x00\x74\x0c\x48\x8b\x4c\x24\x40\x83\xa1\xa8\x03\x00\x00\xfd\x8b\xc3\x4c\x8d\x5c\x24\x60\x49\x8b\x5b\x10\x49\x8b\x73\x20\x49\x8b\xe3\x5f\xc3\x48\x85\xf6\x74\x0b\x48\x85\xff\x0f\x84\x89\x00\x00\x00\x88\x06\x48\x85\xdb\x74\x55\xc7\x03\x01\x00\x00\x00\xeb\x4d\x83\x64\x24\x78\x00\x48\x8d\x4c\x24\x78\x48\x89\x4c\x24\x38\x4c\x8d\x84\x24\x88\x00\x00\x00\x48\x83\x64\x24\x30\x00\x41\xb9\x01\x00\x00\x00\x8b\x48\x0c\x33\xd2\x89\x7c\x24\x28\x48\x89\x74\x24\x20\xff\x15\x35\x8d\x00\x00\x85\xc0\x74\x19\x83\x7c\x24\x78\x00\x0f\x85\x6a\xff\xff\xff\x48\x85\xdb\x74\x02\x89\x03\x33\xdb\xe9\x68\xff\xff\xff\xff\x15\x72\x8d\x00\x00\x83\xf8\x7a\x0f\x85\x4d\xff\xff\xff\x48\x85\xf6\x74\x12\x48\x85\xff\x74\x0d\x4c\x8b\xc7\x33\xd2\x48\x8b\xce\xe8\x6a\xb7\xff\xff\xe8\xb9\xef\xff\xff\xbb\x22\x00\x00\x00\x89\x18\xe8\x8d\xee\xff\xff\xe9\x2c\xff\xff\xff\x48\x83\xec\x38\x48\x83\x64\x24\x20\x00\xe8\x6d\xfe\xff\xff\x48\x83\xc4\x38\xc3\x40\x55\x48\x83\xec\x20\x48\x8d\x6c\x24\x20\x48\x83\xe5\xe0\x8b\x05\x23\x2b\x01\x00\x4c\x8b\xc9\x83\xf8\x05\x0f\x8c\x8c\x00\x00\x00\x4c\x8b\xc1\xb8\x20\x00\x00\x00\x41\x83\xe0\x1f\x49\x2b\xc0\x49\xf7\xd8\x4d\x1b\xd2\x4c\x23\xd0\x49\x3b\xd2\x4c\x0f\x42\xd2\x49\x8d\x04\x0a\xeb\x08\x80\x39\x00\x74\x08\x48\xff\xc1\x48\x3b\xc8\x75\xf3\x49\x2b\xc9\x49\x3b\xca\x0f\x85\xf1\x00\x00\x00\x4c\x8b\xc2\x49\x03\xc9\x4d\x2b\xc2\x49\x8b\xc0\x83\xe0\x1f\x4c\x2b\xc0\x4c\x03\xc1\xc5\xec\x57\xd2\xeb\x10\xc5\xed\x74\x09\xc5\xfd\xd7\xc1\x85\xc0\x75\x09\x48\x83\xc1\x20\x49\x3b\xc8\x75\xeb\x49\x8d\x04\x11\xeb\x08\x80\x39\x00\x74\x08\x48\xff\xc1\x48\x3b\xc8\x75\xf3\x49\x2b\xc9\xc5\xf8\x77\xe9\xa3\x00\x00\x00\x83\xf8\x01\x0f\x8c\x84\x00\x00\x00\x83\xe1\x0f\xb8\x10\x00\x00\x00\x48\x2b\xc1\x48\xf7\xd9\x49\x8b\xc9\x4d\x1b\xd2\x4c\x23\xd0\x49\x3b\xd2\x4c\x0f\x42\xd2\x4b\x8d\x04\x0a\x4c\x3b\xc8\x74\x0d\x80\x39\x00\x74\x08\x48\xff\xc1\x48\x3b\xc8\x75\xf3\x49\x2b\xc9\x49\x3b\xca\x75\x5e\x4c\x8b\xc2\x49\x03\xc9\x4d\x2b\xc2\x0f\x57\xc9\x49\x8b\xc0\x83\xe0\x0f\x4c\x2b\xc0\x4c\x03\xc1\xeb\x14\x66\x0f\x6f\xc1\x66\x0f\x74\x01\x66\x0f\xd7\xc0\x85\xc0\x75\x09\x48\x83\xc1\x10\x49\x3b\xc8\x75\xe7\x49\x8d\x04\x11\xeb\x08\x80\x39\x00\x74\x1d\x48\xff\xc1\x48\x3b\xc8\x75\xf3\xeb\x13\x48\x8d\x04\x11\xeb\x08\x80\x39\x00\x74\x08\x48\xff\xc1\x48\x3b\xc8\x75\xf3\x49\x2b\xc9\x48\x8b\xc1\x48\x83\xc4\x20\x5d\xc3\xcc\xcc\xcc\x40\x55\x48\x83\xec\x20\x48\x8d\x6c\x24\x20\x48\x83\xe5\xe0\x8b\x05\xc7\x29\x01\x00\x4c\x8b\xd2\x4c\x8b\xc1\x83\xf8\x05\x0f\x8c\xd0\x00\x00\x00\xf6\xc1\x01\x74\x2b\x48\x8d\x04\x51\x48\x8b\xd1\x48\x3b\xc8\x0f\x84\xa8\x01\x00\x00\x45\x33\xc9\x66\x44\x39\x0a\x0f\x84\x9b\x01\x00\x00\x48\x83\xc2\x02\x48\x3b\xd0\x75\xed\xe9\x8d\x01\x00\x00\x83\xe1\x1f\xb8\x20\x00\x00\x00\x48\x2b\xc1\x48\xf7\xd9\x4d\x1b\xdb\x4c\x23\xd8\x49\xd1\xeb\x49\x3b\xd3\x4c\x0f\x42\xda\x45\x33\xc9\x49\x8b\xd0\x4b\x8d\x04\x58\x4c\x3b\xc0\x74\x0f\x66\x44\x39\x0a\x74\x09\x48\x83\xc2\x02\x48\x3b\xd0\x75\xf1\x49\x2b\xd0\x48\xd1\xfa\x49\x3b\xd3\x0f\x85\x48\x01\x00\x00\x49\x8b\xca\x49\x8d\x14\x50\x49\x2b\xcb\x48\x8b\xc1\x83\xe0\x1f\x48\x2b\xc8\xc5\xec\x57\xd2\x4c\x8d\x1c\x4a\xeb\x10\xc5\xed\x75\x0a\xc5\xfd\xd7\xc1\x85\xc0\x75\x09\x48\x83\xc2\x20\x49\x3b\xd3\x75\xeb\x4b\x8d\x04\x50\xeb\x0a\x66\x44\x39\x0a\x74\x09\x48\x83\xc2\x02\x48\x3b\xd0\x75\xf1\x49\x2b\xd0\x48\xd1\xfa\xc5\xf8\x77\xe9\xf3\x00\x00\x00\x83\xf8\x01\x0f\x8c\xc6\x00\x00\x00\xf6\xc1\x01\x74\x2b\x48\x8d\x04\x51\x48\x8b\xd1\x48\x3b\xc8\x0f\x84\xcf\x00\x00\x00\x45\x33\xc9\x66\x44\x39\x0a\x0f\x84\xc2\x00\x00\x00\x48\x83\xc2\x02\x48\x3b\xd0\x75\xed\xe9\xb4\x00\x00\x00\x83\xe1\x0f\xb8\x10\x00\x00\x00\x48\x2b\xc1\x48\xf7\xd9\x4d\x1b\xdb\x4c\x23\xd8\x49\xd1\xeb\x49\x3b\xd3\x4c\x0f\x42\xda\x45\x33\xc9\x49\x8b\xd0\x4b\x8d\x04\x58\x4c\x3b\xc0\x74\x0f\x66\x44\x39\x0a\x74\x09\x48\x83\xc2\x02\x48\x3b\xd0\x75\xf1\x49\x2b\xd0\x48\xd1\xfa\x49\x3b\xd3\x75\x73\x49\x8b\xca\x49\x8d\x14\x50\x49\x2b\xcb\x0f\x57\xc9\x48\x8b\xc1\x83\xe0\x0f\x48\x2b\xc8\x4c\x8d\x1c\x4a\xeb\x14\x66\x0f\x6f\xc1\x66\x0f\x75\x02\x66\x0f\xd7\xc0\x85\xc0\x75\x09\x48\x83\xc2\x10\x49\x3b\xd3\x75\xe7\x4b\x8d\x04\x50\xeb\x0a\x66\x44\x39\x0a\x74\x09\x48\x83\xc2\x02\x48\x3b\xd0\x75\xf1\x49\x2b\xd0\xeb\x21\x48\x8d\x04\x51\x48\x8b\xd1\x48\x3b\xc8\x74\x12\x45\x33\xc9\x66\x44\x39\x0a\x74\x09\x48\x83\xc2\x02\x48\x3b\xd0\x75\xf1\x48\x2b\xd1\x48\xd1\xfa\x48\x8b\xc2\x48\x83\xc4\x20\x5d\xc3\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xd9\x49\x8b\xf8\x8b\x0a\xe8\x18\x14\x00\x00\x90\x48\x8b\x07\x48\x8b\x08\x48\x8b\x89\x88\x00\x00\x00\x48\x85\xc9\x74\x1e\x83\xc8\xff\xf0\x0f\xc1\x01\x83\xf8\x01\x75\x12\x48\x8d\x05\x02\x2b\x01\x00\x48\x3b\xc8\x74\x06\xe8\xc0\xe3\xff\xff\x90\x8b\x0b\xe8\x34\x14\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xd9\x49\x8b\xf8\x8b\x0a\xe8\xb8\x13\x00\x00\x90\x48\x8b\x47\x08\x48\x8b\x10\x48\x8b\x0f\x48\x8b\x12\x48\x8b\x09\xe8\x7e\x02\x00\x00\x90\x8b\x0b\xe8\xee\x13\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xd9\x49\x8b\xf8\x8b\x0a\xe8\x70\x13\x00\x00\x90\x48\x8b\x07\x48\x8b\x08\x48\x8b\x81\x88\x00\x00\x00\xf0\xff\x00\x8b\x0b\xe8\xac\x13\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xd9\x49\x8b\xf8\x8b\x0a\xe8\x30\x13\x00\x00\x90\x48\x8b\x0f\x33\xd2\x48\x8b\x09\xe8\xfe\x01\x00\x00\x90\x8b\x0b\xe8\x6e\x13\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x40\x55\x48\x8b\xec\x48\x83\xec\x50\x48\x89\x4d\xd8\x48\x8d\x45\xd8\x48\x89\x45\xe8\x4c\x8d\x4d\x20\xba\x01\x00\x00\x00\x4c\x8d\x45\xe8\xb8\x05\x00\x00\x00\x89\x45\x20\x89\x45\x28\x48\x8d\x45\xd8\x48\x89\x45\xf0\x48\x8d\x45\xe0\x48\x89\x45\xf8\xb8\x04\x00\x00\x00\x89\x45\xd0\x89\x45\xd4\x48\x8d\x05\xc5\x3d\x01\x00\x48\x89\x45\xe0\x89\x51\x28\x48\x8d\x0d\xaf\x95\x00\x00\x48\x8b\x45\xd8\x48\x89\x08\x48\x8d\x0d\xb1\x29\x01\x00\x48\x8b\x45\xd8\x89\x90\xa8\x03\x00\x00\x48\x8b\x45\xd8\x48\x89\x88\x88\x00\x00\x00\x8d\x4a\x42\x48\x8b\x45\xd8\x48\x8d\x55\x28\x66\x89\x88\xbc\x00\x00\x00\x48\x8b\x45\xd8\x66\x89\x88\xc2\x01\x00\x00\x48\x8d\x4d\x18\x48\x8b\x45\xd8\x48\x83\xa0\xa0\x03\x00\x00\x00\xe8\xce\xfe\xff\xff\x4c\x8d\x4d\xd0\x4c\x8d\x45\xf0\x48\x8d\x55\xd4\x48\x8d\x4d\x18\xe8\x71\xfe\xff\xff\x48\x83\xc4\x50\x5d\xc3\xcc\xcc\xcc\x48\x85\xc9\x74\x1a\x53\x48\x83\xec\x20\x48\x8b\xd9\xe8\x0e\x00\x00\x00\x48\x8b\xcb\xe8\xfa\xe1\xff\xff\x48\x83\xc4\x20\x5b\xc3\x40\x55\x48\x8b\xec\x48\x83\xec\x40\x48\x8d\x45\xe8\x48\x89\x4d\xe8\x48\x89\x45\xf0\x48\x8d\x15\x00\x95\x00\x00\xb8\x05\x00\x00\x00\x89\x45\x20\x89\x45\x28\x48\x8d\x45\xe8\x48\x89\x45\xf8\xb8\x04\x00\x00\x00\x89\x45\xe0\x89\x45\xe4\x48\x8b\x01\x48\x3b\xc2\x74\x0c\x48\x8b\xc8\xe8\xaa\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x49\x70\xe8\x9d\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x49\x58\xe8\x90\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x49\x60\xe8\x83\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x49\x68\xe8\x76\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x49\x48\xe8\x69\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x49\x50\xe8\x5c\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x49\x78\xe8\x4f\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x89\x80\x00\x00\x00\xe8\x3f\xe1\xff\xff\x48\x8b\x4d\xe8\x48\x8b\x89\xc0\x03\x00\x00\xe8\x2f\xe1\xff\xff\x4c\x8d\x4d\x20\x4c\x8d\x45\xf0\x48\x8d\x55\x28\x48\x8d\x4d\x18\xe8\x0e\xfd\xff\xff\x4c\x8d\x4d\xe0\x4c\x8d\x45\xf8\x48\x8d\x55\xe4\x48\x8d\x4d\x18\xe8\xe1\xfd\xff\xff\x48\x83\xc4\x40\x5d\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xf9\x48\x8b\xda\x48\x8b\x89\x90\x00\x00\x00\x48\x85\xc9\x74\x2c\xe8\x97\x3a\x00\x00\x48\x8b\x8f\x90\x00\x00\x00\x48\x3b\x0d\xfd\x3b\x01\x00\x74\x17\x48\x8d\x05\x8c\x26\x01\x00\x48\x3b\xc8\x74\x0b\x83\x79\x10\x00\x75\x05\xe8\x70\x38\x00\x00\x48\x89\x9f\x90\x00\x00\x00\x48\x85\xdb\x74\x08\x48\x8b\xcb\xe8\xd0\x37\x00\x00\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\x40\x53\x48\x83\xec\x20\x8b\x0d\x40\x26\x01\x00\x83\xf9\xff\x74\x2a\xe8\x2a\xeb\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x1d\x8b\x0d\x28\x26\x01\x00\x33\xd2\xe8\x6d\xeb\xff\xff\x48\x8b\xcb\xe8\x6d\xfe\xff\xff\x48\x8b\xcb\xe8\x59\xe0\xff\xff\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\xff\x15\x10\x86\x00\x00\x8b\x0d\xf2\x25\x01\x00\x8b\xd8\x83\xf9\xff\x74\x0d\xe8\xda\xea\xff\xff\x48\x8b\xf8\x48\x85\xc0\x75\x41\xba\xc8\x03\x00\x00\xb9\x01\x00\x00\x00\xe8\x6f\xe1\xff\xff\x48\x8b\xf8\x48\x85\xc0\x75\x09\x33\xc9\xe8\x08\xe0\xff\xff\xeb\x3c\x8b\x0d\xb8\x25\x01\x00\x48\x8b\xd0\xe8\xfc\xea\xff\xff\x48\x8b\xcf\x85\xc0\x74\xe4\xe8\x08\xfd\xff\xff\x33\xc9\xe8\xe5\xdf\xff\xff\x48\x85\xff\x74\x16\x8b\xcb\xff\x15\x10\x85\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\xc7\x48\x83\xc4\x20\x5f\xc3\x8b\xcb\xff\x15\xfa\x84\x00\x00\xe8\xbd\xe0\xff\xff\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\xff\x15\x77\x85\x00\x00\x8b\x0d\x59\x25\x01\x00\x33\xf6\x8b\xd8\x83\xf9\xff\x74\x0d\xe8\x3f\xea\xff\xff\x48\x8b\xf8\x48\x85\xc0\x75\x41\xba\xc8\x03\x00\x00\xb9\x01\x00\x00\x00\xe8\xd4\xe0\xff\xff\x48\x8b\xf8\x48\x85\xc0\x75\x09\x33\xc9\xe8\x6d\xdf\xff\xff\xeb\x26\x8b\x0d\x1d\x25\x01\x00\x48\x8b\xd0\xe8\x61\xea\xff\xff\x48\x8b\xcf\x85\xc0\x74\xe4\xe8\x6d\xfc\xff\xff\x33\xc9\xe8\x4a\xdf\xff\xff\x48\x85\xff\x75\x0a\x8b\xcb\xff\x15\x75\x84\x00\x00\xeb\x0b\x8b\xcb\xff\x15\x6b\x84\x00\x00\x48\x8b\xf7\x48\x8b\x5c\x24\x30\x48\x8b\xc6\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x83\xec\x28\x48\x8d\x0d\xfd\xfc\xff\xff\xe8\x08\xe9\xff\xff\x89\x05\xbe\x24\x01\x00\x83\xf8\xff\x75\x04\x32\xc0\xeb\x15\xe8\x3c\xff\xff\xff\x48\x85\xc0\x75\x09\x33\xc9\xe8\x0c\x00\x00\x00\xeb\xe9\xb0\x01\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\x48\x83\xec\x28\x8b\x0d\x8e\x24\x01\x00\x83\xf9\xff\x74\x0c\xe8\x20\xe9\xff\xff\x83\x0d\x7d\x24\x01\x00\xff\xb0\x01\x48\x83\xc4\x28\xc3\xcc\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\x05\xdf\x39\x01\x00\x48\x8b\xda\x48\x39\x02\x74\x16\x8b\x81\xa8\x03\x00\x00\x85\x05\x13\x2b\x01\x00\x75\x08\xe8\xf8\x38\x00\x00\x48\x89\x03\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\x05\xdb\x27\x01\x00\x48\x8b\xda\x48\x39\x02\x74\x16\x8b\x81\xa8\x03\x00\x00\x85\x05\xdf\x2a\x01\x00\x75\x08\xe8\x1c\x16\x00\x00\x48\x89\x03\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x48\x8b\x11\xb9\xff\x07\x00\x00\x48\x8b\xc2\x48\xc1\xe8\x34\x48\x23\xc1\x48\x3b\xc1\x74\x03\x33\xc0\xc3\x48\xb9\xff\xff\xff\xff\xff\xff\x0f\x00\x48\x8b\xc2\x48\x23\xc1\x75\x06\xb8\x01\x00\x00\x00\xc3\x48\xb9\x00\x00\x00\x00\x00\x00\x00\x80\x48\x85\xd1\x74\x15\x48\xb9\x00\x00\x00\x00\x00\x00\x08\x00\x48\x3b\xc1\x75\x06\xb8\x04\x00\x00\x00\xc3\x48\xc1\xea\x33\xf7\xd2\x83\xe2\x01\x83\xca\x02\x8b\xc2\xc3\xcc\xcc\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x54\x41\x56\x41\x57\x48\x83\xec\x70\x8b\x9c\x24\xb8\x00\x00\x00\x45\x33\xe4\x48\x8b\xfa\x44\x88\x22\x48\x8b\x94\x24\xd0\x00\x00\x00\x48\x8b\xf1\x85\xdb\x48\x8d\x48\xc8\x4d\x8b\xf1\x49\x8b\xe8\x41\x0f\x48\xdc\xe8\xc7\xbc\xff\xff\x8d\x43\x0b\x48\x63\xd0\x48\x3b\xea\x77\x16\xe8\xcb\xe5\xff\xff\x41\x8d\x5c\x24\x22\x89\x18\xe8\x9f\xe4\xff\xff\xe9\xbb\x02\x00\x00\x48\x8b\x06\xb9\xff\x07\x00\x00\x48\xc1\xe8\x34\x48\x23\xc1\x48\x3b\xc1\x75\x77\x8b\x84\x24\xc8\x00\x00\x00\x4d\x8b\xce\x4c\x89\x64\x24\x40\x4c\x8b\xc5\x89\x44\x24\x38\x48\x8b\xd7\x48\x8b\x84\x24\xb0\x00\x00\x00\x48\x8b\xce\x44\x88\x64\x24\x30\x89\x5c\x24\x28\x48\x89\x44\x24\x20\xe8\xa7\x02\x00\x00\x8b\xd8\x85\xc0\x74\x08\x44\x88\x27\xe9\x62\x02\x00\x00\xba\x65\x00\x00\x00\x48\x8b\xcf\xe8\xc8\x77\x00\x00\x48\x85\xc0\x0f\x84\x49\x02\x00\x00\x8a\x8c\x24\xc0\x00\x00\x00\xf6\xd9\x1a\xd2\x80\xe2\xe0\x80\xc2\x70\x88\x10\x44\x88\x60\x03\xe9\x2d\x02\x00\x00\x48\xb8\x00\x00\x00\x00\x00\x00\x00\x80\x48\x85\x06\x74\x06\xc6\x07\x2d\x48\xff\xc7\x44\x8a\xbc\x24\xc0\x00\x00\x00\xbd\xff\x03\x00\x00\x41\x8a\xc7\x41\xba\x30\x00\x00\x00\xf6\xd8\x49\xbb\xff\xff\xff\xff\xff\xff\x0f\x00\x48\xb8\x00\x00\x00\x00\x00\x00\xf0\x7f\x1b\xd2\x83\xe2\xe0\x83\xea\xd9\x48\x85\x06\x75\x1a\x44\x88\x17\x48\xff\xc7\x48\x8b\x06\x49\x23\xc3\x48\xf7\xd8\x48\x1b\xed\x81\xe5\xfe\x03\x00\x00\xeb\x06\xc6\x07\x31\x48\xff\xc7\x4c\x8b\xf7\x48\xff\xc7\x85\xdb\x75\x05\x45\x88\x26\xeb\x14\x48\x8b\x44\x24\x58\x48\x8b\x88\xf8\x00\x00\x00\x48\x8b\x01\x8a\x08\x41\x88\x0e\x4c\x85\x1e\x0f\x86\x8a\x00\x00\x00\x45\x0f\xb7\xc2\x49\xb9\x00\x00\x00\x00\x00\x00\x0f\x00\x85\xdb\x7e\x2e\x48\x8b\x06\x41\x8a\xc8\x49\x23\xc1\x49\x23\xc3\x48\xd3\xe8\x66\x41\x03\xc2\x66\x83\xf8\x39\x76\x03\x66\x03\xc2\x88\x07\xff\xcb\x48\xff\xc7\x49\xc1\xe9\x04\x66\x41\x83\xc0\xfc\x79\xce\x66\x45\x85\xc0\x78\x44\x48\x8b\x06\x41\x8a\xc8\x49\x23\xc1\x49\x23\xc3\x48\xd3\xe8\x66\x83\xf8\x08\x76\x2f\x48\x8d\x4f\xff\x8a\x01\x2c\x46\xa8\xdf\x75\x08\x44\x88\x11\x48\xff\xc9\xeb\xf0\x49\x3b\xce\x74\x13\x8a\x01\x3c\x39\x75\x07\x80\xc2\x3a\x88\x11\xeb\x09\xfe\xc0\x88\x01\xeb\x03\xfe\x41\xff\x85\xdb\x7e\x17\x4c\x8b\xc3\x41\x8a\xd2\x48\x8b\xcf\xe8\xa5\xab\xff\xff\x48\x03\xfb\x41\xba\x30\x00\x00\x00\x45\x38\x26\x49\x0f\x44\xfe\x41\xf6\xdf\x1a\xc0\x24\xe0\x04\x70\x88\x07\x48\x8b\x0e\x48\xc1\xe9\x34\x81\xe1\xff\x07\x00\x00\x48\x2b\xcd\x78\x0a\xc6\x47\x01\x2b\x48\x83\xc7\x02\xeb\x0b\xc6\x47\x01\x2d\x48\x83\xc7\x02\x48\xf7\xd9\x44\x88\x17\x4c\x8b\xc7\x48\x81\xf9\xe8\x03\x00\x00\x7c\x33\x48\xb8\xcf\xf7\x53\xe3\xa5\x9b\xc4\x20\x48\xf7\xe9\x48\xc1\xfa\x07\x48\x8b\xc2\x48\xc1\xe8\x3f\x48\x03\xd0\x41\x8d\x04\x12\x88\x07\x48\xff\xc7\x48\x69\xc2\x18\xfc\xff\xff\x48\x03\xc8\x49\x3b\xf8\x75\x06\x48\x83\xf9\x64\x7c\x2e\x48\xb8\x0b\xd7\xa3\x70\x3d\x0a\xd7\xa3\x48\xf7\xe9\x48\x03\xd1\x48\xc1\xfa\x06\x48\x8b\xc2\x48\xc1\xe8\x3f\x48\x03\xd0\x41\x8d\x04\x12\x88\x07\x48\xff\xc7\x48\x6b\xc2\x9c\x48\x03\xc8\x49\x3b\xf8\x75\x06\x48\x83\xf9\x0a\x7c\x2b\x48\xb8\x67\x66\x66\x66\x66\x66\x66\x66\x48\xf7\xe9\x48\xc1\xfa\x02\x48\x8b\xc2\x48\xc1\xe8\x3f\x48\x03\xd0\x41\x8d\x04\x12\x88\x07\x48\xff\xc7\x48\x6b\xc2\xf6\x48\x03\xc8\x41\x02\xca\x88\x0f\x44\x88\x67\x01\x41\x8b\xdc\x44\x38\x64\x24\x68\x74\x0c\x48\x8b\x4c\x24\x50\x83\xa1\xa8\x03\x00\x00\xfd\x4c\x8d\x5c\x24\x70\x8b\xc3\x49\x8b\x5b\x20\x49\x8b\x6b\x28\x49\x8b\x73\x30\x49\x8b\x7b\x38\x49\x8b\xe3\x41\x5f\x41\x5e\x41\x5c\xc3\xcc\xcc\xcc\x4c\x8b\xdc\x49\x89\x5b\x08\x49\x89\x6b\x10\x49\x89\x73\x18\x57\x48\x83\xec\x50\x48\x8b\x84\x24\x80\x00\x00\x00\x49\x8b\xf0\x8b\xac\x24\x88\x00\x00\x00\x4d\x8d\x43\xe8\x48\x8b\x09\x48\x8b\xfa\x49\x89\x43\xc8\x8d\x55\x01\xe8\x28\x3b\x00\x00\x33\xc9\x4c\x8d\x4c\x24\x40\x83\x7c\x24\x40\x2d\x44\x8d\x45\x01\x48\x8b\xd6\x0f\x94\xc1\x33\xc0\x85\xed\x0f\x9f\xc0\x48\x2b\xd0\x48\x2b\xd1\x48\x83\xfe\xff\x48\x0f\x44\xd6\x48\x03\xc8\x48\x03\xcf\xe8\x56\x35\x00\x00\x85\xc0\x74\x05\xc6\x07\x00\xeb\x3d\x48\x8b\x84\x24\xa0\x00\x00\x00\x44\x8b\xc5\x44\x8a\x8c\x24\x90\x00\x00\x00\x48\x8b\xd6\x48\x89\x44\x24\x38\x48\x8b\xcf\x48\x8d\x44\x24\x40\xc6\x44\x24\x30\x00\x48\x89\x44\x24\x28\x8b\x84\x24\x98\x00\x00\x00\x89\x44\x24\x20\xe8\x18\x00\x00\x00\x48\x8b\x5c\x24\x60\x48\x8b\x6c\x24\x68\x48\x8b\x74\x24\x70\x48\x83\xc4\x50\x5f\xc3\xcc\xcc\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x57\x48\x83\xec\x50\x33\xc0\x49\x63\xd8\x45\x85\xc0\x45\x8a\xf9\x48\x8b\xea\x48\x8b\xf9\x0f\x4f\xc3\x83\xc0\x09\x48\x98\x48\x3b\xd0\x77\x2e\xe8\xbc\xe1\xff\xff\xbb\x22\x00\x00\x00\x89\x18\xe8\x90\xe0\xff\xff\x8b\xc3\x48\x8b\x5c\x24\x60\x48\x8b\x6c\x24\x68\x48\x8b\x74\x24\x70\x48\x8b\x7c\x24\x78\x48\x83\xc4\x50\x41\x5f\xc3\x48\x8b\x94\x24\x98\x00\x00\x00\x48\x8d\x4c\x24\x30\xe8\x6d\xb8\xff\xff\x80\xbc\x24\x90\x00\x00\x00\x00\x48\x8b\xb4\x24\x88\x00\x00\x00\x74\x32\x33\xd2\x83\x3e\x2d\x0f\x94\xc2\x33\xc0\x48\x03\xd7\x85\xdb\x0f\x9f\xc0\x85\xc0\x74\x1c\x49\x83\xc8\xff\x49\xff\xc0\x42\x80\x3c\x02\x00\x75\xf6\x48\x63\xc8\x49\xff\xc0\x48\x03\xca\xe8\x79\x6f\x00\x00\x83\x3e\x2d\x48\x8b\xd7\x75\x07\xc6\x07\x2d\x48\x8d\x57\x01\x85\xdb\x7e\x1b\x8a\x42\x01\x88\x02\x48\xff\xc2\x48\x8b\x44\x24\x38\x48\x8b\x88\xf8\x00\x00\x00\x48\x8b\x01\x8a\x08\x88\x0a\x33\xc9\x4c\x8d\x05\x4e\x95\x00\x00\x38\x8c\x24\x90\x00\x00\x00\x0f\x94\xc1\x48\x03\xda\x48\x03\xd9\x48\x2b\xfb\x48\x8b\xcb\x48\x83\xfd\xff\x48\x8d\x14\x2f\x48\x0f\x44\xd5\xe8\x43\xd9\xff\xff\x85\xc0\x0f\x85\xa4\x00\x00\x00\x48\x8d\x4b\x02\x45\x84\xff\x74\x03\xc6\x03\x45\x48\x8b\x46\x08\x80\x38\x30\x74\x57\x44\x8b\x46\x04\x41\x83\xe8\x01\x79\x07\x41\xf7\xd8\xc6\x43\x01\x2d\x41\x83\xf8\x64\x7c\x1b\xb8\x1f\x85\xeb\x51\x41\xf7\xe8\xc1\xfa\x05\x8b\xc2\xc1\xe8\x1f\x03\xd0\x00\x53\x02\x6b\xc2\x9c\x44\x03\xc0\x41\x83\xf8\x0a\x7c\x1b\xb8\x67\x66\x66\x66\x41\xf7\xe8\xc1\xfa\x02\x8b\xc2\xc1\xe8\x1f\x03\xd0\x00\x53\x03\x6b\xc2\xf6\x44\x03\xc0\x44\x00\x43\x04\x83\xbc\x24\x80\x00\x00\x00\x02\x75\x14\x80\x39\x30\x75\x0f\x48\x8d\x51\x01\x41\xb8\x03\x00\x00\x00\xe8\x89\x6e\x00\x00\x80\x7c\x24\x48\x00\x74\x0c\x48\x8b\x44\x24\x30\x83\xa0\xa8\x03\x00\x00\xfd\x33\xc0\xe9\x85\xfe\xff\xff\x48\x83\x64\x24\x20\x00\x45\x33\xc9\x45\x33\xc0\x33\xd2\x33\xc9\xe8\x1e\xdf\xff\xff\xcc\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x40\x48\x8b\x54\x24\x78\x48\x8b\xd9\x48\x8d\x48\xd8\x4d\x8b\xf1\x41\x8b\xf8\xe8\xd8\xb6\xff\xff\x41\x8b\x4e\x04\xff\xc9\x80\x7c\x24\x70\x00\x74\x19\x3b\xcf\x75\x15\x33\xc0\x48\x63\xc9\x41\x83\x3e\x2d\x0f\x94\xc0\x48\x03\xc3\x66\xc7\x04\x01\x30\x00\x41\x83\x3e\x2d\x75\x06\xc6\x03\x2d\x48\xff\xc3\x48\x83\xce\xff\x41\x83\x7e\x04\x00\x7f\x24\x4c\x8b\xc6\x49\xff\xc0\x42\x80\x3c\x03\x00\x75\xf6\x49\xff\xc0\x48\x8d\x4b\x01\x48\x8b\xd3\xe8\xcf\x6d\x00\x00\xc6\x03\x30\x48\xff\xc3\xeb\x07\x49\x63\x46\x04\x48\x03\xd8\x85\xff\x7e\x7c\x48\x8d\x6b\x01\x4c\x8b\xc6\x49\xff\xc0\x42\x80\x3c\x03\x00\x75\xf6\x49\xff\xc0\x48\x8b\xd3\x48\x8b\xcd\xe8\x9d\x6d\x00\x00\x48\x8b\x44\x24\x28\x48\x8b\x88\xf8\x00\x00\x00\x48\x8b\x01\x8a\x08\x88\x0b\x41\x8b\x4e\x04\x85\xc9\x79\x42\x80\x7c\x24\x70\x00\x75\x08\x8b\xc1\xf7\xd8\x3b\xc7\x7d\x04\x8b\xf9\xf7\xdf\x85\xff\x74\x1b\x48\xff\xc6\x80\x3c\x2e\x00\x75\xf7\x48\x63\xcf\x4c\x8d\x46\x01\x48\x03\xcd\x48\x8b\xd5\xe8\x50\x6d\x00\x00\x4c\x63\xc7\xba\x30\x00\x00\x00\x48\x8b\xcd\xe8\xb0\xa6\xff\xff\x80\x7c\x24\x38\x00\x74\x0c\x48\x8b\x44\x24\x20\x83\xa0\xa8\x03\x00\x00\xfd\x48\x8b\x5c\x24\x50\x33\xc0\x48\x8b\x6c\x24\x58\x48\x8b\x74\x24\x60\x48\x8b\x7c\x24\x68\x48\x83\xc4\x40\x41\x5e\xc3\x4c\x8b\xdc\x49\x89\x5b\x08\x49\x89\x6b\x10\x49\x89\x73\x18\x41\x56\x48\x83\xec\x50\x48\x8b\x09\x33\xc0\x49\x89\x43\xe8\x49\x8b\xe8\x49\x89\x43\xf0\x4d\x8d\x43\xe8\x48\x8b\x84\x24\x80\x00\x00\x00\x48\x8b\xf2\x8b\x94\x24\x88\x00\x00\x00\x49\x89\x43\xc8\xe8\x2c\x37\x00\x00\x44\x8b\x74\x24\x44\x4c\x8d\x4c\x24\x40\x44\x8b\x84\x24\x88\x00\x00\x00\x33\xc9\x83\x7c\x24\x40\x2d\x48\x8b\xd5\x0f\x94\xc1\x41\xff\xce\x48\x2b\xd1\x48\x83\xfd\xff\x48\x8d\x1c\x31\x48\x0f\x44\xd5\x48\x8b\xcb\xe8\x57\x31\x00\x00\x85\xc0\x74\x08\xc6\x06\x00\xe9\x98\x00\x00\x00\x8b\x44\x24\x44\xff\xc8\x44\x3b\xf0\x0f\x9c\xc1\x83\xf8\xfc\x7c\x45\x3b\x84\x24\x88\x00\x00\x00\x7d\x3c\x84\xc9\x74\x0c\x8a\x03\x48\xff\xc3\x84\xc0\x75\xf7\x88\x43\xfe\x48\x8b\x84\x24\xa0\x00\x00\x00\x4c\x8d\x4c\x24\x40\x44\x8b\x84\x24\x88\x00\x00\x00\x48\x8b\xd5\x48\x89\x44\x24\x28\x48\x8b\xce\xc6\x44\x24\x20\x01\xe8\xdb\xfd\xff\xff\xeb\x42\x48\x8b\x84\x24\xa0\x00\x00\x00\x48\x8b\xd5\x44\x8a\x8c\x24\x90\x00\x00\x00\x48\x8b\xce\x44\x8b\x84\x24\x88\x00\x00\x00\x48\x89\x44\x24\x38\x48\x8d\x44\x24\x40\xc6\x44\x24\x30\x01\x48\x89\x44\x24\x28\x8b\x84\x24\x98\x00\x00\x00\x89\x44\x24\x20\xe8\xbb\xfb\xff\xff\x48\x8b\x5c\x24\x60\x48\x8b\x6c\x24\x68\x48\x8b\x74\x24\x70\x48\x83\xc4\x50\x41\x5e\xc3\xcc\x40\x55\x48\x8d\x6c\x24\xb1\x48\x81\xec\xc0\x00\x00\x00\x48\x8b\x05\x13\x19\x01\x00\x48\x33\xc4\x48\x89\x45\x3f\x4d\x8b\xd1\x0f\xb6\xc2\x48\x83\xc0\x04\x4d\x8b\xc8\x4c\x3b\xd0\x73\x1e\x41\xc6\x00\x00\xb8\x0c\x00\x00\x00\x48\x8b\x4d\x3f\x48\x33\xcc\xe8\x15\x92\xff\xff\x48\x81\xc4\xc0\x00\x00\x00\x5d\xc3\x84\xd2\x74\x0e\x49\xff\xc1\x41\xc6\x00\x2d\x49\xff\xca\x41\xc6\x01\x00\xf6\x5d\x7f\x48\x8d\x15\x34\x91\x00\x00\x4c\x8d\x05\x31\x91\x00\x00\x48\x89\x55\xdf\x48\x8d\x05\x1a\x91\x00\x00\x48\x89\x55\xe7\x48\x89\x45\xbf\x48\x89\x45\xc7\x48\x8d\x05\x0b\x91\x00\x00\x48\x89\x45\xcf\x48\x89\x45\xd7\x48\x8d\x05\x0c\x91\x00\x00\x48\x89\x45\xff\x48\x8d\x05\x11\x91\x00\x00\x48\x89\x45\x0f\x48\x8d\x05\x16\x91\x00\x00\x48\x89\x45\x1f\x48\x8d\x05\x1b\x91\x00\x00\x48\x89\x45\x2f\x48\x89\x55\x07\x48\x89\x55\x27\x8d\x51\xff\x1b\xc9\x4c\x89\x45\xef\x48\xc1\xe2\x02\xf7\xd1\x83\xe1\x02\x4c\x89\x45\xf7\x8b\xc1\x48\x03\xc2\x4c\x89\x45\x17\x4c\x89\x45\x37\x4c\x8b\x44\xc5\xbf\x48\x83\xc8\xff\x48\xff\xc0\x41\x80\x3c\x00\x00\x75\xf6\x4c\x3b\xd0\x0f\x97\xc0\x45\x33\xc0\x84\xc0\x41\x0f\x94\xc0\x44\x03\xc1\x49\x8b\xc9\x4c\x03\xc2\x49\x8b\xd2\x4e\x8b\x44\xc5\xbf\xe8\xdc\xd4\xff\xff\x85\xc0\x0f\x84\x0b\xff\xff\xff\x48\x83\x64\x24\x20\x00\x45\x33\xc9\x45\x33\xc0\x33\xd2\x33\xc9\xe8\x5b\xdb\xff\xff\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x60\x4d\x8b\xe9\x49\x8b\xe8\x48\x8b\xf2\x4c\x8b\xf9\x48\x85\xd2\x75\x18\xe8\x26\xdc\xff\xff\xbb\x16\x00\x00\x00\x89\x18\xe8\xfa\xda\xff\xff\x8b\xc3\xe9\xde\x01\x00\x00\x4d\x85\xc0\x74\xe3\x4d\x85\xc9\x74\xde\x4c\x8b\xa4\x24\xb0\x00\x00\x00\x4d\x85\xe4\x74\xd1\x8b\x9c\x24\xb8\x00\x00\x00\x83\xfb\x41\x74\x0d\x8d\x43\xbb\x83\xf8\x02\x76\x05\x45\x32\xf6\xeb\x03\x41\xb6\x01\x48\x8b\xbc\x24\xc8\x00\x00\x00\x40\xf6\xc7\x08\x75\x2a\xe8\x3d\xf5\xff\xff\x85\xc0\x74\x21\x49\x8b\x17\x4c\x8b\xcd\x48\xc1\xea\x3f\x4c\x8b\xc6\x80\xe2\x01\x44\x88\x74\x24\x20\x8b\xc8\xe8\x11\xfe\xff\xff\xe9\x73\x01\x00\x00\x48\xc1\xef\x04\x83\xe7\x01\x83\xcf\x02\x83\xeb\x41\x0f\x84\x29\x01\x00\x00\x83\xeb\x04\x0f\x84\xe7\x00\x00\x00\x83\xeb\x01\x74\x58\x83\xeb\x01\x74\x17\x83\xeb\x1a\x0f\x84\x0d\x01\x00\x00\x83\xeb\x04\x0f\x84\xcb\x00\x00\x00\x83\xfb\x01\x74\x3c\x48\x8b\x84\x24\xd0\x00\x00\x00\x4d\x8b\xcd\x48\x89\x44\x24\x40\x4c\x8b\xc5\x8b\x84\x24\xc0\x00\x00\x00\x48\x8b\xd6\x89\x7c\x24\x38\x49\x8b\xcf\x44\x88\x74\x24\x30\x89\x44\x24\x28\x4c\x89\x64\x24\x20\xe8\x60\xfc\xff\xff\xe9\xfa\x00\x00\x00\x8b\x9c\x24\xc0\x00\x00\x00\x4c\x8d\x44\x24\x50\x49\x8b\x0f\x33\xc0\x8b\xd3\x48\x89\x44\x24\x50\x4d\x8b\xcd\x48\x89\x44\x24\x58\x4c\x89\x64\x24\x20\xe8\xa1\x33\x00\x00\x44\x8b\x44\x24\x54\x4c\x8d\x4c\x24\x50\x33\xc9\x48\x8b\xd5\x83\x7c\x24\x50\x2d\x0f\x94\xc1\x44\x03\xc3\x48\x2b\xd1\x48\x83\xfd\xff\x48\x0f\x44\xd5\x48\x03\xce\xe8\xd8\x2d\x00\x00\x85\xc0\x74\x08\xc6\x06\x00\xe9\x97\x00\x00\x00\x48\x8b\x84\x24\xd0\x00\x00\x00\x4c\x8d\x4c\x24\x50\x48\x89\x44\x24\x28\x44\x8b\xc3\x48\x8b\xd5\xc6\x44\x24\x20\x00\x48\x8b\xce\xe8\x8b\xfa\xff\xff\xeb\x70\x48\x8b\x84\x24\xd0\x00\x00\x00\x4d\x8b\xcd\x48\x89\x44\x24\x40\x4c\x8b\xc5\x8b\x84\x24\xc0\x00\x00\x00\x48\x8b\xd6\x89\x7c\x24\x38\x49\x8b\xcf\x44\x88\x74\x24\x30\x89\x44\x24\x28\x4c\x89\x64\x24\x20\xe8\xa6\xf7\xff\xff\xeb\x37\x48\x8b\x84\x24\xd0\x00\x00\x00\x4d\x8b\xcd\x48\x89\x44\x24\x40\x4c\x8b\xc5\x8b\x84\x24\xc0\x00\x00\x00\x48\x8b\xd6\x89\x7c\x24\x38\x49\x8b\xcf\x44\x88\x74\x24\x30\x89\x44\x24\x28\x4c\x89\x64\x24\x20\xe8\x0d\xf4\xff\xff\x4c\x8d\x5c\x24\x60\x49\x8b\x5b\x30\x49\x8b\x6b\x38\x49\x8b\x73\x40\x49\x8b\xe3\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\xc3\xcc\xcc\xcc\x48\x83\xec\x28\x48\x85\xc9\x75\x15\xe8\x06\xda\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\xdb\xd8\xff\xff\x83\xc8\xff\xeb\x03\x8b\x41\x18\x48\x83\xc4\x28\xc3\xcc\xcc\x83\x6a\x10\x01\x0f\x88\x76\x47\x00\x00\x48\x8b\x02\x88\x08\x48\xff\x02\x0f\xb6\xc1\xc3\xcc\xcc\x48\x8b\x0d\x59\x15\x01\x00\x33\xc0\x48\x83\xc9\x01\x48\x39\x0d\x94\x2c\x01\x00\x0f\x94\xc0\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xd9\xe8\x96\xff\xff\xff\x8b\xc8\xe8\x1f\x48\x00\x00\x85\xc0\x0f\x84\xa1\x00\x00\x00\xb9\x01\x00\x00\x00\xe8\xa1\xac\xff\xff\x48\x3b\xd8\x75\x09\x48\x8d\x3d\x61\x2c\x01\x00\xeb\x16\xb9\x02\x00\x00\x00\xe8\x89\xac\xff\xff\x48\x3b\xd8\x75\x7a\x48\x8d\x3d\x51\x2c\x01\x00\xff\x05\x13\x26\x01\x00\x8b\x43\x14\xa9\xc0\x04\x00\x00\x75\x63\xf0\x81\x4b\x14\x82\x02\x00\x00\x48\x8b\x07\x48\x85\xc0\x75\x39\xb9\x00\x10\x00\x00\xe8\x47\xd1\xff\xff\x33\xc9\x48\x89\x07\xe8\xfd\xd0\xff\xff\x48\x8b\x07\x48\x85\xc0\x75\x1d\x48\x8d\x4b\x1c\xc7\x43\x10\x02\x00\x00\x00\x48\x89\x4b\x08\x48\x89\x0b\xc7\x43\x20\x02\x00\x00\x00\xb0\x01\xeb\x1c\x48\x89\x43\x08\x48\x8b\x07\x48\x89\x03\xc7\x43\x10\x00\x10\x00\x00\xc7\x43\x20\x00\x10\x00\x00\xeb\xe2\x32\xc0\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\x84\xc9\x74\x34\x53\x48\x83\xec\x20\x48\x8b\xda\x8b\x42\x14\xc1\xe8\x09\xa8\x01\x74\x1d\x48\x8b\xca\xe8\x86\xdf\xff\xff\xf0\x81\x63\x14\x7f\xfd\xff\xff\x83\x63\x20\x00\x48\x83\x63\x08\x00\x48\x83\x23\x00\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\xb8\x01\x00\x00\x00\x87\x05\x91\x2b\x01\x00\xc3\x40\x57\x48\x83\xec\x20\x48\x8d\x3d\x23\x16\x01\x00\x48\x39\x3d\x84\x2b\x01\x00\x74\x2b\xb9\x04\x00\x00\x00\xe8\x70\x00\x00\x00\x90\x48\x8b\xd7\x48\x8d\x0d\x6d\x2b\x01\x00\xe8\x0c\x2b\x00\x00\x48\x89\x05\x61\x2b\x01\x00\xb9\x04\x00\x00\x00\xe8\xa3\x00\x00\x00\x48\x83\xc4\x20\x5f\xc3\xcc\x40\x53\x48\x83\xec\x20\x33\xdb\x48\x8d\x15\x49\x2b\x01\x00\x45\x33\xc0\x48\x8d\x0c\x9b\x48\x8d\x0c\xca\xba\xa0\x0f\x00\x00\xe8\x68\xdb\xff\xff\x85\xc0\x74\x11\xff\x05\x32\x2d\x01\x00\xff\xc3\x83\xfb\x0d\x72\xd3\xb0\x01\xeb\x09\x33\xc9\xe8\x24\x00\x00\x00\x32\xc0\x48\x83\xc4\x20\x5b\xc3\x48\x63\xc1\x48\x8d\x0c\x80\x48\x8d\x05\x02\x2b\x01\x00\x48\x8d\x0c\xc8\x48\xff\x25\xff\x74\x00\x00\xcc\xcc\xcc\x40\x53\x48\x83\xec\x20\x8b\x1d\xf0\x2c\x01\x00\xeb\x1d\x48\x8d\x05\xdf\x2a\x01\x00\xff\xcb\x48\x8d\x0c\x9b\x48\x8d\x0c\xc8\xff\x15\xe7\x74\x00\x00\xff\x0d\xd1\x2c\x01\x00\x85\xdb\x75\xdf\xb0\x01\x48\x83\xc4\x20\x5b\xc3\xcc\x48\x63\xc1\x48\x8d\x0c\x80\x48\x8d\x05\xae\x2a\x01\x00\x48\x8d\x0c\xc8\x48\xff\x25\xb3\x74\x00\x00\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xd9\x49\x8b\xf8\x8b\x0a\xe8\x74\xff\xff\xff\x90\x48\x8b\xcf\xe8\x13\x00\x00\x00\x90\x8b\x0b\xe8\xb7\xff\xff\xff\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8b\x01\x48\x8b\xd9\x48\x8b\x10\x48\x8b\x82\x88\x00\x00\x00\x8b\x50\x04\x89\x15\x4c\x2c\x01\x00\x48\x8b\x01\x48\x8b\x10\x48\x8b\x82\x88\x00\x00\x00\x8b\x50\x08\x89\x15\x3a\x2c\x01\x00\x48\x8b\x01\x48\x8b\x10\x48\x8b\x82\x88\x00\x00\x00\x48\x8b\x88\x20\x02\x00\x00\x48\x89\x0d\x37\x2c\x01\x00\x48\x8b\x03\x48\x8b\x08\x48\x8b\x81\x88\x00\x00\x00\x48\x83\xc0\x0c\x74\x17\xf2\x0f\x10\x00\xf2\x0f\x11\x05\x08\x2c\x01\x00\x8b\x40\x08\x89\x05\x07\x2c\x01\x00\xeb\x1f\x33\xc0\x48\x89\x05\xf4\x2b\x01\x00\x89\x05\xf6\x2b\x01\x00\xe8\xd5\xd6\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\xaa\xd5\xff\xff\x48\x8b\x03\xbf\x02\x00\x00\x00\x48\x8b\x08\x8d\x77\x7e\x48\x8b\x81\x88\x00\x00\x00\x48\x8d\x0d\xda\x18\x01\x00\x48\x83\xc0\x18\x74\x52\x8b\xd7\x0f\x10\x00\x0f\x11\x01\x0f\x10\x48\x10\x0f\x11\x49\x10\x0f\x10\x40\x20\x0f\x11\x41\x20\x0f\x10\x48\x30\x0f\x11\x49\x30\x0f\x10\x40\x40\x0f\x11\x41\x40\x0f\x10\x48\x50\x0f\x11\x49\x50\x0f\x10\x40\x60\x0f\x11\x41\x60\x48\x03\xce\x0f\x10\x48\x70\x48\x03\xc6\x0f\x11\x49\xf0\x48\x83\xea\x01\x75\xb6\x8a\x00\x88\x01\xeb\x1d\x33\xd2\x41\xb8\x01\x01\x00\x00\xe8\xf5\x9d\xff\xff\xe8\x44\xd6\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x19\xd5\xff\xff\x48\x8b\x03\x48\x8b\x08\x48\x8b\x81\x88\x00\x00\x00\x48\x8d\x0d\x61\x19\x01\x00\x48\x05\x19\x01\x00\x00\x74\x4c\x0f\x10\x00\x0f\x11\x01\x0f\x10\x48\x10\x0f\x11\x49\x10\x0f\x10\x40\x20\x0f\x11\x41\x20\x0f\x10\x48\x30\x0f\x11\x49\x30\x0f\x10\x40\x40\x0f\x11\x41\x40\x0f\x10\x48\x50\x0f\x11\x49\x50\x0f\x10\x40\x60\x0f\x11\x41\x60\x48\x03\xce\x0f\x10\x48\x70\x48\x03\xc6\x0f\x11\x49\xf0\x48\x83\xef\x01\x75\xb6\xeb\x1d\x33\xd2\x41\xb8\x00\x01\x00\x00\xe8\x70\x9d\xff\xff\xe8\xbf\xd5\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x94\xd4\xff\xff\x48\x8b\x0d\xd1\x16\x01\x00\x83\xc8\xff\xf0\x0f\xc1\x01\x83\xf8\x01\x75\x18\x48\x8b\x0d\xbe\x16\x01\x00\x48\x8d\x05\x8f\x14\x01\x00\x48\x3b\xc8\x74\x05\xe8\x4d\xcd\xff\xff\x48\x8b\x03\x48\x8b\x08\x48\x8b\x81\x88\x00\x00\x00\x48\x89\x05\x99\x16\x01\x00\x48\x8b\x03\x48\x8b\x08\x48\x8b\x81\x88\x00\x00\x00\xf0\xff\x00\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x40\x53\x48\x83\xec\x40\x8b\xd9\x33\xd2\x48\x8d\x4c\x24\x20\xe8\x2c\xac\xff\xff\x83\x25\x59\x2a\x01\x00\x00\x83\xfb\xfe\x75\x12\xc7\x05\x4a\x2a\x01\x00\x01\x00\x00\x00\xff\x15\x98\x72\x00\x00\xeb\x15\x83\xfb\xfd\x75\x14\xc7\x05\x33\x2a\x01\x00\x01\x00\x00\x00\xff\x15\x71\x72\x00\x00\x8b\xd8\xeb\x17\x83\xfb\xfc\x75\x12\x48\x8b\x44\x24\x28\xc7\x05\x15\x2a\x01\x00\x01\x00\x00\x00\x8b\x58\x0c\x80\x7c\x24\x38\x00\x74\x0c\x48\x8b\x4c\x24\x20\x83\xa1\xa8\x03\x00\x00\xfd\x8b\xc3\x48\x83\xc4\x40\x5b\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x48\x8d\x59\x18\x48\x8b\xf1\xbd\x01\x01\x00\x00\x48\x8b\xcb\x44\x8b\xc5\x33\xd2\xe8\x53\x9c\xff\xff\x33\xc0\x48\x8d\x7e\x0c\x48\x89\x46\x04\xb9\x06\x00\x00\x00\x48\x89\x86\x20\x02\x00\x00\x0f\xb7\xc0\x66\xf3\xab\x48\x8d\x3d\x80\x13\x01\x00\x48\x2b\xfe\x8a\x04\x1f\x88\x03\x48\xff\xc3\x48\x83\xed\x01\x75\xf2\x48\x8d\x8e\x19\x01\x00\x00\xba\x00\x01\x00\x00\x8a\x04\x39\x88\x01\x48\xff\xc1\x48\x83\xea\x01\x75\xf2\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x10\x48\x89\x7c\x24\x18\x55\x48\x8d\xac\x24\x80\xf9\xff\xff\x48\x81\xec\x80\x07\x00\x00\x48\x8b\x05\xaf\x0f\x01\x00\x48\x33\xc4\x48\x89\x85\x70\x06\x00\x00\x48\x8b\xf9\x48\x8d\x54\x24\x50\x8b\x49\x04\xff\x15\x84\x71\x00\x00\xbb\x00\x01\x00\x00\x85\xc0\x0f\x84\x36\x01\x00\x00\x33\xc0\x48\x8d\x4c\x24\x70\x88\x01\xff\xc0\x48\xff\xc1\x3b\xc3\x72\xf5\x8a\x44\x24\x56\x48\x8d\x54\x24\x56\xc6\x44\x24\x70\x20\xeb\x22\x44\x0f\xb6\x42\x01\x0f\xb6\xc8\xeb\x0d\x3b\xcb\x73\x0e\x8b\xc1\xc6\x44\x0c\x70\x20\xff\xc1\x41\x3b\xc8\x76\xee\x48\x83\xc2\x02\x8a\x02\x84\xc0\x75\xda\x8b\x47\x04\x4c\x8d\x44\x24\x70\x83\x64\x24\x30\x00\x44\x8b\xcb\x89\x44\x24\x28\xba\x01\x00\x00\x00\x48\x8d\x85\x70\x02\x00\x00\x33\xc9\x48\x89\x44\x24\x20\xe8\x3b\x45\x00\x00\x83\x64\x24\x40\x00\x4c\x8d\x4c\x24\x70\x8b\x47\x04\x44\x8b\xc3\x48\x8b\x97\x20\x02\x00\x00\x33\xc9\x89\x44\x24\x38\x48\x8d\x45\x70\x89\x5c\x24\x30\x48\x89\x44\x24\x28\x89\x5c\x24\x20\xe8\xb0\x21\x00\x00\x83\x64\x24\x40\x00\x4c\x8d\x4c\x24\x70\x8b\x47\x04\x41\xb8\x00\x02\x00\x00\x48\x8b\x97\x20\x02\x00\x00\x33\xc9\x89\x44\x24\x38\x48\x8d\x85\x70\x01\x00\x00\x89\x5c\x24\x30\x48\x89\x44\x24\x28\x89\x5c\x24\x20\xe8\x77\x21\x00\x00\x4c\x8d\x45\x70\x4c\x2b\xc7\x4c\x8d\x8d\x70\x01\x00\x00\x4c\x2b\xcf\x48\x8d\x95\x70\x02\x00\x00\x48\x8d\x4f\x19\xf6\x02\x01\x74\x0a\x80\x09\x10\x41\x8a\x44\x08\xe7\xeb\x0d\xf6\x02\x02\x74\x10\x80\x09\x20\x41\x8a\x44\x09\xe7\x88\x81\x00\x01\x00\x00\xeb\x07\xc6\x81\x00\x01\x00\x00\x00\x48\xff\xc1\x48\x83\xc2\x02\x48\x83\xeb\x01\x75\xc8\xeb\x3f\x33\xd2\x48\x8d\x4f\x19\x44\x8d\x42\x9f\x41\x8d\x40\x20\x83\xf8\x19\x77\x08\x80\x09\x10\x8d\x42\x20\xeb\x0c\x41\x83\xf8\x19\x77\x0e\x80\x09\x20\x8d\x42\xe0\x88\x81\x00\x01\x00\x00\xeb\x07\xc6\x81\x00\x01\x00\x00\x00\xff\xc2\x48\xff\xc1\x3b\xd3\x72\xc7\x48\x8b\x8d\x70\x06\x00\x00\x48\x33\xcc\xe8\x33\x87\xff\xff\x4c\x8d\x9c\x24\x80\x07\x00\x00\x49\x8b\x5b\x18\x49\x8b\x7b\x20\x49\x8b\xe3\x5d\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x55\x56\x57\x48\x8b\xec\x48\x83\xec\x40\x40\x8a\xf2\x8b\xd9\xe8\xbb\xe9\xff\xff\x48\x89\x45\xe8\xe8\xbe\x01\x00\x00\x8b\xcb\xe8\xe3\xfc\xff\xff\x48\x8b\x4d\xe8\x8b\xf8\x4c\x8b\x81\x88\x00\x00\x00\x41\x3b\x40\x04\x75\x07\x33\xc0\xe9\xb8\x00\x00\x00\xb9\x28\x02\x00\x00\xe8\x17\xca\xff\xff\x48\x8b\xd8\x48\x85\xc0\x0f\x84\x95\x00\x00\x00\x48\x8b\x45\xe8\xba\x04\x00\x00\x00\x48\x8b\xcb\x48\x8b\x80\x88\x00\x00\x00\x44\x8d\x42\x7c\x0f\x10\x00\x0f\x11\x01\x0f\x10\x48\x10\x0f\x11\x49\x10\x0f\x10\x40\x20\x0f\x11\x41\x20\x0f\x10\x48\x30\x0f\x11\x49\x30\x0f\x10\x40\x40\x0f\x11\x41\x40\x0f\x10\x48\x50\x0f\x11\x49\x50\x0f\x10\x40\x60\x0f\x11\x41\x60\x49\x03\xc8\x0f\x10\x48\x70\x49\x03\xc0\x0f\x11\x49\xf0\x48\x83\xea\x01\x75\xb6\x0f\x10\x00\x0f\x11\x01\x0f\x10\x48\x10\x0f\x11\x49\x10\x48\x8b\x40\x20\x48\x89\x41\x20\x8b\xcf\x21\x13\x48\x8b\xd3\xe8\xc4\x01\x00\x00\x8b\xf8\x83\xf8\xff\x75\x25\xe8\x78\xd1\xff\xff\xc7\x00\x16\x00\x00\x00\x83\xcf\xff\x48\x8b\xcb\xe8\x2b\xc9\xff\xff\x8b\xc7\x48\x8b\x5c\x24\x60\x48\x83\xc4\x40\x5f\x5e\x5d\xc3\x40\x84\xf6\x75\x05\xe8\x9e\xf8\xff\xff\x48\x8b\x45\xe8\x48\x8b\x88\x88\x00\x00\x00\x83\xc8\xff\xf0\x0f\xc1\x01\x83\xf8\x01\x75\x1c\x48\x8b\x45\xe8\x48\x8b\x88\x88\x00\x00\x00\x48\x8d\x05\x21\x10\x01\x00\x48\x3b\xc8\x74\x05\xe8\xdf\xc8\xff\xff\xc7\x03\x01\x00\x00\x00\x48\x8b\xcb\x48\x8b\x45\xe8\x33\xdb\x48\x89\x88\x88\x00\x00\x00\x48\x8b\x45\xe8\xf6\x80\xa8\x03\x00\x00\x02\x75\x89\xf6\x05\x2d\x15\x01\x00\x01\x75\x80\x48\x8d\x45\xe8\x48\x89\x45\xf0\x4c\x8d\x4d\x38\x8d\x43\x05\x4c\x8d\x45\xf0\x89\x45\x38\x48\x8d\x55\xe0\x89\x45\xe0\x48\x8d\x4d\x30\xe8\x25\xf9\xff\xff\x48\x8b\x05\xae\x0f\x01\x00\x40\x84\xf6\x48\x0f\x45\x05\xdb\x11\x01\x00\x48\x89\x05\x9c\x0f\x01\x00\xe9\x3c\xff\xff\xff\xcc\xcc\xcc\x48\x83\xec\x28\x80\x3d\xc9\x25\x01\x00\x00\x75\x13\xb2\x01\xb9\xfd\xff\xff\xff\xe8\x2f\xfe\xff\xff\xc6\x05\xb4\x25\x01\x00\x01\xb0\x01\x48\x83\xc4\x28\xc3\xcc\x48\x89\x5c\x24\x10\x57\x48\x83\xec\x20\xe8\xe5\xe7\xff\xff\x48\x8b\xf8\x8b\x0d\xa4\x14\x01\x00\x85\x88\xa8\x03\x00\x00\x74\x13\x48\x83\xb8\x90\x00\x00\x00\x00\x74\x09\x48\x8b\x98\x88\x00\x00\x00\xeb\x73\xb9\x05\x00\x00\x00\xe8\x2f\xf8\xff\xff\x90\x48\x8b\x9f\x88\x00\x00\x00\x48\x89\x5c\x24\x30\x48\x3b\x1d\x53\x11\x01\x00\x74\x49\x48\x85\xdb\x74\x22\x83\xc8\xff\xf0\x0f\xc1\x03\x83\xf8\x01\x75\x16\x48\x8d\x05\x11\x0f\x01\x00\x48\x8b\x4c\x24\x30\x48\x3b\xc8\x74\x05\xe8\xca\xc7\xff\xff\x48\x8b\x05\x23\x11\x01\x00\x48\x89\x87\x88\x00\x00\x00\x48\x8b\x05\x15\x11\x01\x00\x48\x89\x44\x24\x30\xf0\xff\x00\x48\x8b\x5c\x24\x30\xb9\x05\x00\x00\x00\xe8\x1a\xf8\xff\xff\x48\x85\xdb\x75\x06\xe8\x94\xc8\xff\xff\xcc\x48\x8b\xc3\x48\x8b\x5c\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x5c\x24\x18\x48\x89\x6c\x24\x20\x56\x57\x41\x54\x41\x56\x41\x57\x48\x83\xec\x40\x48\x8b\x05\x2f\x0b\x01\x00\x48\x33\xc4\x48\x89\x44\x24\x38\x48\x8b\xda\xe8\x3f\xfa\xff\xff\x33\xf6\x8b\xf8\x85\xc0\x75\x0d\x48\x8b\xcb\xe8\xaf\xfa\xff\xff\xe9\x3d\x02\x00\x00\x4c\x8d\x25\xb3\x10\x01\x00\x8b\xee\x49\x8b\xc4\x41\xbf\x01\x00\x00\x00\x39\x38\x0f\x84\x30\x01\x00\x00\x41\x03\xef\x48\x83\xc0\x30\x83\xfd\x05\x72\xec\x8d\x87\x18\x02\xff\xff\x41\x3b\xc7\x0f\x86\x0d\x01\x00\x00\x0f\xb7\xcf\xff\x15\xac\x6c\x00\x00\x85\xc0\x0f\x84\xfc\x00\x00\x00\x48\x8d\x54\x24\x20\x8b\xcf\xff\x15\xa7\x6c\x00\x00\x85\xc0\x0f\x84\xdb\x00\x00\x00\x48\x8d\x4b\x18\x33\xd2\x41\xb8\x01\x01\x00\x00\xe8\xbe\x96\xff\xff\x89\x7b\x04\x48\x89\xb3\x20\x02\x00\x00\x44\x39\x7c\x24\x20\x0f\x86\x9e\x00\x00\x00\x48\x8d\x4c\x24\x26\x40\x38\x74\x24\x26\x74\x30\x40\x38\x71\x01\x74\x2a\x0f\xb6\x41\x01\x0f\xb6\x11\x3b\xd0\x77\x16\x2b\xc2\x8d\x7a\x01\x41\x8d\x14\x07\x80\x4c\x1f\x18\x04\x41\x03\xff\x49\x2b\xd7\x75\xf3\x48\x83\xc1\x02\x40\x38\x31\x75\xd0\x48\x8d\x43\x1a\xb9\xfe\x00\x00\x00\x80\x08\x08\x49\x03\xc7\x49\x2b\xcf\x75\xf5\x8b\x4b\x04\x81\xe9\xa4\x03\x00\x00\x74\x2f\x83\xe9\x04\x74\x21\x83\xe9\x0d\x74\x13\x41\x3b\xcf\x74\x05\x48\x8b\xc6\xeb\x22\x48\x8b\x05\x7b\x89\x00\x00\xeb\x19\x48\x8b\x05\x6a\x89\x00\x00\xeb\x10\x48\x8b\x05\x59\x89\x00\x00\xeb\x07\x48\x8b\x05\x48\x89\x00\x00\x48\x89\x83\x20\x02\x00\x00\x44\x89\x7b\x08\xeb\x03\x89\x73\x08\x48\x8d\x7b\x0c\x0f\xb7\xc6\xb9\x06\x00\x00\x00\x66\xf3\xab\xe9\xff\x00\x00\x00\x39\x35\x62\x23\x01\x00\x0f\x85\xb1\xfe\xff\xff\x83\xc8\xff\xe9\xf5\x00\x00\x00\x48\x8d\x4b\x18\x33\xd2\x41\xb8\x01\x01\x00\x00\xe8\xcf\x95\xff\xff\x8b\xc5\x4d\x8d\x4c\x24\x10\x4c\x8d\x35\x41\x0f\x01\x00\xbd\x04\x00\x00\x00\x4c\x8d\x1c\x40\x49\xc1\xe3\x04\x4d\x03\xcb\x49\x8b\xd1\x41\x38\x31\x74\x40\x40\x38\x72\x01\x74\x3a\x44\x0f\xb6\x02\x0f\xb6\x42\x01\x44\x3b\xc0\x77\x24\x45\x8d\x50\x01\x41\x81\xfa\x01\x01\x00\x00\x73\x17\x41\x8a\x06\x45\x03\xc7\x41\x08\x44\x1a\x18\x45\x03\xd7\x0f\xb6\x42\x01\x44\x3b\xc0\x76\xe0\x48\x83\xc2\x02\x40\x38\x32\x75\xc0\x49\x83\xc1\x08\x4d\x03\xf7\x49\x2b\xef\x75\xac\x89\x7b\x04\x44\x89\x7b\x08\x81\xef\xa4\x03\x00\x00\x74\x2a\x83\xef\x04\x74\x1c\x83\xef\x0d\x74\x0e\x41\x3b\xff\x75\x22\x48\x8b\x35\x80\x88\x00\x00\xeb\x19\x48\x8b\x35\x6f\x88\x00\x00\xeb\x10\x48\x8b\x35\x5e\x88\x00\x00\xeb\x07\x48\x8b\x35\x4d\x88\x00\x00\x4c\x2b\xdb\x48\x89\xb3\x20\x02\x00\x00\x48\x8d\x4b\x0c\xba\x06\x00\x00\x00\x4b\x8d\x3c\x23\x0f\xb7\x44\x0f\xf8\x66\x89\x01\x48\x8d\x49\x02\x49\x2b\xd7\x75\xef\x48\x8b\xcb\xe8\xfd\xf8\xff\xff\x33\xc0\x48\x8b\x4c\x24\x38\x48\x33\xcc\xe8\xee\x81\xff\xff\x4c\x8d\x5c\x24\x40\x49\x8b\x5b\x40\x49\x8b\x6b\x48\x49\x8b\xe3\x41\x5f\x41\x5e\x41\x5c\x5f\x5e\xc3\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xec\x40\xff\x15\x7d\x6a\x00\x00\x45\x33\xf6\x48\x8b\xd8\x48\x85\xc0\x0f\x84\xa6\x00\x00\x00\x48\x8b\xf0\x66\x44\x39\x30\x74\x1c\x48\x83\xc8\xff\x48\xff\xc0\x66\x44\x39\x34\x46\x75\xf6\x48\x8d\x34\x46\x48\x83\xc6\x02\x66\x44\x39\x36\x75\xe4\x4c\x89\x74\x24\x38\x48\x2b\xf3\x4c\x89\x74\x24\x30\x48\x83\xc6\x02\x48\xd1\xfe\x4c\x8b\xc3\x44\x8b\xce\x44\x89\x74\x24\x28\x33\xd2\x4c\x89\x74\x24\x20\x33\xc9\xff\x15\xcb\x69\x00\x00\x48\x63\xe8\x85\xc0\x74\x4c\x48\x8b\xcd\xe8\x8c\xc4\xff\xff\x48\x8b\xf8\x48\x85\xc0\x74\x2f\x4c\x89\x74\x24\x38\x44\x8b\xce\x4c\x89\x74\x24\x30\x4c\x8b\xc3\x89\x6c\x24\x28\x33\xd2\x33\xc9\x48\x89\x44\x24\x20\xff\x15\x91\x69\x00\x00\x85\xc0\x74\x08\x48\x8b\xf7\x49\x8b\xfe\xeb\x03\x49\x8b\xf6\x48\x8b\xcf\xe8\x0a\xc4\xff\xff\xeb\x03\x49\x8b\xf6\x48\x85\xdb\x74\x09\x48\x8b\xcb\xff\x15\xbf\x69\x00\x00\x48\x8b\x5c\x24\x50\x48\x8b\xc6\x48\x8b\x74\x24\x60\x48\x8b\x6c\x24\x58\x48\x8b\x7c\x24\x68\x48\x83\xc4\x40\x41\x5e\xc3\xcc\xe9\x03\x00\x00\x00\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x49\x8b\xe8\x48\x8b\xda\x48\x8b\xf1\x48\x85\xd2\x74\x1d\x33\xd2\x48\x8d\x42\xe0\x48\xf7\xf3\x49\x3b\xc0\x73\x0f\xe8\xd7\xcb\xff\xff\xc7\x00\x0c\x00\x00\x00\x33\xc0\xeb\x41\x48\x85\xc9\x74\x0a\xe8\x43\x3f\x00\x00\x48\x8b\xf8\xeb\x02\x33\xff\x48\x0f\xaf\xdd\x48\x8b\xce\x48\x8b\xd3\xe8\x69\x3f\x00\x00\x48\x8b\xf0\x48\x85\xc0\x74\x16\x48\x3b\xfb\x73\x11\x48\x2b\xdf\x48\x8d\x0c\x38\x4c\x8b\xc3\x33\xd2\xe8\x3b\x93\xff\xff\x48\x8b\xc6\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x83\xec\x28\xff\x15\x8e\x67\x00\x00\x48\x85\xc0\x48\x89\x05\x94\x20\x01\x00\x0f\x95\xc0\x48\x83\xc4\x28\xc3\x48\x83\x25\x84\x20\x01\x00\x00\xb0\x01\xc3\xcc\x48\x83\xec\x28\xff\x15\x5e\x67\x00\x00\x48\x89\x05\x87\x20\x01\x00\xff\x15\x49\x67\x00\x00\x48\x89\x05\x82\x20\x01\x00\xb0\x01\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x48\x8b\xf2\x48\x8b\xf9\x48\x3b\xca\x75\x04\xb0\x01\xeb\x5c\x48\x8b\xd9\x48\x8b\x2b\x48\x85\xed\x74\x0f\x48\x8b\xcd\xff\x15\x51\x69\x00\x00\xff\xd5\x84\xc0\x74\x09\x48\x83\xc3\x10\x48\x3b\xde\x75\xe0\x48\x3b\xde\x74\xd4\x48\x3b\xdf\x74\x2d\x48\x83\xc3\xf8\x48\x83\x7b\xf8\x00\x74\x15\x48\x8b\x33\x48\x85\xf6\x74\x0d\x48\x8b\xce\xff\x15\x1c\x69\x00\x00\x33\xc9\xff\xd6\x48\x83\xeb\x10\x48\x8d\x43\x08\x48\x3b\xc7\x75\xd7\x32\xc0\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8b\xf1\x48\x3b\xca\x74\x26\x48\x8d\x5a\xf8\x48\x8b\x3b\x48\x85\xff\x74\x0d\x48\x8b\xcf\xff\x15\xc8\x68\x00\x00\x33\xc9\xff\xd7\x48\x83\xeb\x10\x48\x8d\x43\x08\x48\x3b\xc6\x75\xde\x48\x8b\x5c\x24\x30\xb0\x01\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x0d\x95\x1f\x01\x00\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xf9\xe8\x2e\x00\x00\x00\x48\x8b\xd8\x48\x85\xc0\x74\x19\x48\x8b\xc8\xff\x15\x79\x68\x00\x00\x48\x8b\xcf\xff\xd3\x85\xc0\x74\x07\xb8\x01\x00\x00\x00\xeb\x02\x33\xc0\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x40\x53\x48\x83\xec\x20\x33\xc9\xe8\xd7\xf1\xff\xff\x90\x48\x8b\x1d\x6f\x05\x01\x00\x8b\xcb\x83\xe1\x3f\x48\x33\x1d\x33\x1f\x01\x00\x48\xd3\xcb\x33\xc9\xe8\x0d\xf2\xff\xff\x48\x8b\xc3\x48\x83\xc4\x20\x5b\xc3\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xf9\x8b\x0a\xe8\x97\xf1\xff\xff\x90\x48\x8b\x1d\x2f\x05\x01\x00\x8b\xcb\x83\xe1\x3f\x48\x33\x1d\x0b\x1f\x01\x00\x48\xd3\xcb\x8b\x0f\xe8\xcd\xf1\xff\xff\x48\x8b\xc3\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x4c\x8b\xdc\x48\x83\xec\x28\xb8\x03\x00\x00\x00\x4d\x8d\x4b\x10\x4d\x8d\x43\x08\x89\x44\x24\x38\x49\x8d\x53\x18\x89\x44\x24\x40\x49\x8d\x4b\x08\xe8\x8f\xff\xff\xff\x48\x83\xc4\x28\xc3\xcc\xcc\x48\x89\x0d\xa9\x1e\x01\x00\x48\x89\x0d\xaa\x1e\x01\x00\x48\x89\x0d\xab\x1e\x01\x00\x48\x89\x0d\xac\x1e\x01\x00\xc3\xcc\xcc\xcc\x48\x8b\xc4\x53\x56\x57\x41\x54\x41\x55\x41\x57\x48\x83\xec\x48\x8b\xf9\x45\x33\xed\x44\x21\x68\x18\x40\xb6\x01\x40\x88\xb4\x24\x80\x00\x00\x00\x83\xf9\x02\x0f\x84\x8e\x00\x00\x00\x83\xf9\x04\x74\x22\x83\xf9\x06\x0f\x84\x80\x00\x00\x00\x83\xf9\x08\x74\x14\x83\xf9\x0b\x74\x0f\x83\xf9\x0f\x74\x71\x8d\x41\xeb\x83\xf8\x01\x76\x69\xeb\x44\xe8\xdb\xe0\xff\xff\x4c\x8b\xe8\x48\x85\xc0\x75\x08\x83\xc8\xff\xe9\x22\x02\x00\x00\x48\x8b\x08\x48\x8b\x15\x65\x74\x00\x00\x48\xc1\xe2\x04\x48\x03\xd1\xeb\x09\x39\x79\x04\x74\x0b\x48\x83\xc1\x10\x48\x3b\xca\x75\xf2\x33\xc9\x33\xc0\x48\x85\xc9\x0f\x95\xc0\x85\xc0\x75\x12\xe8\x8f\xc8\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x64\xc7\xff\xff\xeb\xb7\x48\x8d\x59\x08\x40\x32\xf6\x40\x88\xb4\x24\x80\x00\x00\x00\xeb\x3f\x83\xe9\x02\x74\x33\x83\xe9\x04\x74\x13\x83\xe9\x09\x74\x20\x83\xe9\x06\x74\x12\x83\xf9\x01\x74\x04\x33\xdb\xeb\x22\x48\x8d\x1d\xc1\x1d\x01\x00\xeb\x19\x48\x8d\x1d\xb0\x1d\x01\x00\xeb\x10\x48\x8d\x1d\xb7\x1d\x01\x00\xeb\x07\x48\x8d\x1d\x96\x1d\x01\x00\x48\x83\xa4\x24\x98\x00\x00\x00\x00\x40\x84\xf6\x74\x0b\xb9\x03\x00\x00\x00\xe8\x06\xf0\xff\xff\x90\x40\x84\xf6\x74\x17\x48\x8b\x15\x99\x03\x01\x00\x8b\xca\x83\xe1\x3f\x48\x33\x13\x48\xd3\xca\x4c\x8b\xfa\xeb\x03\x4c\x8b\x3b\x49\x83\xff\x01\x0f\x94\xc0\x88\x84\x24\x88\x00\x00\x00\x84\xc0\x0f\x85\xbf\x00\x00\x00\x4d\x85\xff\x75\x18\x40\x84\xf6\x74\x09\x41\x8d\x4f\x03\xe8\x11\xf0\xff\xff\xb9\x03\x00\x00\x00\xe8\x0b\xb7\xff\xff\x41\xbc\x10\x09\x00\x00\x83\xff\x0b\x77\x40\x41\x0f\xa3\xfc\x73\x3a\x49\x8b\x45\x08\x48\x89\x84\x24\x98\x00\x00\x00\x48\x89\x44\x24\x30\x49\x83\x65\x08\x00\x83\xff\x08\x75\x56\xe8\x0a\xdf\xff\xff\x8b\x40\x10\x89\x84\x24\x90\x00\x00\x00\x89\x44\x24\x20\xe8\xf7\xde\xff\xff\xc7\x40\x10\x8c\x00\x00\x00\x83\xff\x08\x75\x32\x48\x8b\x05\x24\x73\x00\x00\x48\xc1\xe0\x04\x49\x03\x45\x00\x48\x8b\x0d\x1d\x73\x00\x00\x48\xc1\xe1\x04\x48\x03\xc8\x48\x89\x44\x24\x28\x48\x3b\xc1\x74\x31\x48\x83\x60\x08\x00\x48\x83\xc0\x10\xeb\xeb\x48\x8b\x15\xca\x02\x01\x00\x8b\xc2\x83\xe0\x3f\xb9\x40\x00\x00\x00\x2b\xc8\x33\xc0\x48\xd3\xc8\x48\x33\xc2\x48\x89\x03\xeb\x06\x41\xbc\x10\x09\x00\x00\x40\x84\xf6\x74\x0a\xb9\x03\x00\x00\x00\xe8\x50\xef\xff\xff\x80\xbc\x24\x88\x00\x00\x00\x00\x74\x04\x33\xc0\xeb\x61\x83\xff\x08\x75\x1e\xe8\x6c\xde\xff\xff\x48\x8b\xd8\x49\x8b\xcf\x48\x8b\x15\x4f\x65\x00\x00\xff\xd2\x8b\x53\x10\x8b\xcf\x41\xff\xd7\xeb\x11\x49\x8b\xcf\x48\x8b\x05\x39\x65\x00\x00\xff\xd0\x8b\xcf\x41\xff\xd7\x83\xff\x0b\x77\xc3\x41\x0f\xa3\xfc\x73\xbd\x48\x8b\x84\x24\x98\x00\x00\x00\x49\x89\x45\x08\x83\xff\x08\x75\xac\xe8\x21\xde\xff\xff\x8b\x8c\x24\x90\x00\x00\x00\x89\x48\x10\xeb\x9b\x48\x83\xc4\x48\x41\x5f\x41\x5d\x41\x5c\x5f\x5e\x5b\xc3\xcc\xcc\xcc\x48\x8b\x15\x15\x02\x01\x00\x8b\xca\x48\x33\x15\x04\x1c\x01\x00\x83\xe1\x3f\x48\xd3\xca\x48\x85\xd2\x0f\x95\xc0\xc3\xcc\xcc\xcc\x48\x89\x0d\xed\x1b\x01\x00\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\x1d\xe3\x01\x01\x00\x48\x8b\xf9\x8b\xcb\x48\x33\x1d\xcf\x1b\x01\x00\x83\xe1\x3f\x48\xd3\xcb\x48\x85\xdb\x75\x04\x33\xc0\xeb\x0e\x48\x8b\xcb\xff\x15\x97\x64\x00\x00\x48\x8b\xcf\xff\xd3\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x8b\x05\xa6\x1b\x01\x00\xc3\xcc\x48\x83\xec\x28\xe8\x83\xdd\xff\xff\x48\x8d\x54\x24\x30\x48\x8b\x88\x90\x00\x00\x00\x48\x89\x4c\x24\x30\x48\x8b\xc8\xe8\xfe\xde\xff\xff\x48\x8b\x44\x24\x30\x48\x8b\x00\x48\x83\xc4\x28\xc3\xcc\x48\x89\x74\x24\x10\x48\x89\x7c\x24\x18\x4c\x89\x74\x24\x20\x55\x48\x8b\xec\x48\x81\xec\x80\x00\x00\x00\x48\x8b\x05\x53\x01\x01\x00\x48\x33\xc4\x48\x89\x45\xf0\x44\x8b\xf2\x48\x63\xf9\x49\x8b\xd0\x48\x8d\x4d\xc8\xe8\x9a\x9c\xff\xff\x8d\x47\x01\x3d\x00\x01\x00\x00\x77\x10\x48\x8b\x45\xd0\x48\x8b\x08\x0f\xb7\x04\x79\xe9\x82\x00\x00\x00\x8b\xf7\x48\x8d\x55\xd0\xc1\xfe\x08\x40\x0f\xb6\xce\xe8\x42\x10\x00\x00\xba\x01\x00\x00\x00\x85\xc0\x74\x12\x40\x88\x75\xc0\x44\x8d\x4a\x01\x40\x88\x7d\xc1\xc6\x45\xc2\x00\xeb\x0b\x40\x88\x7d\xc0\x44\x8b\xca\xc6\x45\xc1\x00\x33\xc0\x89\x54\x24\x30\x89\x45\xe8\x4c\x8d\x45\xc0\x66\x89\x45\xec\x48\x8b\x45\xd0\x8b\x48\x0c\x48\x8d\x45\xe8\x89\x4c\x24\x28\x48\x8d\x4d\xd0\x48\x89\x44\x24\x20\xe8\xe2\x36\x00\x00\x85\xc0\x75\x14\x38\x45\xe0\x74\x0b\x48\x8b\x45\xc8\x83\xa0\xa8\x03\x00\x00\xfd\x33\xc0\xeb\x18\x0f\xb7\x45\xe8\x41\x23\xc6\x80\x7d\xe0\x00\x74\x0b\x48\x8b\x4d\xc8\x83\xa1\xa8\x03\x00\x00\xfd\x48\x8b\x4d\xf0\x48\x33\xcc\xe8\xae\x79\xff\xff\x4c\x8d\x9c\x24\x80\x00\x00\x00\x49\x8b\x73\x18\x49\x8b\x7b\x20\x4d\x8b\x73\x28\x49\x8b\xe3\x5d\xc3\xcc\x48\x8b\xc4\x48\x89\x58\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x33\xed\x4c\x8d\x35\x56\xa0\x00\x00\x44\x8b\xd5\x48\x8b\xf1\x41\xbb\xe3\x00\x00\x00\x43\x8d\x04\x13\x48\x8b\xfe\x99\xbb\x55\x00\x00\x00\x2b\xc2\xd1\xf8\x4c\x63\xc0\x49\x8b\xc8\x48\xc1\xe1\x04\x4e\x8b\x0c\x31\x49\x2b\xf9\x42\x0f\xb7\x14\x0f\x8d\x4a\xbf\x66\x83\xf9\x19\x77\x04\x66\x83\xc2\x20\x41\x0f\xb7\x09\x8d\x41\xbf\x66\x83\xf8\x19\x77\x04\x66\x83\xc1\x20\x49\x83\xc1\x02\x48\x83\xeb\x01\x74\x0a\x66\x85\xd2\x74\x05\x66\x3b\xd1\x74\xc9\x0f\xb7\xc1\x0f\xb7\xca\x2b\xc8\x74\x18\x85\xc9\x79\x06\x45\x8d\x58\xff\xeb\x04\x45\x8d\x50\x01\x45\x3b\xd3\x7e\x8a\x83\xc8\xff\xeb\x0b\x49\x8b\xc0\x48\x03\xc0\x41\x8b\x44\xc6\x08\x48\x8b\x5c\x24\x10\x48\x8b\x6c\x24\x18\x48\x8b\x74\x24\x20\x48\x8b\x7c\x24\x28\x41\x5e\xc3\xcc\x48\x83\xec\x28\x48\x85\xc9\x74\x22\xe8\x2a\xff\xff\xff\x85\xc0\x78\x19\x48\x98\x48\x3d\xe4\x00\x00\x00\x73\x0f\x48\x03\xc0\x48\x8d\x0d\x26\x85\x00\x00\x8b\x04\xc1\xeb\x02\x33\xc0\x48\x83\xc4\x28\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xd9\x48\x85\xc9\x75\x15\xe8\xc5\xc3\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x9a\xc2\xff\xff\x83\xc8\xff\xeb\x51\x83\xcf\xff\x8b\x41\x14\xc1\xe8\x0d\xa8\x01\x74\x3a\xe8\x5b\xca\xff\xff\x48\x8b\xcb\x8b\xf8\xe8\x05\xcc\xff\xff\x48\x8b\xcb\xe8\x7d\xe9\xff\xff\x8b\xc8\xe8\x3e\x38\x00\x00\x85\xc0\x79\x05\x83\xcf\xff\xeb\x13\x48\x8b\x4b\x28\x48\x85\xc9\x74\x0a\xe8\x37\xbb\xff\xff\x48\x83\x63\x28\x00\x48\x8b\xcb\xe8\x7a\x39\x00\x00\x8b\xc7\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x89\x5c\x24\x10\x48\x89\x4c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xd9\x33\xc0\x48\x85\xc9\x0f\x95\xc0\x85\xc0\x75\x15\xe8\x35\xc3\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x0a\xc2\xff\xff\x83\xc8\xff\xeb\x2b\x8b\x41\x14\xc1\xe8\x0c\xa8\x01\x74\x07\xe8\x2a\x39\x00\x00\xeb\xea\xe8\x8f\x96\xff\xff\x90\x48\x8b\xcb\xe8\x2a\xff\xff\xff\x8b\xf8\x48\x8b\xcb\xe8\x88\x96\xff\xff\x8b\xc7\x48\x8b\x5c\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xf9\x49\x8b\xd8\x8b\x0a\xe8\x14\x0c\x00\x00\x90\x48\x8b\x03\x48\x63\x08\x48\x8b\xd1\x48\x8b\xc1\x48\xc1\xf8\x06\x4c\x8d\x05\x84\x11\x01\x00\x83\xe2\x3f\x48\xc1\xe2\x06\x49\x8b\x04\xc0\xf6\x44\x10\x38\x01\x74\x24\xe8\xe9\x0c\x00\x00\x48\x8b\xc8\xff\x15\x9c\x5e\x00\x00\x33\xdb\x85\xc0\x75\x1e\xe8\x6d\xc2\xff\xff\x48\x8b\xd8\xff\x15\x18\x60\x00\x00\x89\x03\xe8\x7d\xc2\xff\xff\xc7\x00\x09\x00\x00\x00\x83\xcb\xff\x8b\x0f\xe8\xd5\x0b\x00\x00\x8b\xc3\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x89\x4c\x24\x08\x48\x83\xec\x38\x48\x63\xd1\x83\xfa\xfe\x75\x0d\xe8\x4b\xc2\xff\xff\xc7\x00\x09\x00\x00\x00\xeb\x6c\x85\xc9\x78\x58\x3b\x15\x05\x15\x01\x00\x73\x50\x48\x8b\xca\x4c\x8d\x05\xf9\x10\x01\x00\x83\xe1\x3f\x48\x8b\xc2\x48\xc1\xf8\x06\x48\xc1\xe1\x06\x49\x8b\x04\xc0\xf6\x44\x08\x38\x01\x74\x2d\x48\x8d\x44\x24\x40\x89\x54\x24\x50\x89\x54\x24\x58\x4c\x8d\x4c\x24\x50\x48\x8d\x54\x24\x58\x48\x89\x44\x24\x20\x4c\x8d\x44\x24\x20\x48\x8d\x4c\x24\x48\xe8\xfd\xfe\xff\xff\xeb\x13\xe8\xe2\xc1\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\xb7\xc0\xff\xff\x83\xc8\xff\x48\x83\xc4\x38\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8b\xec\x48\x81\xec\x80\x00\x00\x00\x48\x8b\x05\x37\xfd\x00\x00\x48\x33\xc4\x48\x89\x45\xf0\x48\x63\xf2\x48\x8d\x05\x66\x10\x01\x00\x4c\x8b\xfe\x45\x8b\xe1\x49\xc1\xff\x06\x83\xe6\x3f\x48\xc1\xe6\x06\x4d\x8b\xf0\x4c\x89\x45\xd8\x48\x8b\xd9\x4d\x03\xe0\x4a\x8b\x04\xf8\x48\x8b\x44\x30\x28\x48\x89\x45\xd0\xff\x15\x5d\x5d\x00\x00\x33\xd2\x89\x45\xcc\x48\x89\x13\x49\x8b\xfe\x89\x53\x08\x4d\x3b\xf4\x0f\x83\x64\x01\x00\x00\x44\x8a\x2f\x4c\x8d\x35\x14\x10\x01\x00\x66\x89\x55\xc0\x4b\x8b\x14\xfe\x8a\x4c\x32\x3d\xf6\xc1\x04\x74\x1e\x8a\x44\x32\x3e\x80\xe1\xfb\x88\x4c\x32\x3d\x41\xb8\x02\x00\x00\x00\x48\x8d\x55\xe0\x88\x45\xe0\x44\x88\x6d\xe1\xeb\x45\xe8\xfc\xfa\xff\xff\x0f\xb6\x0f\xba\x00\x80\x00\x00\x66\x85\x14\x48\x74\x29\x49\x3b\xfc\x0f\x83\xef\x00\x00\x00\x41\xb8\x02\x00\x00\x00\x48\x8d\x4d\xc0\x48\x8b\xd7\xe8\xb7\xcf\xff\xff\x83\xf8\xff\x0f\x84\xf4\x00\x00\x00\x48\xff\xc7\xeb\x1b\x41\xb8\x01\x00\x00\x00\x48\x8b\xd7\x48\x8d\x4d\xc0\xe8\x97\xcf\xff\xff\x83\xf8\xff\x0f\x84\xd4\x00\x00\x00\x48\x83\x64\x24\x38\x00\x48\x8d\x45\xe8\x48\x83\x64\x24\x30\x00\x4c\x8d\x45\xc0\x8b\x4d\xcc\x41\xb9\x01\x00\x00\x00\xc7\x44\x24\x28\x05\x00\x00\x00\x33\xd2\x48\x89\x44\x24\x20\x48\xff\xc7\xff\x15\xc1\x5d\x00\x00\x44\x8b\xf0\x85\xc0\x0f\x84\x94\x00\x00\x00\x48\x8b\x4d\xd0\x4c\x8d\x4d\xc8\x48\x83\x64\x24\x20\x00\x48\x8d\x55\xe8\x44\x8b\xc0\xff\x15\x63\x5c\x00\x00\x33\xd2\x85\xc0\x74\x6b\x8b\x4b\x08\x2b\x4d\xd8\x03\xcf\x89\x4b\x04\x44\x39\x75\xc8\x72\x62\x41\x80\xfd\x0a\x75\x34\x48\x8b\x4d\xd0\x8d\x42\x0d\x48\x89\x54\x24\x20\x44\x8d\x42\x01\x48\x8d\x55\xc4\x66\x89\x45\xc4\x4c\x8d\x4d\xc8\xff\x15\x24\x5c\x00\x00\x33\xd2\x85\xc0\x74\x2c\x83\x7d\xc8\x01\x72\x2e\xff\x43\x08\xff\x43\x04\x49\x3b\xfc\xe9\xb6\xfe\xff\xff\x8a\x07\x4b\x8b\x0c\xfe\x88\x44\x31\x3e\x4b\x8b\x04\xfe\x80\x4c\x30\x3d\x04\xff\x43\x04\xeb\x08\xff\x15\x84\x5d\x00\x00\x89\x03\x48\x8b\xc3\x48\x8b\x4d\xf0\x48\x33\xcc\xe8\x9b\x74\xff\xff\x48\x8b\x9c\x24\xc0\x00\x00\x00\x48\x81\xc4\x80\x00\x00\x00\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\x5e\x5d\xc3\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x18\x56\x57\x41\x56\xb8\x50\x14\x00\x00\xe8\x78\x4d\x00\x00\x48\x2b\xe0\x48\x8b\x05\x2e\xfb\x00\x00\x48\x33\xc4\x48\x89\x84\x24\x40\x14\x00\x00\x48\x8b\xd9\x4c\x63\xd2\x49\x8b\xc2\x41\x8b\xe9\x48\xc1\xf8\x06\x48\x8d\x0d\x4c\x0e\x01\x00\x41\x83\xe2\x3f\x49\x03\xe8\x83\x23\x00\x49\x8b\xf0\x83\x63\x04\x00\x48\x8b\x04\xc1\x83\x63\x08\x00\x49\xc1\xe2\x06\x4e\x8b\x74\x10\x28\x4c\x3b\xc5\x73\x6f\x48\x8d\x7c\x24\x40\x48\x3b\xf5\x73\x24\x8a\x06\x48\xff\xc6\x3c\x0a\x75\x09\xff\x43\x08\xc6\x07\x0d\x48\xff\xc7\x88\x07\x48\xff\xc7\x48\x8d\x84\x24\x3f\x14\x00\x00\x48\x3b\xf8\x72\xd7\x48\x83\x64\x24\x20\x00\x48\x8d\x44\x24\x40\x2b\xf8\x4c\x8d\x4c\x24\x30\x44\x8b\xc7\x48\x8d\x54\x24\x40\x49\x8b\xce\xff\x15\x04\x5b\x00\x00\x85\xc0\x74\x12\x8b\x44\x24\x30\x01\x43\x04\x3b\xc7\x72\x0f\x48\x3b\xf5\x72\x9b\xeb\x08\xff\x15\x80\x5c\x00\x00\x89\x03\x48\x8b\xc3\x48\x8b\x8c\x24\x40\x14\x00\x00\x48\x33\xcc\xe8\x93\x73\xff\xff\x4c\x8d\x9c\x24\x50\x14\x00\x00\x49\x8b\x5b\x20\x49\x8b\x6b\x30\x49\x8b\xe3\x41\x5e\x5f\x5e\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x18\x56\x57\x41\x56\xb8\x50\x14\x00\x00\xe8\x70\x4c\x00\x00\x48\x2b\xe0\x48\x8b\x05\x26\xfa\x00\x00\x48\x33\xc4\x48\x89\x84\x24\x40\x14\x00\x00\x48\x8b\xf9\x4c\x63\xd2\x49\x8b\xc2\x41\x8b\xe9\x48\xc1\xf8\x06\x48\x8d\x0d\x44\x0d\x01\x00\x41\x83\xe2\x3f\x49\x03\xe8\x83\x27\x00\x49\x8b\xf0\x83\x67\x04\x00\x48\x8b\x04\xc1\x83\x67\x08\x00\x49\xc1\xe2\x06\x4e\x8b\x74\x10\x28\x4c\x3b\xc5\x0f\x83\x82\x00\x00\x00\x48\x8d\x5c\x24\x40\x48\x3b\xf5\x73\x31\x0f\xb7\x06\x48\x83\xc6\x02\x66\x83\xf8\x0a\x75\x10\x83\x47\x08\x02\xb9\x0d\x00\x00\x00\x66\x89\x0b\x48\x83\xc3\x02\x66\x89\x03\x48\x83\xc3\x02\x48\x8d\x84\x24\x3e\x14\x00\x00\x48\x3b\xd8\x72\xca\x48\x83\x64\x24\x20\x00\x48\x8d\x44\x24\x40\x48\x2b\xd8\x4c\x8d\x4c\x24\x30\x48\xd1\xfb\x48\x8d\x54\x24\x40\x03\xdb\x49\x8b\xce\x44\x8b\xc3\xff\x15\xe5\x59\x00\x00\x85\xc0\x74\x12\x8b\x44\x24\x30\x01\x47\x04\x3b\xc3\x72\x0f\x48\x3b\xf5\x72\x88\xeb\x08\xff\x15\x61\x5b\x00\x00\x89\x07\x48\x8b\xc7\x48\x8b\x8c\x24\x40\x14\x00\x00\x48\x33\xcc\xe8\x74\x72\xff\xff\x4c\x8d\x9c\x24\x50\x14\x00\x00\x49\x8b\x5b\x20\x49\x8b\x6b\x30\x49\x8b\xe3\x41\x5e\x5f\x5e\xc3\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x18\x56\x57\x41\x54\x41\x56\x41\x57\xb8\x70\x14\x00\x00\xe8\x50\x4b\x00\x00\x48\x2b\xe0\x48\x8b\x05\x06\xf9\x00\x00\x48\x33\xc4\x48\x89\x84\x24\x60\x14\x00\x00\x4c\x63\xd2\x48\x8b\xd9\x49\x8b\xc2\x45\x8b\xf1\x48\xc1\xf8\x06\x48\x8d\x0d\x24\x0c\x01\x00\x41\x83\xe2\x3f\x4d\x03\xf0\x49\xc1\xe2\x06\x4d\x8b\xf8\x49\x8b\xf8\x48\x8b\x04\xc1\x4e\x8b\x64\x10\x28\x33\xc0\x83\x23\x00\x48\x89\x43\x04\x4d\x3b\xc6\x0f\x83\xcf\x00\x00\x00\x48\x8d\x44\x24\x50\x49\x3b\xfe\x73\x2d\x0f\xb7\x0f\x48\x83\xc7\x02\x66\x83\xf9\x0a\x75\x0c\xba\x0d\x00\x00\x00\x66\x89\x10\x48\x83\xc0\x02\x66\x89\x08\x48\x83\xc0\x02\x48\x8d\x8c\x24\xf8\x06\x00\x00\x48\x3b\xc1\x72\xce\x48\x83\x64\x24\x38\x00\x48\x8d\x4c\x24\x50\x48\x83\x64\x24\x30\x00\x4c\x8d\x44\x24\x50\x48\x2b\xc1\xc7\x44\x24\x28\x55\x0d\x00\x00\x48\x8d\x8c\x24\x00\x07\x00\x00\x48\xd1\xf8\x48\x89\x4c\x24\x20\x44\x8b\xc8\xb9\xe9\xfd\x00\x00\x33\xd2\xff\x15\xe8\x59\x00\x00\x8b\xe8\x85\xc0\x74\x49\x33\xf6\x85\xc0\x74\x33\x48\x83\x64\x24\x20\x00\x48\x8d\x94\x24\x00\x07\x00\x00\x8b\xce\x4c\x8d\x4c\x24\x40\x44\x8b\xc5\x48\x03\xd1\x49\x8b\xcc\x44\x2b\xc6\xff\x15\x7d\x58\x00\x00\x85\xc0\x74\x18\x03\x74\x24\x40\x3b\xf5\x72\xcd\x8b\xc7\x41\x2b\xc7\x89\x43\x04\x49\x3b\xfe\xe9\x33\xff\xff\xff\xff\x15\xf3\x59\x00\x00\x89\x03\x48\x8b\xc3\x48\x8b\x8c\x24\x60\x14\x00\x00\x48\x33\xcc\xe8\x06\x71\xff\xff\x4c\x8d\x9c\x24\x70\x14\x00\x00\x49\x8b\x5b\x30\x49\x8b\x6b\x40\x49\x8b\xe3\x41\x5f\x41\x5e\x41\x5c\x5f\x5e\xc3\xcc\xcc\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x18\x89\x4c\x24\x08\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x20\x45\x8b\xf8\x4c\x8b\xe2\x48\x63\xd9\x83\xfb\xfe\x75\x18\xe8\xde\xbb\xff\xff\x83\x20\x00\xe8\xf6\xbb\xff\xff\xc7\x00\x09\x00\x00\x00\xe9\x90\x00\x00\x00\x85\xc9\x78\x74\x3b\x1d\xad\x0e\x01\x00\x73\x6c\x48\x8b\xf3\x4c\x8b\xf3\x49\xc1\xfe\x06\x4c\x8d\x2d\x9a\x0a\x01\x00\x83\xe6\x3f\x48\xc1\xe6\x06\x4b\x8b\x44\xf5\x00\x0f\xb6\x4c\x30\x38\x83\xe1\x01\x74\x45\x8b\xcb\xe8\xf5\x04\x00\x00\x83\xcf\xff\x4b\x8b\x44\xf5\x00\xf6\x44\x30\x38\x01\x75\x15\xe8\x9d\xbb\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x72\xbb\xff\xff\x83\x20\x00\xeb\x0f\x45\x8b\xc7\x49\x8b\xd4\x8b\xcb\xe8\x40\x00\x00\x00\x8b\xf8\x8b\xcb\xe8\xdf\x04\x00\x00\x8b\xc7\xeb\x1b\xe8\x4e\xbb\xff\xff\x83\x20\x00\xe8\x66\xbb\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x3b\xba\xff\xff\x83\xc8\xff\x48\x8b\x5c\x24\x58\x48\x8b\x74\x24\x60\x48\x83\xc4\x20\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\xc3\x48\x89\x5c\x24\x20\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8b\xec\x48\x83\xec\x60\x33\xff\x45\x8b\xf8\x4c\x63\xe1\x48\x8b\xf2\x45\x85\xc0\x75\x07\x33\xc0\xe9\x9b\x02\x00\x00\x48\x85\xd2\x75\x1f\xe8\xe8\xba\xff\xff\x89\x38\xe8\x01\xbb\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\xd6\xb9\xff\xff\x83\xc8\xff\xe9\x77\x02\x00\x00\x4d\x8b\xf4\x48\x8d\x05\xb0\x09\x01\x00\x41\x83\xe6\x3f\x4d\x8b\xec\x49\xc1\xfd\x06\x49\xc1\xe6\x06\x4c\x89\x6d\xf0\x4a\x8b\x0c\xe8\x42\x8a\x5c\x31\x39\x8d\x43\xff\x3c\x01\x77\x09\x41\x8b\xc7\xf7\xd0\xa8\x01\x74\xab\x42\xf6\x44\x31\x38\x20\x74\x0e\x33\xd2\x41\x8b\xcc\x44\x8d\x42\x02\xe8\x8e\x32\x00\x00\x41\x8b\xcc\x48\x89\x7d\xe0\xe8\x12\x29\x00\x00\x85\xc0\x0f\x84\x01\x01\x00\x00\x48\x8d\x05\x53\x09\x01\x00\x4a\x8b\x04\xe8\x42\xf6\x44\x30\x38\x80\x0f\x84\xea\x00\x00\x00\xe8\xe6\xd1\xff\xff\x48\x8b\x88\x90\x00\x00\x00\x48\x39\xb9\x38\x01\x00\x00\x75\x16\x48\x8d\x05\x27\x09\x01\x00\x4a\x8b\x04\xe8\x42\x38\x7c\x30\x39\x0f\x84\xbf\x00\x00\x00\x48\x8d\x05\x11\x09\x01\x00\x4a\x8b\x0c\xe8\x48\x8d\x55\xf8\x4a\x8b\x4c\x31\x28\xff\x15\x1e\x56\x00\x00\x85\xc0\x0f\x84\x9d\x00\x00\x00\x84\xdb\x74\x7b\xfe\xcb\x80\xfb\x01\x0f\x87\x2b\x01\x00\x00\x21\x7d\xd0\x4e\x8d\x24\x3e\x33\xdb\x4c\x8b\xfe\x89\x5d\xd4\x49\x3b\xf4\x0f\x83\x09\x01\x00\x00\x45\x0f\xb7\x2f\x41\x0f\xb7\xcd\xe8\xea\x31\x00\x00\x66\x41\x3b\xc5\x75\x33\x83\xc3\x02\x89\x5d\xd4\x66\x41\x83\xfd\x0a\x75\x1b\x41\xbd\x0d\x00\x00\x00\x41\x8b\xcd\xe8\xc9\x31\x00\x00\x66\x41\x3b\xc5\x75\x12\xff\xc3\x89\x5d\xd4\xff\xc7\x49\x83\xc7\x02\x4d\x3b\xfc\x73\x0b\xeb\xba\xff\x15\x4b\x57\x00\x00\x89\x45\xd0\x4c\x8b\x6d\xf0\xe9\xb1\x00\x00\x00\x45\x8b\xcf\x48\x8d\x4d\xd0\x4c\x8b\xc6\x41\x8b\xd4\xe8\xcd\xf7\xff\xff\xf2\x0f\x10\x00\x8b\x78\x08\xe9\x98\x00\x00\x00\x48\x8d\x05\x52\x08\x01\x00\x4a\x8b\x0c\xe8\x42\xf6\x44\x31\x38\x80\x74\x4d\x0f\xbe\xcb\x84\xdb\x74\x32\x83\xe9\x01\x74\x19\x83\xf9\x01\x75\x79\x45\x8b\xcf\x48\x8d\x4d\xd0\x4c\x8b\xc6\x41\x8b\xd4\xe8\x9b\xfa\xff\xff\xeb\xbc\x45\x8b\xcf\x48\x8d\x4d\xd0\x4c\x8b\xc6\x41\x8b\xd4\xe8\xa3\xfb\xff\xff\xeb\xa8\x45\x8b\xcf\x48\x8d\x4d\xd0\x4c\x8b\xc6\x41\x8b\xd4\xe8\x6b\xf9\xff\xff\xeb\x94\x4a\x8b\x4c\x31\x28\x4c\x8d\x4d\xd4\x21\x7d\xd0\x33\xc0\x48\x21\x44\x24\x20\x45\x8b\xc7\x48\x8b\xd6\x48\x89\x45\xd4\xff\x15\x06\x55\x00\x00\x85\xc0\x75\x09\xff\x15\x94\x56\x00\x00\x89\x45\xd0\x8b\x7d\xd8\xf2\x0f\x10\x45\xd0\xf2\x0f\x11\x45\xe0\x48\x8b\x45\xe0\x48\xc1\xe8\x20\x85\xc0\x75\x68\x8b\x45\xe0\x85\xc0\x74\x2d\x83\xf8\x05\x75\x1b\xe8\xd3\xb8\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\xa8\xb8\xff\xff\xc7\x00\x05\x00\x00\x00\xe9\xc7\xfd\xff\xff\x8b\x4d\xe0\xe8\x45\xb8\xff\xff\xe9\xba\xfd\xff\xff\x48\x8d\x05\x75\x07\x01\x00\x4a\x8b\x04\xe8\x42\xf6\x44\x30\x38\x40\x74\x09\x80\x3e\x1a\x0f\x84\x7b\xfd\xff\xff\xe8\x8f\xb8\xff\xff\xc7\x00\x1c\x00\x00\x00\xe8\x64\xb8\xff\xff\x83\x20\x00\xe9\x86\xfd\xff\xff\x8b\x45\xe4\x2b\xc7\x48\x8b\x9c\x24\xb8\x00\x00\x00\x48\x83\xc4\x60\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\x5e\x5d\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\xba\x40\x00\x00\x00\x8b\xca\xe8\x58\xb1\xff\xff\x33\xf6\x48\x8b\xd8\x48\x85\xc0\x74\x4c\x48\x8d\xa8\x00\x10\x00\x00\x48\x3b\xc5\x74\x3d\x48\x8d\x78\x30\x48\x8d\x4f\xd0\x45\x33\xc0\xba\xa0\x0f\x00\x00\xe8\x41\xbb\xff\xff\x48\x83\x4f\xf8\xff\x48\x89\x37\xc7\x47\x08\x00\x00\x0a\x0a\xc6\x47\x0c\x0a\x80\x67\x0d\xf8\x40\x88\x77\x0e\x48\x8d\x7f\x40\x48\x8d\x47\xd0\x48\x3b\xc5\x75\xc7\x48\x8b\xf3\x33\xc9\xe8\xa3\xaf\xff\xff\x48\x8b\x5c\x24\x30\x48\x8b\xc6\x48\x8b\x74\x24\x40\x48\x8b\x6c\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x85\xc9\x74\x4a\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x8d\xb1\x00\x10\x00\x00\x48\x8b\xd9\x48\x8b\xf9\x48\x3b\xce\x74\x12\x48\x8b\xcf\xff\x15\xa9\x54\x00\x00\x48\x83\xc7\x40\x48\x3b\xfe\x75\xee\x48\x8b\xcb\xe8\x48\xaf\xff\xff\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7c\x24\x18\x41\x57\x48\x83\xec\x30\x8b\xf1\x33\xdb\x8b\xc3\x81\xf9\x00\x20\x00\x00\x0f\x92\xc0\x85\xc0\x75\x15\xe8\x47\xb7\xff\xff\xbb\x09\x00\x00\x00\x89\x18\xe8\x1b\xb6\xff\xff\x8b\xc3\xeb\x64\xb9\x07\x00\x00\x00\xe8\x19\xdf\xff\xff\x90\x48\x8b\xfb\x48\x89\x5c\x24\x20\x8b\x05\xea\x09\x01\x00\x3b\xf0\x7c\x3b\x4c\x8d\x3d\xdf\x05\x01\x00\x49\x39\x1c\xff\x74\x02\xeb\x22\xe8\xaa\xfe\xff\xff\x49\x89\x04\xff\x48\x85\xc0\x75\x05\x8d\x58\x0c\xeb\x19\x8b\x05\xbe\x09\x01\x00\x83\xc0\x40\x89\x05\xb5\x09\x01\x00\x48\xff\xc7\x48\x89\x7c\x24\x20\xeb\xc1\xb9\x07\x00\x00\x00\xe8\x15\xdf\xff\xff\xeb\x98\x48\x8b\x5c\x24\x40\x48\x8b\x74\x24\x48\x48\x8b\x7c\x24\x50\x48\x83\xc4\x30\x41\x5f\xc3\xcc\x48\x63\xc9\x48\x8d\x15\x7e\x05\x01\x00\x48\x8b\xc1\x83\xe1\x3f\x48\xc1\xf8\x06\x48\xc1\xe1\x06\x48\x03\x0c\xc2\x48\xff\x25\x9d\x53\x00\x00\xcc\x48\x63\xc9\x48\x8d\x15\x5a\x05\x01\x00\x48\x8b\xc1\x83\xe1\x3f\x48\xc1\xf8\x06\x48\xc1\xe1\x06\x48\x03\x0c\xc2\x48\xff\x25\x81\x53\x00\x00\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x48\x89\x7c\x24\x18\x41\x56\x48\x83\xec\x20\x48\x63\xd9\x85\xc9\x78\x72\x3b\x1d\x1e\x09\x01\x00\x73\x6a\x48\x8b\xfb\x4c\x8d\x35\x12\x05\x01\x00\x83\xe7\x3f\x48\x8b\xf3\x48\xc1\xfe\x06\x48\xc1\xe7\x06\x49\x8b\x04\xf6\xf6\x44\x38\x38\x01\x74\x47\x48\x83\x7c\x38\x28\xff\x74\x3f\xe8\x70\x2e\x00\x00\x83\xf8\x01\x75\x27\x85\xdb\x74\x16\x2b\xd8\x74\x0b\x3b\xd8\x75\x1b\xb9\xf4\xff\xff\xff\xeb\x0c\xb9\xf5\xff\xff\xff\xeb\x05\xb9\xf6\xff\xff\xff\x33\xd2\xff\x15\xd8\x51\x00\x00\x49\x8b\x04\xf6\x48\x83\x4c\x38\x28\xff\x33\xc0\xeb\x16\xe8\xe1\xb5\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\xb6\xb5\xff\xff\x83\x20\x00\x83\xc8\xff\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x8b\x7c\x24\x40\x48\x83\xc4\x20\x41\x5e\xc3\xcc\xcc\x48\x83\xec\x28\x83\xf9\xfe\x75\x15\xe8\x8a\xb5\xff\xff\x83\x20\x00\xe8\xa2\xb5\xff\xff\xc7\x00\x09\x00\x00\x00\xeb\x4e\x85\xc9\x78\x32\x3b\x0d\x5c\x08\x01\x00\x73\x2a\x48\x63\xd1\x48\x8d\x0d\x50\x04\x01\x00\x48\x8b\xc2\x83\xe2\x3f\x48\xc1\xf8\x06\x48\xc1\xe2\x06\x48\x8b\x04\xc1\xf6\x44\x10\x38\x01\x74\x07\x48\x8b\x44\x10\x28\xeb\x1c\xe8\x3f\xb5\xff\xff\x83\x20\x00\xe8\x57\xb5\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x2c\xb4\xff\xff\x48\x83\xc8\xff\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\x40\x53\x48\x83\xec\x40\x8b\xd9\x48\x8d\x4c\x24\x20\xe8\x1a\x8c\xff\xff\x48\x8b\x44\x24\x28\x0f\xb6\xd3\x48\x8b\x08\x0f\xb7\x04\x51\x25\x00\x80\x00\x00\x80\x7c\x24\x38\x00\x74\x0c\x48\x8b\x4c\x24\x20\x83\xa1\xa8\x03\x00\x00\xfd\x48\x83\xc4\x40\x5b\xc3\xcc\x40\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x60\x48\x8d\x6c\x24\x50\x48\x89\x5d\x40\x48\x89\x75\x48\x48\x89\x7d\x50\x48\x8b\x05\x66\xf0\x00\x00\x48\x33\xc5\x48\x89\x45\x08\x48\x63\x5d\x60\x4d\x8b\xf9\x48\x89\x55\x00\x45\x8b\xe8\x48\x8b\xf9\x85\xdb\x7e\x14\x48\x8b\xd3\x49\x8b\xc9\xe8\x0b\x2d\x00\x00\x3b\xc3\x8d\x58\x01\x7c\x02\x8b\xd8\x44\x8b\x75\x78\x45\x85\xf6\x75\x07\x48\x8b\x07\x44\x8b\x70\x0c\xf7\x9d\x80\x00\x00\x00\x44\x8b\xcb\x4d\x8b\xc7\x41\x8b\xce\x1b\xd2\x83\x64\x24\x28\x00\x48\x83\x64\x24\x20\x00\x83\xe2\x08\xff\xc2\xff\x15\x9f\x51\x00\x00\x4c\x63\xe0\x85\xc0\x0f\x84\x7b\x02\x00\x00\x49\x8b\xd4\x49\xb8\xf0\xff\xff\xff\xff\xff\xff\x0f\x48\x03\xd2\x48\x8d\x4a\x10\x48\x3b\xd1\x48\x1b\xc0\x48\x85\xc1\x74\x72\x48\x8d\x4a\x10\x48\x3b\xd1\x48\x1b\xc0\x48\x23\xc1\x48\x3d\x00\x04\x00\x00\x48\x8d\x42\x10\x77\x37\x48\x3b\xd0\x48\x1b\xc9\x48\x23\xc8\x48\x8d\x41\x0f\x48\x3b\xc1\x77\x03\x49\x8b\xc0\x48\x83\xe0\xf0\xe8\xde\x41\x00\x00\x48\x2b\xe0\x48\x8d\x74\x24\x50\x48\x85\xf6\x0f\x84\xfa\x01\x00\x00\xc7\x06\xcc\xcc\x00\x00\xeb\x1c\x48\x3b\xd0\x48\x1b\xc9\x48\x23\xc8\xe8\xef\xab\xff\xff\x48\x8b\xf0\x48\x85\xc0\x74\x0e\xc7\x00\xdd\xdd\x00\x00\x48\x83\xc6\x10\xeb\x02\x33\xf6\x48\x85\xf6\x0f\x84\xc5\x01\x00\x00\x44\x89\x64\x24\x28\x44\x8b\xcb\x4d\x8b\xc7\x48\x89\x74\x24\x20\xba\x01\x00\x00\x00\x41\x8b\xce\xff\x15\xda\x50\x00\x00\x85\xc0\x0f\x84\x9f\x01\x00\x00\x48\x83\x64\x24\x40\x00\x45\x8b\xcc\x48\x83\x64\x24\x38\x00\x4c\x8b\xc6\x48\x83\x64\x24\x30\x00\x41\x8b\xd5\x4c\x8b\x7d\x00\x83\x64\x24\x28\x00\x49\x8b\xcf\x48\x83\x64\x24\x20\x00\xe8\x1c\xb7\xff\xff\x48\x63\xf8\x85\xc0\x0f\x84\x62\x01\x00\x00\x41\xb8\x00\x04\x00\x00\x45\x85\xe8\x74\x52\x8b\x45\x70\x85\xc0\x0f\x84\x4e\x01\x00\x00\x3b\xf8\x0f\x8f\x44\x01\x00\x00\x48\x83\x64\x24\x40\x00\x45\x8b\xcc\x48\x83\x64\x24\x38\x00\x4c\x8b\xc6\x48\x83\x64\x24\x30\x00\x41\x8b\xd5\x89\x44\x24\x28\x49\x8b\xcf\x48\x8b\x45\x68\x48\x89\x44\x24\x20\xe8\xc3\xb6\xff\xff\x8b\xf8\x85\xc0\x0f\x85\x0c\x01\x00\x00\xe9\x05\x01\x00\x00\x48\x8b\xd7\x48\x03\xd2\x48\x8d\x4a\x10\x48\x3b\xd1\x48\x1b\xc0\x48\x85\xc1\x74\x76\x48\x8d\x4a\x10\x48\x3b\xd1\x48\x1b\xc0\x48\x23\xc1\x49\x3b\xc0\x48\x8d\x42\x10\x77\x3e\x48\x3b\xd0\x48\x1b\xc9\x48\x23\xc8\x48\x8d\x41\x0f\x48\x3b\xc1\x77\x0a\x48\xb8\xf0\xff\xff\xff\xff\xff\xff\x0f\x48\x83\xe0\xf0\xe8\x88\x40\x00\x00\x48\x2b\xe0\x48\x8d\x5c\x24\x50\x48\x85\xdb\x0f\x84\xa4\x00\x00\x00\xc7\x03\xcc\xcc\x00\x00\xeb\x1c\x48\x3b\xd0\x48\x1b\xc9\x48\x23\xc8\xe8\x99\xaa\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x0e\xc7\x00\xdd\xdd\x00\x00\x48\x83\xc3\x10\xeb\x02\x33\xdb\x48\x85\xdb\x74\x73\x48\x83\x64\x24\x40\x00\x45\x8b\xcc\x48\x83\x64\x24\x38\x00\x4c\x8b\xc6\x48\x83\x64\x24\x30\x00\x41\x8b\xd5\x89\x7c\x24\x28\x49\x8b\xcf\x48\x89\x5c\x24\x20\xe8\xf6\xb5\xff\xff\x85\xc0\x74\x32\x48\x83\x64\x24\x38\x00\x33\xd2\x48\x21\x54\x24\x30\x44\x8b\xcf\x8b\x45\x70\x4c\x8b\xc3\x41\x8b\xce\x85\xc0\x75\x66\x21\x54\x24\x28\x48\x21\x54\x24\x20\xff\x15\x52\x4f\x00\x00\x8b\xf8\x85\xc0\x75\x60\x48\x8d\x4b\xf0\x81\x39\xdd\xdd\x00\x00\x75\x05\xe8\xcb\xa9\xff\xff\x33\xff\x48\x85\xf6\x74\x11\x48\x8d\x4e\xf0\x81\x39\xdd\xdd\x00\x00\x75\x05\xe8\xb3\xa9\xff\xff\x8b\xc7\x48\x8b\x4d\x08\x48\x33\xcd\xe8\x9d\x66\xff\xff\x48\x8b\x5d\x40\x48\x8b\x75\x48\x48\x8b\x7d\x50\x48\x8d\x65\x10\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5d\xc3\x89\x44\x24\x28\x48\x8b\x45\x68\x48\x89\x44\x24\x20\xeb\x94\x48\x8d\x4b\xf0\x81\x39\xdd\xdd\x00\x00\x75\xa7\xe8\x6b\xa9\xff\xff\xeb\xa0\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x70\x48\x8b\xf2\x49\x8b\xd9\x48\x8b\xd1\x41\x8b\xf8\x48\x8d\x4c\x24\x50\xe8\x6b\x88\xff\xff\x8b\x84\x24\xc0\x00\x00\x00\x48\x8d\x4c\x24\x58\x89\x44\x24\x40\x4c\x8b\xcb\x8b\x84\x24\xb8\x00\x00\x00\x44\x8b\xc7\x89\x44\x24\x38\x48\x8b\xd6\x8b\x84\x24\xb0\x00\x00\x00\x89\x44\x24\x30\x48\x8b\x84\x24\xa8\x00\x00\x00\x48\x89\x44\x24\x28\x8b\x84\x24\xa0\x00\x00\x00\x89\x44\x24\x20\xe8\x33\xfc\xff\xff\x80\x7c\x24\x68\x00\x74\x0c\x48\x8b\x4c\x24\x50\x83\xa1\xa8\x03\x00\x00\xfd\x4c\x8d\x5c\x24\x70\x49\x8b\x5b\x10\x49\x8b\x73\x18\x49\x8b\xe3\x5f\xc3\xcc\xcc\xf0\xff\x41\x10\x48\x8b\x81\xe0\x00\x00\x00\x48\x85\xc0\x74\x03\xf0\xff\x00\x48\x8b\x81\xf0\x00\x00\x00\x48\x85\xc0\x74\x03\xf0\xff\x00\x48\x8b\x81\xe8\x00\x00\x00\x48\x85\xc0\x74\x03\xf0\xff\x00\x48\x8b\x81\x00\x01\x00\x00\x48\x85\xc0\x74\x03\xf0\xff\x00\x48\x8d\x41\x38\x41\xb8\x06\x00\x00\x00\x48\x8d\x15\xaf\xef\x00\x00\x48\x39\x50\xf0\x74\x0b\x48\x8b\x10\x48\x85\xd2\x74\x03\xf0\xff\x02\x48\x83\x78\xe8\x00\x74\x0c\x48\x8b\x50\xf8\x48\x85\xd2\x74\x03\xf0\xff\x02\x48\x83\xc0\x20\x49\x83\xe8\x01\x75\xcb\x48\x8b\x89\x20\x01\x00\x00\xe9\x79\x01\x00\x00\xcc\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xec\x20\x48\x8b\x81\xf8\x00\x00\x00\x48\x8b\xd9\x48\x85\xc0\x74\x79\x48\x8d\x0d\xa2\xf4\x00\x00\x48\x3b\xc1\x74\x6d\x48\x8b\x83\xe0\x00\x00\x00\x48\x85\xc0\x74\x61\x83\x38\x00\x75\x5c\x48\x8b\x8b\xf0\x00\x00\x00\x48\x85\xc9\x74\x16\x83\x39\x00\x75\x11\xe8\xee\xa7\xff\xff\x48\x8b\x8b\xf8\x00\x00\x00\xe8\xfa\x1e\x00\x00\x48\x8b\x8b\xe8\x00\x00\x00\x48\x85\xc9\x74\x16\x83\x39\x00\x75\x11\xe8\xcc\xa7\xff\xff\x48\x8b\x8b\xf8\x00\x00\x00\xe8\xe4\x1f\x00\x00\x48\x8b\x8b\xe0\x00\x00\x00\xe8\xb4\xa7\xff\xff\x48\x8b\x8b\xf8\x00\x00\x00\xe8\xa8\xa7\xff\xff\x48\x8b\x83\x00\x01\x00\x00\x48\x85\xc0\x74\x47\x83\x38\x00\x75\x42\x48\x8b\x8b\x08\x01\x00\x00\x48\x81\xe9\xfe\x00\x00\x00\xe8\x84\xa7\xff\xff\x48\x8b\x8b\x10\x01\x00\x00\xbf\x80\x00\x00\x00\x48\x2b\xcf\xe8\x70\xa7\xff\xff\x48\x8b\x8b\x18\x01\x00\x00\x48\x2b\xcf\xe8\x61\xa7\xff\xff\x48\x8b\x8b\x00\x01\x00\x00\xe8\x55\xa7\xff\xff\x48\x8b\x8b\x20\x01\x00\x00\xe8\xa5\x00\x00\x00\x48\x8d\xb3\x28\x01\x00\x00\xbd\x06\x00\x00\x00\x48\x8d\x7b\x38\x48\x8d\x05\x62\xee\x00\x00\x48\x39\x47\xf0\x74\x1a\x48\x8b\x0f\x48\x85\xc9\x74\x12\x83\x39\x00\x75\x0d\xe8\x1a\xa7\xff\xff\x48\x8b\x0e\xe8\x12\xa7\xff\xff\x48\x83\x7f\xe8\x00\x74\x13\x48\x8b\x4f\xf8\x48\x85\xc9\x74\x0a\x83\x39\x00\x75\x05\xe8\xf8\xa6\xff\xff\x48\x83\xc6\x08\x48\x83\xc7\x20\x48\x83\xed\x01\x75\xb1\x48\x8b\xcb\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x8b\x74\x24\x40\x48\x83\xc4\x20\x5f\xe9\xce\xa6\xff\xff\xcc\xcc\x48\x85\xc9\x74\x1c\x48\x8d\x05\x58\x63\x00\x00\x48\x3b\xc8\x74\x10\xb8\x01\x00\x00\x00\xf0\x0f\xc1\x81\x5c\x01\x00\x00\xff\xc0\xc3\xb8\xff\xff\xff\x7f\xc3\xcc\x48\x85\xc9\x74\x30\x53\x48\x83\xec\x20\x48\x8d\x05\x2b\x63\x00\x00\x48\x8b\xd9\x48\x3b\xc8\x74\x17\x8b\x81\x5c\x01\x00\x00\x85\xc0\x75\x0d\xe8\x64\x1f\x00\x00\x48\x8b\xcb\xe8\x74\xa6\xff\xff\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\x48\x85\xc9\x74\x1a\x48\x8d\x05\xf8\x62\x00\x00\x48\x3b\xc8\x74\x0e\x83\xc8\xff\xf0\x0f\xc1\x81\x5c\x01\x00\x00\xff\xc8\xc3\xb8\xff\xff\xff\x7f\xc3\xcc\xcc\xcc\x48\x83\xec\x28\x48\x85\xc9\x0f\x84\x96\x00\x00\x00\x41\x83\xc9\xff\xf0\x44\x01\x49\x10\x48\x8b\x81\xe0\x00\x00\x00\x48\x85\xc0\x74\x04\xf0\x44\x01\x08\x48\x8b\x81\xf0\x00\x00\x00\x48\x85\xc0\x74\x04\xf0\x44\x01\x08\x48\x8b\x81\xe8\x00\x00\x00\x48\x85\xc0\x74\x04\xf0\x44\x01\x08\x48\x8b\x81\x00\x01\x00\x00\x48\x85\xc0\x74\x04\xf0\x44\x01\x08\x48\x8d\x41\x38\x41\xb8\x06\x00\x00\x00\x48\x8d\x15\x0d\xed\x00\x00\x48\x39\x50\xf0\x74\x0c\x48\x8b\x10\x48\x85\xd2\x74\x04\xf0\x44\x01\x0a\x48\x83\x78\xe8\x00\x74\x0d\x48\x8b\x50\xf8\x48\x85\xd2\x74\x04\xf0\x44\x01\x0a\x48\x83\xc0\x20\x49\x83\xe8\x01\x75\xc9\x48\x8b\x89\x20\x01\x00\x00\xe8\x35\xff\xff\xff\x48\x83\xc4\x28\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\xe8\x3d\xc5\xff\xff\x48\x8b\xf8\x8b\x0d\xfc\xf1\x00\x00\x85\x88\xa8\x03\x00\x00\x74\x0c\x48\x8b\x98\x90\x00\x00\x00\x48\x85\xdb\x75\x36\xb9\x04\x00\x00\x00\xe8\x8e\xd5\xff\xff\x90\x48\x8d\x8f\x90\x00\x00\x00\x48\x8b\x15\x87\x00\x01\x00\xe8\x26\x00\x00\x00\x48\x8b\xd8\xb9\x04\x00\x00\x00\xe8\xc1\xd5\xff\xff\x48\x85\xdb\x75\x06\xe8\x3b\xa6\xff\xff\xcc\x48\x8b\xc3\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xfa\x48\x85\xd2\x74\x49\x48\x85\xc9\x74\x44\x48\x8b\x19\x48\x3b\xda\x75\x05\x48\x8b\xc2\xeb\x39\x48\x89\x11\x48\x8b\xca\xe8\x2d\xfc\xff\xff\x48\x85\xdb\x74\x22\x48\x8b\xcb\xe8\xac\xfe\xff\xff\x83\x7b\x10\x00\x75\x14\x48\x8d\x05\xab\xea\x00\x00\x48\x3b\xd8\x74\x08\x48\x8b\xcb\xe8\x92\xfc\xff\xff\x48\x8b\xc7\xeb\x02\x33\xc0\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\x40\x53\x48\x83\xec\x20\x33\xdb\x48\x85\xc9\x75\x18\xe8\xee\xac\xff\xff\xbb\x16\x00\x00\x00\x89\x18\xe8\xc2\xab\xff\xff\x8b\xc3\xe9\x94\x00\x00\x00\x48\x85\xd2\x74\xe3\x45\x85\xc0\x88\x19\x8b\xc3\x41\x0f\x4f\xc0\xff\xc0\x48\x98\x48\x3b\xd0\x77\x0c\xe8\xbd\xac\xff\xff\xbb\x22\x00\x00\x00\xeb\xcd\x4d\x85\xc9\x74\xbe\x49\x8b\x51\x08\x48\x8d\x41\x01\xc6\x01\x30\xeb\x19\x44\x8a\x12\x45\x84\xd2\x74\x05\x48\xff\xc2\xeb\x03\x41\xb2\x30\x44\x88\x10\x48\xff\xc0\x41\xff\xc8\x45\x85\xc0\x7f\xe2\x88\x18\x78\x14\x80\x3a\x35\x7c\x0f\xeb\x03\xc6\x00\x30\x48\xff\xc8\x80\x38\x39\x74\xf5\xfe\x00\x80\x39\x31\x75\x06\x41\xff\x41\x04\xeb\x1a\x49\x83\xc8\xff\x49\xff\xc0\x42\x38\x5c\x01\x01\x75\xf6\x49\xff\xc0\x48\x8d\x51\x01\xe8\x85\x3a\x00\x00\x33\xc0\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x89\x54\x24\x10\x56\x57\x48\x81\xec\x48\x02\x00\x00\x44\x8b\x09\x48\x8b\xfa\x48\x8b\xf1\x45\x85\xc9\x75\x0c\x33\xc0\x48\x81\xc4\x48\x02\x00\x00\x5f\x5e\xc3\x8b\x02\x85\xc0\x74\xee\x48\x89\x9c\x24\x40\x02\x00\x00\x41\xff\xc9\x48\x89\xac\x24\x38\x02\x00\x00\x4c\x89\xa4\x24\x30\x02\x00\x00\x4c\x89\xb4\x24\x20\x02\x00\x00\x4c\x89\xbc\x24\x18\x02\x00\x00\x83\xe8\x01\x0f\x85\xf2\x00\x00\x00\x44\x8b\x7a\x04\x45\x33\xf6\x41\x83\xff\x01\x75\x28\x8b\x59\x04\x4c\x8d\x44\x24\x44\x48\x83\xc1\x04\x44\x89\x36\x45\x33\xc9\x44\x89\x74\x24\x40\xba\xcc\x01\x00\x00\xe8\xac\x17\x00\x00\x8b\xc3\xe9\x05\x04\x00\x00\x45\x85\xc9\x75\x39\x8b\x59\x04\x4c\x8d\x44\x24\x44\x44\x89\x31\x45\x33\xc9\x48\x83\xc1\x04\x44\x89\x74\x24\x40\xba\xcc\x01\x00\x00\xe8\x7f\x17\x00\x00\x33\xd2\x8b\xc3\x41\xf7\xf7\x85\xd2\x89\x56\x04\x41\x0f\x95\xc6\x44\x89\x36\xe9\xc7\x03\x00\x00\x41\xbc\xff\xff\xff\xff\x49\x8b\xfe\x49\x8b\xee\x45\x3b\xcc\x74\x2f\x49\x8b\xcf\x0f\x1f\x80\x00\x00\x00\x00\x42\x8b\x44\x8e\x04\x33\xd2\x48\xc1\xe5\x20\x45\x03\xcc\x48\x0b\xc5\x48\xc1\xe7\x20\x48\xf7\xf1\x8b\xc0\x48\x8b\xea\x48\x03\xf8\x45\x3b\xcc\x75\xdb\x45\x33\xc9\x44\x89\x74\x24\x40\x4c\x8d\x44\x24\x44\x44\x89\x36\xba\xcc\x01\x00\x00\x48\x8d\x4e\x04\xe8\x09\x17\x00\x00\x48\x8b\xcd\x89\x6e\x04\x48\xc1\xe9\x20\x48\x8b\xc7\x85\xc9\x89\x4e\x08\x41\x0f\x95\xc6\x41\xff\xc6\x44\x89\x36\xe9\x48\x03\x00\x00\x41\x3b\xc1\x76\x07\x33\xc0\xe9\x3c\x03\x00\x00\x45\x8b\xc1\x49\x63\xd1\x44\x2b\xc0\x4c\x89\xac\x24\x28\x02\x00\x00\x49\x63\xd8\x44\x8d\x68\x01\x45\x8b\xd1\x48\x3b\xd3\x7c\x4c\x48\x83\xc1\x04\x48\x8d\x04\x9d\x00\x00\x00\x00\x4c\x8b\xdf\x4c\x2b\xd8\x4c\x2b\xde\x48\x8d\x0c\x91\x0f\x1f\x80\x00\x00\x00\x00\x8b\x01\x41\x39\x04\x0b\x75\x11\x41\xff\xca\x48\xff\xca\x48\x83\xe9\x04\x48\x3b\xd3\x7d\xe9\xeb\x13\x49\x63\xc2\x48\x8b\xc8\x48\x2b\xcb\x8b\x44\x86\x04\x39\x44\x8f\x04\x73\x03\x41\xff\xc0\x45\x85\xc0\x75\x07\x33\xc0\xe9\xb9\x02\x00\x00\x41\x8d\x45\xff\x41\xbb\x20\x00\x00\x00\x44\x8b\x54\x87\x04\x41\x8d\x45\xfe\x8b\x5c\x87\x04\x41\x0f\xbd\xc2\x89\x9c\x24\x78\x02\x00\x00\x74\x09\xba\x1f\x00\x00\x00\x2b\xd0\xeb\x03\x41\x8b\xd3\x44\x2b\xda\x89\x94\x24\x70\x02\x00\x00\x44\x89\x5c\x24\x20\x85\xd2\x74\x40\x41\x8b\xc2\x8b\xd3\x41\x8b\xcb\xd3\xea\x8b\x8c\x24\x70\x02\x00\x00\x44\x8b\xd2\xd3\xe0\x8b\xd1\xd3\xe3\x44\x0b\xd0\x89\x9c\x24\x78\x02\x00\x00\x41\x83\xfd\x02\x76\x16\x41\x8d\x45\xfd\x41\x8b\xcb\x8b\x44\x87\x04\xd3\xe8\x0b\xd8\x89\x9c\x24\x78\x02\x00\x00\x45\x33\xf6\x41\x8d\x58\xff\x89\x9c\x24\x60\x02\x00\x00\x45\x8b\xfe\x85\xdb\x0f\x88\xdf\x01\x00\x00\x41\x8b\xc3\x42\x8d\x3c\x2b\x45\x8b\xda\x41\xbc\xff\xff\xff\xff\x4c\x89\x5c\x24\x30\x48\x89\x44\x24\x38\x41\x3b\xf9\x77\x06\x8b\x6c\xbe\x04\xeb\x03\x41\x8b\xee\x8d\x47\xff\x8b\x4c\x86\x04\x8d\x47\xfe\x44\x8b\x54\x86\x04\x48\x89\x4c\x24\x28\x89\x6c\x24\x2c\x85\xd2\x74\x32\x48\x8b\x4c\x24\x38\x45\x8b\xc2\x48\x8b\x44\x24\x28\x49\xd3\xe8\x8b\xca\x48\xd3\xe0\x4c\x0b\xc0\x41\xd3\xe2\x83\xff\x03\x72\x17\x8b\x4c\x24\x20\x8d\x47\xfd\x8b\x44\x86\x04\xd3\xe8\x44\x0b\xd0\xeb\x05\x4c\x8b\x44\x24\x28\x33\xd2\x49\x8b\xc0\x49\xf7\xf3\x8b\xca\x4c\x8b\xc0\x49\x3b\xc4\x76\x17\x48\xb8\x01\x00\x00\x00\xff\xff\xff\xff\x49\x03\xc0\x4d\x8b\xc4\x49\x0f\xaf\xc3\x48\x03\xc8\x49\x3b\xcc\x77\x44\x48\x8b\x5c\x24\x30\x45\x8b\xda\x44\x8b\x94\x24\x78\x02\x00\x00\x41\x8b\xd2\x49\x0f\xaf\xd0\x49\xf7\xda\x66\x0f\x1f\x44\x00\x00\x48\x8b\xc1\x48\xc1\xe0\x20\x49\x0b\xc3\x48\x3b\xd0\x76\x0e\x49\xff\xc8\x49\x03\xd2\x48\x03\xcb\x49\x3b\xcc\x76\xe3\x8b\x9c\x24\x60\x02\x00\x00\x4d\x85\xc0\x0f\x84\xc0\x00\x00\x00\x49\x8b\xce\x45\x85\xed\x74\x58\x4c\x8b\x8c\x24\x68\x02\x00\x00\x8b\xd3\x49\x83\xc1\x04\x41\x8b\xdd\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x41\x8b\x01\x49\x0f\xaf\xc0\x48\x03\xc8\x8b\xc2\x44\x8b\xd1\x48\xc1\xe9\x20\x4c\x8d\x1c\x86\x8b\x44\x86\x04\x41\x3b\xc2\x73\x03\x48\xff\xc1\x41\x2b\xc2\xff\xc2\x49\x83\xc1\x04\x41\x89\x43\x04\x48\x83\xeb\x01\x75\xca\x8b\x9c\x24\x60\x02\x00\x00\x8b\xc5\x48\x3b\xc1\x73\x4e\x45\x8b\xce\x45\x85\xed\x74\x43\x4c\x8b\x9c\x24\x68\x02\x00\x00\x44\x8b\xd3\x49\x83\xc3\x04\x41\x8b\xdd\x66\x90\x41\x8b\xc2\x4d\x8d\x5b\x04\x8b\x54\x86\x04\x48\x8d\x0c\x86\x41\x8b\x43\xfc\x41\xff\xc2\x48\x03\xd0\x41\x8b\xc1\x48\x03\xd0\x4c\x8b\xca\x89\x51\x04\x49\xc1\xe9\x20\x48\x83\xeb\x01\x75\xd1\x49\xff\xc8\x8b\x9c\x24\x60\x02\x00\x00\x44\x8d\x4f\xff\x4c\x8b\x5c\x24\x30\xff\xcb\x8b\x94\x24\x70\x02\x00\x00\xff\xcf\x49\xc1\xe7\x20\x41\x8b\xc0\x4c\x03\xf8\x89\x9c\x24\x60\x02\x00\x00\x85\xdb\x0f\x89\x3b\xfe\xff\xff\x41\xff\xc1\x41\x8b\xc9\x44\x3b\x0e\x73\x0d\x8b\xc1\xff\xc1\x44\x89\x74\x86\x04\x3b\x0e\x72\xf3\x44\x89\x0e\x45\x85\xc9\x74\x1b\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x8b\x16\xff\xca\x44\x39\x74\x96\x04\x75\x06\x89\x16\x85\xd2\x75\xef\x49\x8b\xc7\x4c\x8b\xac\x24\x28\x02\x00\x00\x4c\x8b\xb4\x24\x20\x02\x00\x00\x4c\x8b\xa4\x24\x30\x02\x00\x00\x48\x8b\xac\x24\x38\x02\x00\x00\x48\x8b\x9c\x24\x40\x02\x00\x00\x4c\x8b\xbc\x24\x18\x02\x00\x00\x48\x81\xc4\x48\x02\x00\x00\x5f\x5e\xc3\xcc\xcc\x40\x55\x53\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8d\xac\x24\x28\xf9\xff\xff\x48\x81\xec\xd8\x07\x00\x00\x48\x8b\x05\xcd\xe2\x00\x00\x48\x33\xc4\x48\x89\x85\xc0\x06\x00\x00\x48\x89\x4c\x24\x38\x4d\x8b\xf1\x48\x8d\x4c\x24\x60\x4c\x89\x4c\x24\x50\x4d\x8b\xf8\x4c\x89\x44\x24\x70\x8b\xf2\xe8\x86\x1f\x00\x00\x8b\x44\x24\x60\x45\x33\xed\x83\xe0\x1f\x3c\x1f\x75\x07\x44\x88\x6c\x24\x68\xeb\x0f\x48\x8d\x4c\x24\x60\xe8\xd3\x1f\x00\x00\xc6\x44\x24\x68\x01\x48\x8b\x5c\x24\x38\x48\xb9\x00\x00\x00\x00\x00\x00\x00\x80\x48\x8b\xc3\x4d\x89\x77\x08\x48\x23\xc1\xbf\x20\x00\x00\x00\x48\xf7\xd8\x49\xbc\xff\xff\xff\xff\xff\xff\x0f\x00\x48\xb8\x00\x00\x00\x00\x00\x00\xf0\x7f\x1b\xc9\x83\xe1\x0d\x03\xcf\x41\x89\x0f\x48\x85\xd8\x75\x2c\x49\x85\xdc\x75\x27\x48\x8b\x95\x40\x07\x00\x00\x4c\x8d\x05\xa3\xa4\x00\x00\x49\x8b\xce\x45\x89\x6f\x04\xe8\xf3\x9e\xff\xff\x85\xc0\x0f\x84\xf1\x11\x00\x00\xe9\x20\x12\x00\x00\x48\x8d\x4c\x24\x38\xe8\xe8\xbf\xff\xff\x85\xc0\x74\x08\x41\xc7\x47\x04\x01\x00\x00\x00\x83\xe8\x01\x0f\x84\xaf\x11\x00\x00\x83\xe8\x01\x0f\x84\x87\x11\x00\x00\x83\xe8\x01\x0f\x84\x5f\x11\x00\x00\x83\xf8\x01\x0f\x84\x37\x11\x00\x00\x48\xb8\xff\xff\xff\xff\xff\xff\xff\x7f\x41\xb9\xff\x07\x00\x00\x48\x23\xd8\xff\xc6\x48\x89\x5c\x24\x38\xf2\x0f\x10\x44\x24\x38\xf2\x0f\x11\x44\x24\x58\x48\x8b\x54\x24\x58\x4c\x8b\xc2\x89\x74\x24\x4c\x49\xc1\xe8\x34\x4d\x85\xc1\x0f\x94\xc1\x8a\xc1\xf6\xd8\x48\xb8\x00\x00\x00\x00\x00\x00\x10\x00\x4d\x1b\xf6\x49\x23\xd4\x49\xf7\xd6\x4c\x23\xf0\x4c\x03\xf2\xf6\xd9\x1b\xc0\x45\x23\xc1\xf7\xd8\xff\xc0\x41\x8d\x98\xcc\xfb\xff\xff\x03\xd8\xe8\xd2\x1f\x00\x00\xe8\xfd\x1e\x00\x00\xf2\x0f\x2c\xc8\x44\x89\x75\x84\x41\xba\x01\x00\x00\x00\x8d\x81\x01\x00\x00\x80\x83\xe0\xfe\xf7\xd8\x45\x1b\xe4\x49\xc1\xee\x20\x44\x23\xe1\x44\x89\x75\x88\x41\x8b\xc6\x44\x89\x64\x24\x30\xf7\xd8\x1b\xd2\xf7\xda\x41\x03\xd2\x89\x55\x80\x85\xdb\x0f\x88\xa9\x02\x00\x00\x33\xc0\xc7\x85\x28\x03\x00\x00\x00\x00\x10\x00\x89\x85\x24\x03\x00\x00\x8d\x70\x02\x89\xb5\x20\x03\x00\x00\x3b\xd6\x0f\x85\x61\x01\x00\x00\x45\x8b\xc5\x41\x8b\xc8\x8b\x44\x8d\x84\x39\x84\x8d\x24\x03\x00\x00\x0f\x85\x4a\x01\x00\x00\x45\x03\xc2\x44\x3b\xc6\x75\xe4\x44\x8d\x5b\x02\x44\x89\x6c\x24\x38\x45\x8b\xcb\x8b\xf7\x41\x83\xe3\x1f\x41\xc1\xe9\x05\x41\x2b\xf3\x49\x8b\xda\x8b\xce\x48\xd3\xe3\x41\x2b\xda\x41\x0f\xbd\xc6\x44\x8b\xe3\x41\xf7\xd4\x74\x04\xff\xc0\xeb\x03\x41\x8b\xc5\x2b\xf8\x41\x8d\x41\x02\x44\x3b\xdf\x41\x0f\x97\xc7\x83\xf8\x73\x41\x0f\x97\xc0\x83\xf8\x73\x75\x08\x41\x8a\xca\x45\x84\xff\x75\x03\x41\x8a\xcd\x41\x83\xcd\xff\x45\x84\xc0\x0f\x85\xa1\x00\x00\x00\x84\xc9\x0f\x85\x99\x00\x00\x00\x41\xbe\x72\x00\x00\x00\x41\x3b\xc6\x44\x0f\x42\xf0\x45\x3b\xf5\x74\x5c\x45\x8b\xc6\x45\x2b\xc1\x43\x8d\x3c\x08\x41\x3b\xf9\x72\x47\x44\x3b\xc2\x73\x07\x46\x8b\x54\x85\x84\xeb\x03\x45\x33\xd2\x41\x8d\x40\xff\x3b\xc2\x73\x06\x8b\x54\x85\x84\xeb\x02\x33\xd2\x41\x23\xd4\x8b\xce\xd3\xea\x45\x03\xc5\x44\x23\xd3\x41\x8b\xcb\x41\xd3\xe2\x41\x0b\xd2\x43\x8d\x04\x08\x89\x54\xbd\x84\x41\x3b\xc5\x74\x05\x8b\x55\x80\xeb\xb0\x41\xba\x01\x00\x00\x00\x45\x33\xed\x41\x8b\xcd\x45\x85\xc9\x74\x0f\x8b\xc1\x41\x03\xca\x44\x89\x6c\x85\x84\x41\x3b\xc9\x75\xf1\x45\x84\xff\x41\x8d\x46\x01\x44\x0f\x45\xf0\x44\x89\x75\x80\xeb\x0a\x45\x33\xed\x45\x8b\xf5\x44\x89\x6d\x80\xc7\x85\x54\x01\x00\x00\x04\x00\x00\x00\x44\x8b\x64\x24\x30\x41\xbf\x01\x00\x00\x00\x44\x89\xbd\x50\x01\x00\x00\x44\x89\xbd\x20\x03\x00\x00\x44\x89\xad\x28\x03\x00\x00\xe9\x74\x03\x00\x00\x83\x64\x24\x38\x00\x44\x8d\x5b\x01\x45\x8b\xcb\x8d\x42\xff\x41\x83\xe3\x1f\x41\xc1\xe9\x05\x44\x8b\xff\x49\x8b\xda\x45\x2b\xfb\x41\x8b\xcf\x48\xd3\xe3\x41\x2b\xda\x8b\xc8\x0f\xbd\x44\x85\x84\x44\x8b\xeb\x41\xf7\xd5\x74\x04\xff\xc0\xeb\x02\x33\xc0\x2b\xf8\x42\x8d\x04\x0a\x44\x3b\xdf\x41\x0f\x97\xc4\x83\xf8\x73\x41\x0f\x97\xc0\x83\xf8\x73\x75\x0a\x45\x84\xe4\x74\x05\x41\x8a\xca\xeb\x02\x32\xc9\x41\x83\xca\xff\x45\x84\xc0\x0f\x85\xa0\x00\x00\x00\x84\xc9\x0f\x85\x98\x00\x00\x00\x41\xbe\x72\x00\x00\x00\x41\x3b\xc6\x44\x0f\x42\xf0\x45\x3b\xf2\x74\x5c\x45\x8b\xc6\x45\x2b\xc1\x43\x8d\x3c\x08\x41\x3b\xf9\x72\x4d\x44\x3b\xc2\x73\x07\x46\x8b\x54\x85\x84\xeb\x03\x45\x33\xd2\x41\x8d\x40\xff\x3b\xc2\x73\x06\x8b\x54\x85\x84\xeb\x02\x33\xd2\x44\x23\xd3\x41\x8b\xcb\x41\xd3\xe2\x41\x23\xd5\x41\x8b\xcf\xd3\xea\x44\x0b\xd2\x44\x89\x54\xbd\x84\x41\x83\xca\xff\x45\x03\xc2\x43\x8d\x04\x08\x41\x3b\xc2\x74\x05\x8b\x55\x80\xeb\xaa\x45\x33\xed\x41\x8b\xcd\x45\x85\xc9\x74\x0e\x8b\xc1\xff\xc1\x44\x89\x6c\x85\x84\x41\x3b\xc9\x75\xf2\x45\x84\xe4\x41\x8d\x46\x01\x44\x0f\x45\xf0\x44\x89\x75\x80\xeb\x0a\x45\x33\xed\x45\x8b\xf5\x44\x89\x6d\x80\x89\xb5\x54\x01\x00\x00\xe9\xb6\xfe\xff\xff\x81\xfb\x02\xfc\xff\xff\x0f\x84\x2c\x01\x00\x00\x33\xc0\xc7\x85\x28\x03\x00\x00\x00\x00\x10\x00\x89\x85\x24\x03\x00\x00\x8d\x70\x02\x89\xb5\x20\x03\x00\x00\x3b\xd6\x0f\x85\x09\x01\x00\x00\x45\x8b\xc5\x41\x8b\xc8\x8b\x44\x8d\x84\x39\x84\x8d\x24\x03\x00\x00\x0f\x85\xf2\x00\x00\x00\x45\x03\xc2\x44\x3b\xc6\x75\xe4\x41\x0f\xbd\xc6\x44\x89\x6c\x24\x38\x74\x04\xff\xc0\xeb\x03\x41\x8b\xc5\x2b\xf8\x8b\xce\x3b\xfe\x41\x0f\x92\xc1\x41\x83\xcd\xff\x3b\xca\x73\x09\x8b\xc1\x44\x8b\x44\x85\x84\xeb\x03\x45\x33\xc0\x8d\x41\xff\x3b\xc2\x73\x06\x8b\x54\x85\x84\xeb\x02\x33\xd2\x41\x8b\xc0\xc1\xea\x1e\xc1\xe0\x02\x33\xd0\x8b\xc1\x41\x03\xcd\x89\x54\x85\x84\x41\x3b\xcd\x74\x05\x8b\x55\x80\xeb\xc3\x41\xf6\xd9\x48\x8d\x8d\x24\x03\x00\x00\x45\x1b\xf6\x33\xd2\x41\xf7\xde\x44\x03\xf6\x2b\xf3\x8b\xfe\x44\x89\x75\x80\xc1\xef\x05\x8b\xdf\x48\xc1\xe3\x02\x4c\x8b\xc3\xe8\xb8\x69\xff\xff\x83\xe6\x1f\x44\x8d\x7f\x01\x40\x8a\xce\x45\x8b\xc7\xb8\x01\x00\x00\x00\x49\xc1\xe0\x02\xd3\xe0\x89\x84\x1d\x24\x03\x00\x00\x45\x33\xed\x44\x89\xbd\x50\x01\x00\x00\x44\x89\xbd\x20\x03\x00\x00\x4d\x85\xc0\x0f\x84\x3d\x01\x00\x00\xbb\xcc\x01\x00\x00\x48\x8d\x8d\x54\x01\x00\x00\x4c\x3b\xc3\x0f\x87\x07\x01\x00\x00\x48\x8d\x95\x24\x03\x00\x00\xe8\xee\x2f\x00\x00\xe9\x10\x01\x00\x00\x8d\x42\xff\x44\x89\x6c\x24\x38\x8b\xc8\x0f\xbd\x44\x85\x84\x74\x04\xff\xc0\xeb\x03\x41\x8b\xc5\x2b\xf8\x41\x3b\xfa\x41\x0f\x92\xc1\x83\xfa\x73\x0f\x97\xc1\x83\xfa\x73\x75\x08\x41\x8a\xc2\x45\x84\xc9\x75\x03\x41\x8a\xc5\x41\x83\xcd\xff\x84\xc9\x75\x68\x84\xc0\x75\x64\x41\xbe\x72\x00\x00\x00\x41\x3b\xd6\x44\x0f\x42\xf2\x45\x3b\xf5\x74\x3e\x41\x8b\xce\x3b\xca\x73\x09\x8b\xc1\x44\x8b\x44\x85\x84\xeb\x03\x45\x33\xc0\x8d\x41\xff\x3b\xc2\x73\x06\x8b\x54\x85\x84\xeb\x02\x33\xd2\xc1\xea\x1f\x43\x8d\x04\x00\x33\xd0\x8b\xc1\x41\x03\xcd\x89\x54\x85\x84\x41\x3b\xcd\x74\x05\x8b\x55\x80\xeb\xc5\x45\x33\xed\x41\x8d\x46\x01\x45\x84\xc9\x44\x0f\x45\xf0\x44\x89\x75\x80\xeb\x0a\x45\x33\xed\x45\x8b\xf5\x44\x89\x6d\x80\x41\x8b\xfa\x48\x8d\x8d\x24\x03\x00\x00\x2b\xfb\x33\xd2\x8b\xf7\xc1\xee\x05\x8b\xde\x48\xc1\xe3\x02\x4c\x8b\xc3\xe8\x87\x68\xff\xff\x83\xe7\x1f\x44\x8d\x7e\x01\x40\x8a\xcf\x45\x8b\xc7\xb8\x01\x00\x00\x00\xd3\xe0\x89\x84\x1d\x24\x03\x00\x00\x49\xc1\xe0\x02\xe9\xcd\xfe\xff\xff\x4c\x8b\xc3\x33\xd2\xe8\x59\x68\xff\xff\xe8\xa8\xa0\xff\xff\xc7\x00\x22\x00\x00\x00\xe8\x7d\x9f\xff\xff\x44\x8b\xbd\x50\x01\x00\x00\xb8\xcd\xcc\xcc\xcc\x45\x85\xe4\x0f\x88\xbe\x04\x00\x00\x41\xf7\xe4\x8b\xc2\x48\x8d\x15\x08\x3c\xff\xff\xc1\xe8\x03\x89\x44\x24\x48\x44\x8b\xe0\x89\x44\x24\x40\x85\xc0\x0f\x84\xd3\x03\x00\x00\xb8\x26\x00\x00\x00\x45\x8b\xec\x44\x3b\xe0\x44\x0f\x47\xe8\x44\x89\x6c\x24\x44\x41\x8d\x45\xff\x0f\xb6\x8c\x82\xc2\x61\x01\x00\x0f\xb6\xb4\x82\xc3\x61\x01\x00\x8b\xd9\x8b\xf8\x33\xd2\x48\xc1\xe3\x02\x4c\x8b\xc3\x8d\x04\x0e\x48\x8d\x8d\x24\x03\x00\x00\x89\x85\x20\x03\x00\x00\xe8\xc8\x67\xff\xff\x48\x8d\x0d\xa1\x3b\xff\xff\x48\xc1\xe6\x02\x0f\xb7\x84\xb9\xc0\x61\x01\x00\x48\x8d\x91\xb0\x58\x01\x00\x48\x8d\x8d\x24\x03\x00\x00\x4c\x8b\xc6\x48\x03\xcb\x48\x8d\x14\x82\xe8\x28\x2e\x00\x00\x44\x8b\x9d\x20\x03\x00\x00\x41\x83\xfb\x01\x0f\x87\xa2\x00\x00\x00\x8b\x85\x24\x03\x00\x00\x85\xc0\x75\x0f\x45\x33\xff\x44\x89\xbd\x50\x01\x00\x00\xe9\x09\x03\x00\x00\x83\xf8\x01\x0f\x84\x00\x03\x00\x00\x45\x85\xff\x0f\x84\xf7\x02\x00\x00\x45\x33\xc0\x4c\x8b\xd0\x45\x33\xc9\x42\x8b\x8c\x8d\x54\x01\x00\x00\x41\x8b\xc0\x49\x0f\xaf\xca\x48\x03\xc8\x4c\x8b\xc1\x42\x89\x8c\x8d\x54\x01\x00\x00\x49\xc1\xe8\x20\x41\xff\xc1\x45\x3b\xcf\x75\xd7\x45\x85\xc0\x74\x34\x83\xbd\x50\x01\x00\x00\x73\x73\x1a\x8b\x85\x50\x01\x00\x00\x44\x89\x84\x85\x54\x01\x00\x00\x44\x8b\xbd\x50\x01\x00\x00\x41\xff\xc7\xeb\x88\x45\x33\xff\x44\x89\xbd\x50\x01\x00\x00\x32\xc0\xe9\x8e\x02\x00\x00\x44\x8b\xbd\x50\x01\x00\x00\xe9\x80\x02\x00\x00\x41\x83\xff\x01\x0f\x87\xad\x00\x00\x00\x8b\x9d\x54\x01\x00\x00\x4d\x8b\xc3\x49\xc1\xe0\x02\x45\x8b\xfb\x44\x89\x9d\x50\x01\x00\x00\x4d\x85\xc0\x74\x40\xb8\xcc\x01\x00\x00\x48\x8d\x8d\x54\x01\x00\x00\x4c\x3b\xc0\x77\x0e\x48\x8d\x95\x24\x03\x00\x00\xe8\x32\x2d\x00\x00\xeb\x1a\x4c\x8b\xc0\x33\xd2\xe8\x96\x66\xff\xff\xe8\xe5\x9e\xff\xff\xc7\x00\x22\x00\x00\x00\xe8\xba\x9d\xff\xff\x44\x8b\xbd\x50\x01\x00\x00\x85\xdb\x0f\x84\xfa\xfe\xff\xff\x83\xfb\x01\x0f\x84\x09\x02\x00\x00\x45\x85\xff\x0f\x84\x00\x02\x00\x00\x45\x33\xc0\x4c\x8b\xd3\x45\x33\xc9\x42\x8b\x8c\x8d\x54\x01\x00\x00\x41\x8b\xc0\x49\x0f\xaf\xca\x48\x03\xc8\x4c\x8b\xc1\x42\x89\x8c\x8d\x54\x01\x00\x00\x49\xc1\xe8\x20\x41\xff\xc1\x45\x3b\xcf\x75\xd7\xe9\x04\xff\xff\xff\x45\x3b\xdf\x48\x8d\x8d\x54\x01\x00\x00\x45\x8b\xe7\x4c\x8d\xad\x24\x03\x00\x00\x0f\x92\xc0\x48\x8d\x95\x54\x01\x00\x00\x84\xc0\x4c\x0f\x44\xe9\x45\x0f\x45\xe3\x45\x0f\x45\xdf\x48\x8d\x8d\x24\x03\x00\x00\x48\x0f\x44\xd1\x45\x33\xff\x45\x33\xd2\x48\x89\x54\x24\x38\x44\x89\xbd\xf0\x04\x00\x00\x45\x85\xe4\x0f\x84\x1a\x01\x00\x00\x43\x8b\x74\x95\x00\x41\x8b\xc2\x85\xf6\x75\x21\x45\x3b\xd7\x0f\x85\xf9\x00\x00\x00\x42\x21\xb4\x95\xf4\x04\x00\x00\x45\x8d\x7a\x01\x44\x89\xbd\xf0\x04\x00\x00\xe9\xe1\x00\x00\x00\x33\xdb\x45\x8b\xca\x45\x85\xdb\x0f\x84\xc4\x00\x00\x00\x41\x8b\xfa\xf7\xdf\x41\x83\xf9\x73\x74\x67\x45\x3b\xcf\x75\x1b\x41\x8b\xc1\x41\x8d\x4a\x01\x83\xa4\x85\xf4\x04\x00\x00\x00\x42\x8d\x04\x0f\x03\xc8\x89\x8d\xf0\x04\x00\x00\x42\x8d\x04\x0f\x45\x8b\xc1\x8b\x14\x82\x41\xff\xc1\x8b\xc3\x48\x0f\xaf\xd6\x48\x03\xd0\x42\x8b\x84\x85\xf4\x04\x00\x00\x48\x03\xd0\x42\x8d\x04\x0f\x48\x8b\xda\x42\x89\x94\x85\xf4\x04\x00\x00\x44\x8b\xbd\xf0\x04\x00\x00\x48\xc1\xeb\x20\x41\x3b\xc3\x74\x07\x48\x8b\x54\x24\x38\xeb\x93\x85\xdb\x74\x4e\x41\x83\xf9\x73\x0f\x84\x7e\x01\x00\x00\x45\x3b\xcf\x75\x15\x41\x8b\xc1\x83\xa4\x85\xf4\x04\x00\x00\x00\x41\x8d\x41\x01\x89\x85\xf0\x04\x00\x00\x41\x8b\xc9\x41\xff\xc1\x8b\xd3\x8b\x84\x8d\xf4\x04\x00\x00\x48\x03\xd0\x89\x94\x8d\xf4\x04\x00\x00\x44\x8b\xbd\xf0\x04\x00\x00\x48\xc1\xea\x20\x8b\xda\x85\xd2\x75\xb2\x41\x83\xf9\x73\x0f\x84\x30\x01\x00\x00\x48\x8b\x54\x24\x38\x41\xff\xc2\x45\x3b\xd4\x0f\x85\xe6\xfe\xff\xff\x45\x8b\xc7\x49\xc1\xe0\x02\x44\x89\xbd\x50\x01\x00\x00\x4d\x85\xc0\x74\x40\xb8\xcc\x01\x00\x00\x48\x8d\x8d\x54\x01\x00\x00\x4c\x3b\xc0\x77\x0e\x48\x8d\x95\xf4\x04\x00\x00\xe8\x22\x2b\x00\x00\xeb\x1a\x4c\x8b\xc0\x33\xd2\xe8\x86\x64\xff\xff\xe8\xd5\x9c\xff\xff\xc7\x00\x22\x00\x00\x00\xe8\xaa\x9b\xff\xff\x44\x8b\xbd\x50\x01\x00\x00\x44\x8b\x64\x24\x40\x44\x8b\x6c\x24\x44\xb0\x01\x84\xc0\x0f\x84\xb8\x00\x00\x00\x45\x2b\xe5\x48\x8d\x15\x31\x38\xff\xff\x44\x89\x64\x24\x40\x0f\x85\x34\xfc\xff\xff\x8b\x44\x24\x48\x45\x33\xed\x8b\x7c\x24\x30\x8d\x04\x80\x03\xc0\x8b\xcf\x2b\xc8\x0f\x84\x1f\x05\x00\x00\x8d\x41\xff\x8b\x84\x82\x58\x62\x01\x00\x85\xc0\x0f\x84\x89\x00\x00\x00\x83\xf8\x01\x0f\x84\x04\x05\x00\x00\x45\x85\xff\x0f\x84\xfb\x04\x00\x00\x45\x8b\xc5\x45\x8b\xcd\x44\x8b\xd0\x41\x8b\xd1\x41\xff\xc1\x41\x8b\xc0\x8b\x8c\x95\x54\x01\x00\x00\x49\x0f\xaf\xca\x48\x03\xc8\x4c\x8b\xc1\x89\x8c\x95\x54\x01\x00\x00\x49\xc1\xe8\x20\x45\x3b\xcf\x75\xd6\x45\x85\xc0\x74\x4e\x83\xbd\x50\x01\x00\x00\x73\x73\x36\x8b\x85\x50\x01\x00\x00\x44\x89\x84\x85\x54\x01\x00\x00\x44\x8b\xbd\x50\x01\x00\x00\x41\xff\xc7\x44\x89\xbd\x50\x01\x00\x00\xe9\x96\x04\x00\x00\x45\x33\xed\x45\x8b\xfd\x44\x89\xad\x50\x01\x00\x00\xe9\x80\x04\x00\x00\x45\x8b\xfd\x44\x89\xad\x50\x01\x00\x00\xe9\x75\x04\x00\x00\x44\x8b\xbd\x50\x01\x00\x00\xe9\x69\x04\x00\x00\x41\x8b\xcc\xf7\xd9\xf7\xe1\x89\x4c\x24\x44\x8b\xc2\x48\x8d\x15\x42\x37\xff\xff\xc1\xe8\x03\x89\x44\x24\x38\x44\x8b\xe0\x89\x44\x24\x40\x85\xc0\x0f\x84\x97\x03\x00\x00\xb8\x26\x00\x00\x00\x45\x8b\xec\x44\x3b\xe0\x44\x0f\x47\xe8\x44\x89\x6c\x24\x48\x41\x8d\x45\xff\x0f\xb6\x8c\x82\xc2\x61\x01\x00\x0f\xb6\xb4\x82\xc3\x61\x01\x00\x8b\xd9\x8b\xf8\x33\xd2\x48\xc1\xe3\x02\x4c\x8b\xc3\x8d\x04\x0e\x48\x8d\x8d\x24\x03\x00\x00\x89\x85\x20\x03\x00\x00\xe8\x02\x63\xff\xff\x48\x8d\x0d\xdb\x36\xff\xff\x48\xc1\xe6\x02\x0f\xb7\x84\xb9\xc0\x61\x01\x00\x48\x8d\x91\xb0\x58\x01\x00\x48\x8d\x8d\x24\x03\x00\x00\x4c\x8b\xc6\x48\x03\xcb\x48\x8d\x14\x82\xe8\x62\x29\x00\x00\x8b\xbd\x20\x03\x00\x00\x83\xff\x01\x0f\x87\x87\x00\x00\x00\x8b\x85\x24\x03\x00\x00\x85\xc0\x75\x0c\x45\x33\xf6\x44\x89\x75\x80\xe9\xce\x02\x00\x00\x83\xf8\x01\x0f\x84\xc5\x02\x00\x00\x45\x85\xf6\x0f\x84\xbc\x02\x00\x00\x45\x33\xc0\x4c\x8b\xd0\x45\x33\xc9\x42\x8b\x4c\x8d\x84\x41\x8b\xc0\x49\x0f\xaf\xca\x48\x03\xc8\x4c\x8b\xc1\x42\x89\x4c\x8d\x84\x49\xc1\xe8\x20\x41\xff\xc1\x45\x3b\xce\x75\xdd\x45\x85\xc0\x74\x25\x83\x7d\x80\x73\x73\x11\x8b\x45\x80\x44\x89\x44\x85\x84\x44\x8b\x75\x80\x41\xff\xc6\xeb\x9d\x45\x33\xf6\x44\x89\x75\x80\x32\xc0\xe9\x68\x02\x00\x00\x44\x8b\x75\x80\xe9\x5d\x02\x00\x00\x41\x83\xfe\x01\x0f\x87\x9a\x00\x00\x00\x8b\x5d\x84\x4c\x8b\xc7\x49\xc1\xe0\x02\x44\x8b\xf7\x89\x7d\x80\x4d\x85\xc0\x74\x3a\xb8\xcc\x01\x00\x00\x48\x8d\x4d\x84\x4c\x3b\xc0\x77\x0e\x48\x8d\x95\x24\x03\x00\x00\xe8\x93\x28\x00\x00\xeb\x1a\x4c\x8b\xc0\x33\xd2\xe8\xf7\x61\xff\xff\xe8\x46\x9a\xff\xff\xc7\x00\x22\x00\x00\x00\xe8\x1b\x99\xff\xff\x44\x8b\x75\x80\x85\xdb\x0f\x84\x22\xff\xff\xff\x83\xfb\x01\x0f\x84\xf3\x01\x00\x00\x45\x85\xf6\x0f\x84\xea\x01\x00\x00\x45\x33\xc0\x4c\x8b\xd3\x45\x33\xc9\x42\x8b\x4c\x8d\x84\x41\x8b\xc0\x49\x0f\xaf\xca\x48\x03\xc8\x4c\x8b\xc1\x42\x89\x4c\x8d\x84\x49\xc1\xe8\x20\x41\xff\xc1\x45\x3b\xce\x75\xdd\xe9\x29\xff\xff\xff\x41\x3b\xfe\x48\x8d\x4d\x84\x45\x8b\xe6\x4c\x8d\xad\x24\x03\x00\x00\x0f\x92\xc0\x48\x8d\x55\x84\x84\xc0\x4c\x0f\x44\xe9\x44\x0f\x45\xe7\x41\x0f\x45\xfe\x48\x8d\x8d\x24\x03\x00\x00\x48\x0f\x44\xd1\x45\x33\xf6\x45\x33\xd2\x48\x89\x54\x24\x58\x44\x89\xb5\xf0\x04\x00\x00\x45\x85\xe4\x0f\x84\x19\x01\x00\x00\x43\x8b\x74\x95\x00\x41\x8b\xc2\x85\xf6\x75\x21\x45\x3b\xd6\x0f\x85\xf8\x00\x00\x00\x42\x21\xb4\x95\xf4\x04\x00\x00\x45\x8d\x72\x01\x44\x89\xb5\xf0\x04\x00\x00\xe9\xe0\x00\x00\x00\x33\xdb\x45\x8b\xca\x85\xff\x0f\x84\xc4\x00\x00\x00\x45\x8b\xda\x41\xf7\xdb\x41\x83\xf9\x73\x74\x66\x45\x3b\xce\x75\x1b\x41\x8b\xc1\x41\x8d\x49\x01\x83\xa4\x85\xf4\x04\x00\x00\x00\x43\x8d\x04\x1a\x03\xc8\x89\x8d\xf0\x04\x00\x00\x43\x8d\x04\x0b\x45\x8b\xc1\x8b\x14\x82\x41\xff\xc1\x48\x0f\xaf\xd6\x42\x8b\x84\x85\xf4\x04\x00\x00\x48\x03\xd0\x8b\xc3\x48\x03\xd0\x43\x8d\x04\x0b\x48\x8b\xda\x42\x89\x94\x85\xf4\x04\x00\x00\x44\x8b\xb5\xf0\x04\x00\x00\x48\xc1\xeb\x20\x3b\xc7\x74\x07\x48\x8b\x54\x24\x58\xeb\x94\x85\xdb\x74\x4e\x41\x83\xf9\x73\x0f\x84\x57\x01\x00\x00\x45\x3b\xce\x75\x15\x41\x8b\xc1\x83\xa4\x85\xf4\x04\x00\x00\x00\x41\x8d\x41\x01\x89\x85\xf0\x04\x00\x00\x41\x8b\xc9\x41\xff\xc1\x8b\xc3\x8b\x94\x8d\xf4\x04\x00\x00\x48\x03\xd0\x89\x94\x8d\xf4\x04\x00\x00\x44\x8b\xb5\xf0\x04\x00\x00\x48\xc1\xea\x20\x8b\xda\x85\xd2\x75\xb2\x41\x83\xf9\x73\x0f\x84\x09\x01\x00\x00\x48\x8b\x54\x24\x58\x41\xff\xc2\x45\x3b\xd4\x0f\x85\xe7\xfe\xff\xff\x45\x8b\xc6\x49\xc1\xe0\x02\x44\x89\x75\x80\x4d\x85\xc0\x74\x3a\xb8\xcc\x01\x00\x00\x48\x8d\x4d\x84\x4c\x3b\xc0\x77\x0e\x48\x8d\x95\xf4\x04\x00\x00\xe8\x99\x26\x00\x00\xeb\x1a\x4c\x8b\xc0\x33\xd2\xe8\xfd\x5f\xff\xff\xe8\x4c\x98\xff\xff\xc7\x00\x22\x00\x00\x00\xe8\x21\x97\xff\xff\x44\x8b\x75\x80\x44\x8b\x64\x24\x40\x44\x8b\x6c\x24\x48\xb0\x01\x84\xc0\x0f\x84\x9a\x00\x00\x00\x45\x2b\xe5\x48\x8d\x15\xab\x33\xff\xff\x44\x89\x64\x24\x40\x0f\x85\x74\xfc\xff\xff\x8b\x4c\x24\x44\x45\x33\xed\x8b\x44\x24\x38\x8d\x04\x80\x03\xc0\x2b\xc8\x0f\x84\x97\x00\x00\x00\x8d\x41\xff\x8b\x84\x82\x58\x62\x01\x00\x85\xc0\x74\x62\x83\xf8\x01\x0f\x84\x80\x00\x00\x00\x45\x85\xf6\x74\x7b\x45\x8b\xc5\x45\x8b\xcd\x44\x8b\xd0\x41\x8b\xd1\x41\xff\xc1\x41\x8b\xc0\x8b\x4c\x95\x84\x49\x0f\xaf\xca\x48\x03\xc8\x4c\x8b\xc1\x89\x4c\x95\x84\x49\xc1\xe8\x20\x45\x3b\xce\x75\xdc\x45\x85\xc0\x74\x45\x83\x7d\x80\x73\x8b\x7c\x24\x30\x73\x2d\x8b\x45\x80\x44\x89\x44\x85\x84\x44\x8b\x75\x80\x41\xff\xc6\x44\x89\x75\x80\xeb\x2e\x45\x33\xed\x48\x8b\x74\x24\x50\x8b\x7c\x24\x30\x48\x8b\xde\x44\x89\x6d\x80\xe9\x87\x00\x00\x00\x48\x8b\x74\x24\x50\x48\x8b\xde\x44\x89\x6d\x80\xeb\x79\x44\x8b\x75\x80\x8b\x7c\x24\x30\x48\x8b\x74\x24\x50\x48\x8b\xde\x45\x85\xf6\x74\x64\x45\x8b\xc5\x45\x8b\xcd\x41\x8b\xd1\x41\xff\xc1\x8b\x44\x95\x84\x48\x8d\x0c\x80\x41\x8b\xc0\x4c\x8d\x04\x48\x44\x89\x44\x95\x84\x49\xc1\xe8\x20\x45\x3b\xce\x75\xdd\x45\x85\xc0\x74\x36\x83\x7d\x80\x73\x73\x0d\x8b\x45\x80\x44\x89\x44\x85\x84\xff\x45\x80\xeb\x23\x45\x33\xc9\x44\x89\xad\x20\x03\x00\x00\x4c\x8d\x85\x24\x03\x00\x00\x44\x89\x6d\x80\xba\xcc\x01\x00\x00\x48\x8d\x4d\x84\xe8\xf8\x02\x00\x00\x48\x8d\x95\x50\x01\x00\x00\x48\x8d\x4d\x80\xe8\xac\xea\xff\xff\x83\xf8\x0a\x0f\x85\x90\x00\x00\x00\xff\xc7\xc6\x06\x31\x48\x8d\x5e\x01\x45\x85\xff\x0f\x84\x8e\x00\x00\x00\x45\x8b\xc5\x45\x8b\xcd\x41\x8b\xd1\x41\xff\xc1\x8b\x84\x95\x54\x01\x00\x00\x48\x8d\x0c\x80\x41\x8b\xc0\x4c\x8d\x04\x48\x44\x89\x84\x95\x54\x01\x00\x00\x49\xc1\xe8\x20\x45\x3b\xcf\x75\xd7\x45\x85\xc0\x74\x5a\x83\xbd\x50\x01\x00\x00\x73\x73\x16\x8b\x85\x50\x01\x00\x00\x44\x89\x84\x85\x54\x01\x00\x00\xff\x85\x50\x01\x00\x00\xeb\x3b\x45\x33\xc9\x44\x89\xad\x20\x03\x00\x00\x4c\x8d\x85\x24\x03\x00\x00\x44\x89\xad\x50\x01\x00\x00\xba\xcc\x01\x00\x00\x48\x8d\x8d\x54\x01\x00\x00\xe8\x51\x02\x00\x00\xeb\x10\x85\xc0\x75\x04\xff\xcf\xeb\x08\x04\x30\x48\x8d\x5e\x01\x88\x06\x48\x8b\x44\x24\x70\x8b\x4c\x24\x4c\x89\x78\x04\x85\xff\x78\x0a\x81\xf9\xff\xff\xff\x7f\x77\x02\x03\xcf\x48\x8b\x85\x40\x07\x00\x00\x48\xff\xc8\x8b\xf9\x48\x3b\xc7\x48\x0f\x42\xf8\x48\x03\xfe\x48\x3b\xdf\x0f\x84\xe8\x00\x00\x00\x41\xbe\x09\x00\x00\x00\x83\xce\xff\x44\x8b\x55\x80\x45\x85\xd2\x0f\x84\xd2\x00\x00\x00\x45\x8b\xc5\x45\x8b\xcd\x41\x8b\xd1\x41\xff\xc1\x8b\x44\x95\x84\x48\x69\xc8\x00\xca\x9a\x3b\x41\x8b\xc0\x48\x03\xc8\x4c\x8b\xc1\x89\x4c\x95\x84\x49\xc1\xe8\x20\x45\x3b\xca\x75\xd9\x45\x85\xc0\x74\x36\x83\x7d\x80\x73\x73\x0d\x8b\x45\x80\x44\x89\x44\x85\x84\xff\x45\x80\xeb\x23\x45\x33\xc9\x44\x89\xad\x20\x03\x00\x00\x4c\x8d\x85\x24\x03\x00\x00\x44\x89\x6d\x80\xba\xcc\x01\x00\x00\x48\x8d\x4d\x84\xe8\x88\x01\x00\x00\x48\x8d\x95\x50\x01\x00\x00\x48\x8d\x4d\x80\xe8\x3c\xe9\xff\xff\x44\x8b\xd7\x4c\x8b\xc0\x44\x2b\xd3\x41\xb9\x08\x00\x00\x00\xb8\xcd\xcc\xcc\xcc\x41\xf7\xe0\xc1\xea\x03\x8a\xca\xc0\xe1\x02\x8d\x04\x11\x02\xc0\x44\x2a\xc0\x41\x8d\x48\x30\x44\x8b\xc2\x45\x3b\xd1\x72\x06\x41\x8b\xc1\x88\x0c\x18\x44\x03\xce\x44\x3b\xce\x75\xce\x48\x8b\xc7\x48\x2b\xc3\x49\x3b\xc6\x49\x0f\x4f\xc6\x48\x03\xd8\x48\x3b\xdf\x0f\x85\x21\xff\xff\xff\x44\x88\x2b\xeb\x7b\x48\x8b\x95\x40\x07\x00\x00\x4c\x8d\x05\x27\x93\x00\x00\x49\x8b\xce\xe8\x5f\x8d\xff\xff\x85\xc0\x74\x61\xe9\xa5\x00\x00\x00\x48\x8b\x95\x40\x07\x00\x00\x4c\x8d\x05\x00\x93\x00\x00\x49\x8b\xce\xe8\x40\x8d\xff\xff\x85\xc0\x74\x42\xe9\x9b\x00\x00\x00\x48\x8b\x95\x40\x07\x00\x00\x4c\x8d\x05\xd9\x92\x00\x00\x49\x8b\xce\xe8\x21\x8d\xff\xff\x85\xc0\x74\x23\xe9\x91\x00\x00\x00\x48\x8b\x95\x40\x07\x00\x00\x4c\x8d\x05\xb2\x92\x00\x00\x49\x8b\xce\xe8\x02\x8d\xff\xff\x85\xc0\x0f\x85\x88\x00\x00\x00\x44\x38\x6c\x24\x68\x74\x0a\x48\x8d\x4c\x24\x60\xe8\x15\x0d\x00\x00\x48\x8b\x8d\xc0\x06\x00\x00\x48\x33\xcc\xe8\x32\x49\xff\xff\x48\x81\xc4\xd8\x07\x00\x00\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\x5e\x5b\x5d\xc3\x45\x33\xc9\x4c\x89\x6c\x24\x20\x45\x33\xc0\x33\xd2\x33\xc9\xe8\x4e\x93\xff\xff\xcc\x45\x33\xc9\x4c\x89\x6c\x24\x20\x45\x33\xc0\x33\xd2\x33\xc9\xe8\x39\x93\xff\xff\xcc\x45\x33\xc9\x4c\x89\x6c\x24\x20\x45\x33\xc0\x33\xd2\x33\xc9\xe8\x24\x93\xff\xff\xcc\x45\x33\xc9\x4c\x89\x6c\x24\x20\x45\x33\xc0\x33\xd2\x33\xc9\xe8\x0f\x93\xff\xff\xcc\x45\x33\xc9\x4c\x89\x6c\x24\x20\x45\x33\xc0\x33\xd2\x33\xc9\xe8\xfa\x92\xff\xff\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x49\x8b\xd9\x49\x8b\xf0\x48\x8b\xfa\x4d\x85\xc9\x75\x04\x33\xc0\xeb\x56\x48\x85\xc9\x75\x15\xe8\xcd\x93\xff\xff\xbb\x16\x00\x00\x00\x89\x18\xe8\xa1\x92\xff\xff\x8b\xc3\xeb\x3c\x4d\x85\xc0\x74\x12\x48\x3b\xd3\x72\x0d\x4c\x8b\xc3\x48\x8b\xd6\xe8\xe4\x21\x00\x00\xeb\xcb\x4c\x8b\xc2\x33\xd2\xe8\x48\x5b\xff\xff\x48\x85\xf6\x74\xc5\x48\x3b\xfb\x73\x0c\xe8\x8d\x93\xff\xff\xbb\x22\x00\x00\x00\xeb\xbe\xb8\x16\x00\x00\x00\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\x48\x8b\xc4\x48\x89\x58\x18\x48\x89\x70\x20\x48\x89\x50\x10\x88\x48\x08\x57\x48\x83\xec\x20\x48\x8b\xca\xe8\x3d\xb9\xff\xff\x48\x8b\x4c\x24\x38\x4c\x63\xc8\x8b\x51\x14\xf6\xc2\xc0\x0f\x84\xa8\x00\x00\x00\x48\x8b\x4c\x24\x38\x33\xdb\x8b\xf3\x48\x8b\x41\x08\x8b\x39\x48\xff\xc0\x2b\x79\x08\x48\x89\x01\x48\x8b\x44\x24\x38\x8b\x48\x20\xff\xc9\x89\x48\x10\x85\xff\x7e\x29\x48\x8b\x54\x24\x38\x44\x8b\xc7\x41\x8b\xc9\x48\x8b\x52\x08\xe8\xd4\xd6\xff\xff\x8b\xf0\x48\x8b\x44\x24\x38\x3b\xf7\x48\x8b\x48\x08\x8a\x44\x24\x30\x88\x01\xeb\x6c\x41\x8d\x41\x02\x83\xf8\x01\x76\x1e\x49\x8b\xc9\x48\x8d\x15\xa4\xe1\x00\x00\x83\xe1\x3f\x49\x8b\xc1\x48\xc1\xf8\x06\x48\xc1\xe1\x06\x48\x03\x0c\xc2\xeb\x07\x48\x8d\x0d\xf9\xcf\x00\x00\xf6\x41\x38\x20\x74\xb9\x33\xd2\x41\x8b\xc9\x44\x8d\x42\x02\xe8\x8d\x0a\x00\x00\x48\x83\xf8\xff\x75\xa5\x48\x8b\x4c\x24\x38\xf0\x83\x49\x14\x10\xb0\x01\xeb\x19\x41\xb8\x01\x00\x00\x00\x48\x8d\x54\x24\x30\x41\x8b\xc9\xe8\x56\xd6\xff\xff\x83\xf8\x01\x0f\x94\xc0\x48\x8b\x5c\x24\x40\x48\x8b\x74\x24\x48\x48\x83\xc4\x20\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x8b\xf9\x48\x8b\xda\x48\x8b\xca\xe8\x3c\xb8\xff\xff\x44\x8b\x43\x14\x8b\xf0\x41\xf6\xc0\x06\x75\x18\xe8\x3f\x92\xff\xff\xc7\x00\x09\x00\x00\x00\xf0\x83\x4b\x14\x10\x83\xc8\xff\xe9\x98\x00\x00\x00\x8b\x43\x14\xc1\xe8\x0c\xb9\x01\x00\x00\x00\x84\xc1\x74\x0d\xe8\x18\x92\xff\xff\xc7\x00\x22\x00\x00\x00\xeb\xd7\x8b\x43\x14\x84\xc1\x74\x1a\x83\x63\x10\x00\x8b\x43\x14\xc1\xe8\x03\x84\xc1\x74\xc2\x48\x8b\x43\x08\x48\x89\x03\xf0\x83\x63\x14\xfe\xf0\x83\x4b\x14\x02\xf0\x83\x63\x14\xf7\x83\x63\x10\x00\x8b\x43\x14\xa9\xc0\x04\x00\x00\x75\x2c\xe8\xe2\x64\xff\xff\x48\x3b\xd8\x74\x0f\xb9\x02\x00\x00\x00\xe8\xd3\x64\xff\xff\x48\x3b\xd8\x75\x0b\x8b\xce\xe8\x33\x00\x00\x00\x85\xc0\x75\x08\x48\x8b\xcb\xe8\x53\x11\x00\x00\x48\x8b\xd3\x40\x8a\xcf\xe8\x30\xfe\xff\xff\x84\xc0\x0f\x84\x5f\xff\xff\xff\x40\x0f\xb6\xc7\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\x48\x83\xec\x28\x83\xf9\xfe\x75\x0d\xe8\x76\x91\xff\xff\xc7\x00\x09\x00\x00\x00\xeb\x42\x85\xc9\x78\x2e\x3b\x0d\x30\xe4\x00\x00\x73\x26\x48\x63\xc9\x48\x8d\x15\x24\xe0\x00\x00\x48\x8b\xc1\x83\xe1\x3f\x48\xc1\xf8\x06\x48\xc1\xe1\x06\x48\x8b\x04\xc2\x0f\xb6\x44\x08\x38\x83\xe0\x40\xeb\x12\xe8\x37\x91\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x0c\x90\xff\xff\x33\xc0\x48\x83\xc4\x28\xc3\xcc\x48\x85\xc9\x0f\x84\x00\x01\x00\x00\x53\x48\x83\xec\x20\x48\x8b\xd9\x48\x8b\x49\x18\x48\x3b\x0d\x6c\xd5\x00\x00\x74\x05\xe8\xc5\x88\xff\xff\x48\x8b\x4b\x20\x48\x3b\x0d\x62\xd5\x00\x00\x74\x05\xe8\xb3\x88\xff\xff\x48\x8b\x4b\x28\x48\x3b\x0d\x58\xd5\x00\x00\x74\x05\xe8\xa1\x88\xff\xff\x48\x8b\x4b\x30\x48\x3b\x0d\x4e\xd5\x00\x00\x74\x05\xe8\x8f\x88\xff\xff\x48\x8b\x4b\x38\x48\x3b\x0d\x44\xd5\x00\x00\x74\x05\xe8\x7d\x88\xff\xff\x48\x8b\x4b\x40\x48\x3b\x0d\x3a\xd5\x00\x00\x74\x05\xe8\x6b\x88\xff\xff\x48\x8b\x4b\x48\x48\x3b\x0d\x30\xd5\x00\x00\x74\x05\xe8\x59\x88\xff\xff\x48\x8b\x4b\x68\x48\x3b\x0d\x3e\xd5\x00\x00\x74\x05\xe8\x47\x88\xff\xff\x48\x8b\x4b\x70\x48\x3b\x0d\x34\xd5\x00\x00\x74\x05\xe8\x35\x88\xff\xff\x48\x8b\x4b\x78\x48\x3b\x0d\x2a\xd5\x00\x00\x74\x05\xe8\x23\x88\xff\xff\x48\x8b\x8b\x80\x00\x00\x00\x48\x3b\x0d\x1d\xd5\x00\x00\x74\x05\xe8\x0e\x88\xff\xff\x48\x8b\x8b\x88\x00\x00\x00\x48\x3b\x0d\x10\xd5\x00\x00\x74\x05\xe8\xf9\x87\xff\xff\x48\x8b\x8b\x90\x00\x00\x00\x48\x3b\x0d\x03\xd5\x00\x00\x74\x05\xe8\xe4\x87\xff\xff\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\x48\x85\xc9\x74\x66\x53\x48\x83\xec\x20\x48\x8b\xd9\x48\x8b\x09\x48\x3b\x0d\x4d\xd4\x00\x00\x74\x05\xe8\xbe\x87\xff\xff\x48\x8b\x4b\x08\x48\x3b\x0d\x43\xd4\x00\x00\x74\x05\xe8\xac\x87\xff\xff\x48\x8b\x4b\x10\x48\x3b\x0d\x39\xd4\x00\x00\x74\x05\xe8\x9a\x87\xff\xff\x48\x8b\x4b\x58\x48\x3b\x0d\x6f\xd4\x00\x00\x74\x05\xe8\x88\x87\xff\xff\x48\x8b\x4b\x60\x48\x3b\x0d\x65\xd4\x00\x00\x74\x05\xe8\x76\x87\xff\xff\x48\x83\xc4\x20\x5b\xc3\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x33\xff\x48\x8d\x04\xd1\x48\x8b\xf0\x48\x8b\xd9\x48\x2b\xf1\x48\x83\xc6\x07\x48\xc1\xee\x03\x48\x3b\xc8\x48\x0f\x47\xf7\x48\x85\xf6\x74\x14\x48\x8b\x0b\xe8\x36\x87\xff\xff\x48\xff\xc7\x48\x8d\x5b\x08\x48\x3b\xfe\x75\xec\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x48\x85\xc9\x0f\x84\xfe\x00\x00\x00\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x56\x48\x83\xec\x20\xbd\x07\x00\x00\x00\x48\x8b\xd9\x8b\xd5\xe8\x81\xff\xff\xff\x48\x8d\x4b\x38\x8b\xd5\xe8\x76\xff\xff\xff\x8d\x75\x05\x8b\xd6\x48\x8d\x4b\x70\xe8\x68\xff\xff\xff\x48\x8d\x8b\xd0\x00\x00\x00\x8b\xd6\xe8\x5a\xff\xff\xff\x48\x8d\x8b\x30\x01\x00\x00\x8d\x55\xfb\xe8\x4b\xff\xff\xff\x48\x8b\x8b\x40\x01\x00\x00\xe8\xaf\x86\xff\xff\x48\x8b\x8b\x48\x01\x00\x00\xe8\xa3\x86\xff\xff\x48\x8b\x8b\x50\x01\x00\x00\xe8\x97\x86\xff\xff\x48\x8d\x8b\x60\x01\x00\x00\x8b\xd5\xe8\x19\xff\xff\xff\x48\x8d\x8b\x98\x01\x00\x00\x8b\xd5\xe8\x0b\xff\xff\xff\x48\x8d\x8b\xd0\x01\x00\x00\x8b\xd6\xe8\xfd\xfe\xff\xff\x48\x8d\x8b\x30\x02\x00\x00\x8b\xd6\xe8\xef\xfe\xff\xff\x48\x8d\x8b\x90\x02\x00\x00\x8d\x55\xfb\xe8\xe0\xfe\xff\xff\x48\x8b\x8b\xa0\x02\x00\x00\xe8\x44\x86\xff\xff\x48\x8b\x8b\xa8\x02\x00\x00\xe8\x38\x86\xff\xff\x48\x8b\x8b\xb0\x02\x00\x00\xe8\x2c\x86\xff\xff\x48\x8b\x8b\xb8\x02\x00\x00\xe8\x20\x86\xff\xff\x48\x8b\x5c\x24\x30\x48\x8b\x6c\x24\x38\x48\x83\xc4\x20\x5e\xc3\x40\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x60\x48\x8d\x6c\x24\x30\x48\x89\x5d\x60\x48\x89\x75\x68\x48\x89\x7d\x70\x48\x8b\x05\xb2\xc9\x00\x00\x48\x33\xc5\x48\x89\x45\x20\x44\x8b\xea\x45\x8b\xf9\x48\x8b\xd1\x4d\x8b\xe0\x48\x8d\x4d\x00\xe8\xf6\x64\xff\xff\x8b\xb5\x88\x00\x00\x00\x85\xf6\x75\x07\x48\x8b\x45\x08\x8b\x70\x0c\xf7\x9d\x90\x00\x00\x00\x45\x8b\xcf\x4d\x8b\xc4\x8b\xce\x1b\xd2\x83\x64\x24\x28\x00\x48\x83\x64\x24\x20\x00\x83\xe2\x08\xff\xc2\xff\x15\xff\x2a\x00\x00\x4c\x63\xf0\x85\xc0\x75\x07\x33\xff\xe9\xf1\x00\x00\x00\x49\x8b\xfe\x48\x03\xff\x48\x8d\x4f\x10\x48\x3b\xf9\x48\x1b\xc0\x48\x85\xc1\x74\x75\x48\x8d\x4f\x10\x48\x3b\xf9\x48\x1b\xc0\x48\x23\xc1\x48\x3d\x00\x04\x00\x00\x48\x8d\x47\x10\x77\x3a\x48\x3b\xf8\x48\x1b\xc9\x48\x23\xc8\x48\x8d\x41\x0f\x48\x3b\xc1\x77\x0a\x48\xb8\xf0\xff\xff\xff\xff\xff\xff\x0f\x48\x83\xe0\xf0\xe8\x3e\x1b\x00\x00\x48\x2b\xe0\x48\x8d\x5c\x24\x30\x48\x85\xdb\x74\x79\xc7\x03\xcc\xcc\x00\x00\xeb\x1c\x48\x3b\xf8\x48\x1b\xc9\x48\x23\xc8\xe8\x53\x85\xff\xff\x48\x8b\xd8\x48\x85\xc0\x74\x0e\xc7\x00\xdd\xdd\x00\x00\x48\x83\xc3\x10\xeb\x02\x33\xdb\x48\x85\xdb\x74\x48\x4c\x8b\xc7\x33\xd2\x48\x8b\xcb\xe8\xd3\x54\xff\xff\x45\x8b\xcf\x44\x89\x74\x24\x28\x4d\x8b\xc4\x48\x89\x5c\x24\x20\xba\x01\x00\x00\x00\x8b\xce\xff\x15\x36\x2a\x00\x00\x85\xc0\x74\x1a\x4c\x8b\x8d\x80\x00\x00\x00\x44\x8b\xc0\x48\x8b\xd3\x41\x8b\xcd\xff\x15\xfc\x28\x00\x00\x8b\xf8\xeb\x02\x33\xff\x48\x85\xdb\x74\x11\x48\x8d\x4b\xf0\x81\x39\xdd\xdd\x00\x00\x75\x05\xe8\x98\x84\xff\xff\x80\x7d\x18\x00\x74\x0b\x48\x8b\x45\x00\x83\xa0\xa8\x03\x00\x00\xfd\x8b\xc7\x48\x8b\x4d\x20\x48\x33\xcd\xe8\x71\x41\xff\xff\x48\x8b\x5d\x60\x48\x8b\x75\x68\x48\x8b\x7d\x70\x48\x8d\x65\x30\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5d\xc3\xcc\xcc\xcc\x48\x83\xec\x28\xe8\xe7\xbb\xff\xff\x33\xc9\x84\xc0\x0f\x94\xc1\x8b\xc1\x48\x83\xc4\x28\xc3\xcc\x48\x83\xec\x28\x48\x85\xc9\x75\x19\xe8\x72\x8c\xff\xff\xc7\x00\x16\x00\x00\x00\xe8\x47\x8b\xff\xff\x48\x83\xc8\xff\x48\x83\xc4\x28\xc3\x4c\x8b\xc1\x33\xd2\x48\x8b\x0d\x86\xe1\x00\x00\x48\x83\xc4\x28\x48\xff\x25\x23\x28\x00\x00\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xda\x48\x8b\xf9\x48\x85\xc9\x75\x0a\x48\x8b\xca\xe8\x2b\x84\xff\xff\xeb\x58\x48\x85\xd2\x75\x07\xe8\xdf\x83\xff\xff\xeb\x4a\x48\x83\xfa\xe0\x77\x39\x4c\x8b\xca\x4c\x8b\xc1\xeb\x1b\xe8\xe6\xc5\xff\xff\x85\xc0\x74\x28\x48\x8b\xcb\xe8\xc2\xc1\xff\xff\x85\xc0\x74\x1c\x4c\x8b\xcb\x4c\x8b\xc7\x48\x8b\x0d\x1d\xe1\x00\x00\x33\xd2\xff\x15\xb5\x27\x00\x00\x48\x85\xc0\x74\xd1\xeb\x0d\xe8\xd5\x8b\xff\xff\xc7\x00\x0c\x00\x00\x00\x33\xc0\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x48\x89\x5c\x24\x08\x4c\x89\x4c\x24\x20\x57\x48\x83\xec\x20\x49\x8b\xf9\x49\x8b\xd8\x8b\x0a\xe8\xe8\xd4\xff\xff\x90\x48\x8b\x03\x48\x63\x08\x48\x8b\xd1\x48\x8b\xc1\x48\xc1\xf8\x06\x4c\x8d\x05\x58\xda\x00\x00\x83\xe2\x3f\x48\xc1\xe2\x06\x49\x8b\x04\xc0\xf6\x44\x10\x38\x01\x74\x09\xe8\xcd\x00\x00\x00\x8b\xd8\xeb\x0e\xe8\x6c\x8b\xff\xff\xc7\x00\x09\x00\x00\x00\x83\xcb\xff\x8b\x0f\xe8\xc4\xd4\xff\xff\x8b\xc3\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x89\x4c\x24\x08\x48\x83\xec\x38\x48\x63\xd1\x83\xfa\xfe\x75\x15\xe8\x17\x8b\xff\xff\x83\x20\x00\xe8\x2f\x8b\xff\xff\xc7\x00\x09\x00\x00\x00\xeb\x74\x85\xc9\x78\x58\x3b\x15\xe9\xdd\x00\x00\x73\x50\x48\x8b\xca\x4c\x8d\x05\xdd\xd9\x00\x00\x83\xe1\x3f\x48\x8b\xc2\x48\xc1\xf8\x06\x48\xc1\xe1\x06\x49\x8b\x04\xc0\xf6\x44\x08\x38\x01\x74\x2d\x48\x8d\x44\x24\x40\x89\x54\x24\x50\x89\x54\x24\x58\x4c\x8d\x4c\x24\x50\x48\x8d\x54\x24\x58\x48\x89\x44\x24\x20\x4c\x8d\x44\x24\x20\x48\x8d\x4c\x24\x48\xe8\x0d\xff\xff\xff\xeb\x1b\xe8\xa6\x8a\xff\xff\x83\x20\x00\xe8\xbe\x8a\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\x93\x89\xff\xff\x83\xc8\xff\x48\x83\xc4\x38\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x63\xf9\x8b\xcf\xe8\xdc\xd4\xff\xff\x48\x83\xf8\xff\x75\x04\x33\xdb\xeb\x57\x48\x8b\x05\x4f\xd9\x00\x00\xb9\x02\x00\x00\x00\x83\xff\x01\x75\x09\x40\x84\xb8\xb8\x00\x00\x00\x75\x0a\x3b\xf9\x75\x1d\xf6\x40\x78\x01\x74\x17\xe8\xa9\xd4\xff\xff\xb9\x01\x00\x00\x00\x48\x8b\xd8\xe8\x9c\xd4\xff\xff\x48\x3b\xc3\x74\xc1\x8b\xcf\xe8\x90\xd4\xff\xff\x48\x8b\xc8\xff\x15\x0b\x26\x00\x00\x85\xc0\x75\xad\xff\x15\xc9\x27\x00\x00\x8b\xd8\x8b\xcf\xe8\xb8\xd3\xff\xff\x48\x8b\xd7\x4c\x8d\x05\xee\xd8\x00\x00\x83\xe2\x3f\x48\x8b\xcf\x48\xc1\xf9\x06\x48\xc1\xe2\x06\x49\x8b\x0c\xc8\xc6\x44\x11\x38\x00\x85\xdb\x74\x0c\x8b\xcb\xe8\x90\x89\xff\xff\x83\xc8\xff\xeb\x02\x33\xc0\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\x48\x89\x4c\x24\x08\x4c\x8b\xdc\x33\xd2\x48\x89\x11\x49\x8b\x43\x08\x48\x89\x50\x08\x49\x8b\x43\x08\x89\x50\x10\x49\x8b\x43\x08\x83\x48\x18\xff\x49\x8b\x43\x08\x89\x50\x1c\x49\x8b\x43\x08\x89\x50\x20\x49\x8b\x43\x08\x48\x89\x50\x28\x49\x8b\x43\x08\x87\x50\x14\xc3\xcc\xcc\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x18\x89\x4c\x24\x08\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xec\x20\x45\x8b\xf8\x4c\x8b\xe2\x48\x63\xd9\x83\xfb\xfe\x75\x18\xe8\x5a\x89\xff\xff\x83\x20\x00\xe8\x72\x89\xff\xff\xc7\x00\x09\x00\x00\x00\xe9\x93\x00\x00\x00\x85\xc9\x78\x77\x3b\x1d\x29\xdc\x00\x00\x73\x6f\x48\x8b\xf3\x4c\x8b\xf3\x49\xc1\xfe\x06\x4c\x8d\x2d\x16\xd8\x00\x00\x83\xe6\x3f\x48\xc1\xe6\x06\x4b\x8b\x44\xf5\x00\x0f\xb6\x4c\x30\x38\x83\xe1\x01\x74\x48\x8b\xcb\xe8\x71\xd2\xff\xff\x48\x83\xcf\xff\x4b\x8b\x44\xf5\x00\xf6\x44\x30\x38\x01\x75\x15\xe8\x18\x89\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\xed\x88\xff\xff\x83\x20\x00\xeb\x10\x45\x8b\xc7\x49\x8b\xd4\x8b\xcb\xe8\x43\x00\x00\x00\x48\x8b\xf8\x8b\xcb\xe8\x59\xd2\xff\xff\x48\x8b\xc7\xeb\x1c\xe8\xc7\x88\xff\xff\x83\x20\x00\xe8\xdf\x88\xff\xff\xc7\x00\x09\x00\x00\x00\xe8\xb4\x87\xff\xff\x48\x83\xc8\xff\x48\x8b\x5c\x24\x58\x48\x8b\x74\x24\x60\x48\x83\xc4\x20\x41\x5f\x41\x5e\x41\x5d\x41\x5c\x5f\xc3\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x48\x63\xd9\x41\x8b\xf8\x8b\xcb\x48\x8b\xf2\xe8\xe1\xd2\xff\xff\x48\x83\xf8\xff\x75\x11\xe8\x8e\x88\xff\xff\xc7\x00\x09\x00\x00\x00\x48\x83\xc8\xff\xeb\x53\x44\x8b\xcf\x4c\x8d\x44\x24\x48\x48\x8b\xd6\x48\x8b\xc8\xff\x15\x32\x24\x00\x00\x85\xc0\x75\x0f\xff\x15\xf8\x25\x00\x00\x8b\xc8\xe8\xed\x87\xff\xff\xeb\xd3\x48\x8b\x44\x24\x48\x48\x83\xf8\xff\x74\xc8\x48\x8b\xd3\x4c\x8d\x05\x12\xd7\x00\x00\x83\xe2\x3f\x48\x8b\xcb\x48\xc1\xf9\x06\x48\xc1\xe2\x06\x49\x8b\x0c\xc8\x80\x64\x11\x38\xfd\x48\x8b\x5c\x24\x30\x48\x8b\x74\x24\x38\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\xe9\x6f\xfe\xff\xff\xcc\xcc\xcc\xe9\x57\xff\xff\xff\xcc\xcc\xcc\x66\x89\x4c\x24\x08\x48\x83\xec\x38\x48\x8b\x0d\xe8\xcc\x00\x00\x48\x83\xf9\xfe\x75\x0c\xe8\xfd\x07\x00\x00\x48\x8b\x0d\xd6\xcc\x00\x00\x48\x83\xf9\xff\x75\x07\xb8\xff\xff\x00\x00\xeb\x25\x48\x83\x64\x24\x20\x00\x4c\x8d\x4c\x24\x48\x41\xb8\x01\x00\x00\x00\x48\x8d\x54\x24\x40\xff\x15\x7d\x23\x00\x00\x85\xc0\x74\xd9\x0f\xb7\x44\x24\x40\x48\x83\xc4\x38\xc3\xcc\xcc\xcc\x8b\x05\x42\xdd\x00\x00\xc3\xcc\x33\xc0\x38\x01\x74\x0e\x48\x3b\xc2\x74\x09\x48\xff\xc0\x80\x3c\x08\x00\x75\xf2\xc3\xcc\xcc\xcc\x40\x53\x48\x83\xec\x20\x48\x8b\xd9\xe8\xea\x07\x00\x00\x89\x03\xe8\xfb\x07\x00\x00\x89\x43\x04\x33\xc0\x48\x83\xc4\x20\x5b\xc3\x40\x53\x48\x83\xec\x20\x83\x64\x24\x30\x00\x48\x8b\xd9\x8b\x09\x83\x64\x24\x34\x00\xe8\xea\x07\x00\x00\x8b\x4b\x04\xe8\xee\x07\x00\x00\x48\x8d\x4c\x24\x30\xe8\xb4\xff\xff\xff\x8b\x44\x24\x30\x39\x03\x75\x0d\x8b\x44\x24\x34\x39\x43\x04\x75\x04\x33\xc0\xeb\x05\xb8\x01\x00\x00\x00\x48\x83\xc4\x20\x5b\xc3\x40\x53\x48\x83\xec\x20\x83\x64\x24\x38\x00\x48\x8b\xd9\x83\x64\x24\x3c\x00\x48\x8d\x4c\x24\x38\xe8\x77\xff\xff\xff\x85\xc0\x74\x07\xb8\x01\x00\x00\x00\xeb\x22\x48\x8b\x44\x24\x38\x48\x8d\x4c\x24\x38\x83\x4c\x24\x38\x1f\x48\x89\x03\xe8\x75\xff\xff\xff\x85\xc0\x75\xde\xe8\xcc\x07\x00\x00\x33\xc0\x48\x83\xc4\x20\x5b\xc3\x45\x33\xc0\xf2\x0f\x11\x44\x24\x08\x48\x8b\x54\x24\x08\x48\xb9\xff\xff\xff\xff\xff\xff\xff\x7f\x48\x8b\xc2\x48\x23\xc1\x48\xb9\x00\x00\x00\x00\x00\x00\x40\x43\x48\x3b\xd0\x41\x0f\x95\xc0\x48\x3b\xc1\x72\x17\x48\xb9\x00\x00\x00\x00\x00\x00\xf0\x7f\x48\x3b\xc1\x76\x7e\x48\x8b\xca\xe9\x05\x0d\x00\x00\x48\xb9\x00\x00\x00\x00\x00\x00\xf0\x3f\x48\x3b\xc1\x73\x2b\x48\x85\xc0\x74\x62\x4d\x85\xc0\x74\x17\x48\xb8\x00\x00\x00\x00\x00\x00\x00\x80\x48\x89\x44\x24\x08\xf2\x0f\x10\x44\x24\x08\xeb\x46\xf2\x0f\x10\x05\x7d\x84\x00\x00\xeb\x3c\x48\x8b\xc2\xb9\x33\x00\x00\x00\x48\xc1\xe8\x34\x2a\xc8\xb8\x01\x00\x00\x00\x48\xd3\xe0\x48\xff\xc8\x48\xf7\xd0\x48\x23\xc2\x48\x89\x44\x24\x08\xf2\x0f\x10\x44\x24\x08\x4d\x85\xc0\x75\x0d\x48\x3b\xc2\x74\x08\xf2\x0f\x58\x05\x3f\x84\x00\x00\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x83\xec\x58\x66\x0f\x7f\x74\x24\x20\x83\x3d\x93\xdb\x00\x00\x00\x0f\x85\xe9\x02\x00\x00\x66\x0f\x28\xd8\x66\x0f\x28\xe0\x66\x0f\x73\xd3\x34\x66\x48\x0f\x7e\xc0\x66\x0f\xfb\x1d\x4f\x84\x00\x00\x66\x0f\x28\xe8\x66\x0f\x54\x2d\x13\x84\x00\x00\x66\x0f\x2f\x2d\x0b\x84\x00\x00\x0f\x84\x85\x02\x00\x00\x66\x0f\x28\xd0\xf3\x0f\xe6\xf3\x66\x0f\x57\xed\x66\x0f\x2f\xc5\x0f\x86\x2f\x02\x00\x00\x66\x0f\xdb\x15\x37\x84\x00\x00\xf2\x0f\x5c\x25\xbf\x84\x00\x00\x66\x0f\x2f\x35\x47\x85\x00\x00\x0f\x84\xd8\x01\x00\x00\x66\x0f\x54\x25\x99\x85\x00\x00\x4c\x8b\xc8\x48\x23\x05\x1f\x84\x00\x00\x4c\x23\x0d\x28\x84\x00\x00\x49\xd1\xe1\x49\x03\xc1\x66\x48\x0f\x6e\xc8\x66\x0f\x2f\x25\x35\x85\x00\x00\x0f\x82\xdf\x00\x00\x00\x48\xc1\xe8\x2c\x66\x0f\xeb\x15\x83\x84\x00\x00\x66\x0f\xeb\x0d\x7b\x84\x00\x00\x4c\x8d\x0d\xf4\x95\x00\x00\xf2\x0f\x5c\xca\xf2\x41\x0f\x59\x0c\xc1\x66\x0f\x28\xd1\x66\x0f\x28\xc1\x4c\x8d\x0d\xbb\x85\x00\x00\xf2\x0f\x10\x1d\xc3\x84\x00\x00\xf2\x0f\x10\x0d\x8b\x84\x00\x00\xf2\x0f\x59\xda\xf2\x0f\x59\xca\xf2\x0f\x59\xc2\x66\x0f\x28\xe0\xf2\x0f\x58\x1d\x93\x84\x00\x00\xf2\x0f\x58\x0d\x5b\x84\x00\x00\xf2\x0f\x59\xe0\xf2\x0f\x59\xda\xf2\x0f\x59\xc8\xf2\x0f\x58\x1d\x67\x84\x00\x00\xf2\x0f\x58\xca\xf2\x0f\x59\xdc\xf2\x0f\x58\xcb\xf2\x0f\x10\x2d\xd3\x83\x00\x00\xf2\x0f\x59\x0d\x8b\x83\x00\x00\xf2\x0f\x59\xee\xf2\x0f\x5c\xe9\xf2\x41\x0f\x10\x04\xc1\x48\x8d\x15\x56\x8d\x00\x00\xf2\x0f\x10\x14\xc2\xf2\x0f\x10\x25\x99\x83\x00\x00\xf2\x0f\x59\xe6\xf2\x0f\x58\xc4\xf2\x0f\x58\xd5\xf2\x0f\x58\xc2\x66\x0f\x6f\x74\x24\x20\x48\x83\xc4\x58\xc3\x66\x66\x66\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\xf2\x0f\x10\x15\x88\x83\x00\x00\xf2\x0f\x5c\x05\x90\x83\x00\x00\xf2\x0f\x58\xd0\x66\x0f\x28\xc8\xf2\x0f\x5e\xca\xf2\x0f\x10\x25\x8c\x84\x00\x00\xf2\x0f\x10\x2d\xa4\x84\x00\x00\x66\x0f\x28\xf0\xf2\x0f\x59\xf1\xf2\x0f\x58\xc9\x66\x0f\x28\xd1\xf2\x0f\x59\xd1\xf2\x0f\x59\xe2\xf2\x0f\x59\xea\xf2\x0f\x58\x25\x50\x84\x00\x00\xf2\x0f\x58\x2d\x68\x84\x00\x00\xf2\x0f\x59\xd1\xf2\x0f\x59\xe2\xf2\x0f\x59\xd2\xf2\x0f\x59\xd1\xf2\x0f\x59\xea\xf2\x0f\x10\x15\xec\x82\x00\x00\xf2\x0f\x58\xe5\xf2\x0f\x5c\xe6\xf2\x0f\x10\x35\xcc\x82\x00\x00\x66\x0f\x28\xd8\x66\x0f\xdb\x1d\x50\x84\x00\x00\xf2\x0f\x5c\xc3\xf2\x0f\x58\xe0\x66\x0f\x28\xc3\x66\x0f\x28\xcc\xf2\x0f\x59\xe2\xf2\x0f\x59\xc2\xf2\x0f\x59\xce\xf2\x0f\x59\xde\xf2\x0f\x58\xc4\xf2\x0f\x58\xc1\xf2\x0f\x58\xc3\x66\x0f\x6f\x74\x24\x20\x48\x83\xc4\x58\xc3\x66\x0f\xeb\x15\xd1\x82\x00\x00\xf2\x0f\x5c\x15\xc9\x82\x00\x00\xf2\x0f\x10\xea\x66\x0f\xdb\x15\x2d\x82\x00\x00\x66\x48\x0f\x7e\xd0\x66\x0f\x73\xd5\x34\x66\x0f\xfa\x2d\x4b\x83\x00\x00\xf3\x0f\xe6\xf5\xe9\xf1\xfd\xff\xff\x66\x90\x75\x1e\xf2\x0f\x10\x0d\xa6\x81\x00\x00\x44\x8b\x05\xdf\x83\x00\x00\xe8\x6a\x0a\x00\x00\xeb\x48\x0f\x1f\x84\x00\x00\x00\x00\x00\xf2\x0f\x10\x0d\xa8\x81\x00\x00\x44\x8b\x05\xc5\x83\x00\x00\xe8\x4c\x0a\x00\x00\xeb\x2a\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x3b\x05\x79\x81\x00\x00\x74\x17\x48\x3b\x05\x60\x81\x00\x00\x74\xce\x48\x0b\x05\x87\x81\x00\x00\x66\x48\x0f\x6e\xc0\x66\x90\x66\x0f\x6f\x74\x24\x20\x48\x83\xc4\x58\xc3\x0f\x1f\x44\x00\x00\x48\x33\xc0\xc5\xe1\x73\xd0\x34\xc4\xe1\xf9\x7e\xc0\xc5\xe1\xfb\x1d\x6b\x81\x00\x00\xc5\xfa\xe6\xf3\xc5\xf9\xdb\x2d\x2f\x81\x00\x00\xc5\xf9\x2f\x2d\x27\x81\x00\x00\x0f\x84\x41\x02\x00\x00\xc5\xd1\xef\xed\xc5\xf9\x2f\xc5\x0f\x86\xe3\x01\x00\x00\xc5\xf9\xdb\x15\x5b\x81\x00\x00\xc5\xfb\x5c\x25\xe3\x81\x00\x00\xc5\xf9\x2f\x35\x6b\x82\x00\x00\x0f\x84\x8e\x01\x00\x00\xc5\xf9\xdb\x0d\x4d\x81\x00\x00\xc5\xf9\xdb\x1d\x55\x81\x00\x00\xc5\xe1\x73\xf3\x01\xc5\xe1\xd4\xc9\xc4\xe1\xf9\x7e\xc8\xc5\xd9\xdb\x25\x9f\x82\x00\x00\xc5\xf9\x2f\x25\x57\x82\x00\x00\x0f\x82\xb1\x00\x00\x00\x48\xc1\xe8\x2c\xc5\xe9\xeb\x15\xa5\x81\x00\x00\xc5\xf1\xeb\x0d\x9d\x81\x00\x00\x4c\x8d\x0d\x16\x93\x00\x00\xc5\xf3\x5c\xca\xc4\xc1\x73\x59\x0c\xc1\x4c\x8d\x0d\xe5\x82\x00\x00\xc5\xf3\x59\xc1\xc5\xfb\x10\x1d\xe9\x81\x00\x00\xc5\xfb\x10\x2d\xb1\x81\x00\x00\xc4\xe2\xf1\xa9\x1d\xc8\x81\x00\x00\xc4\xe2\xf1\xa9\x2d\x5f\x81\x00\x00\xf2\x0f\x10\xe0\xc4\xe2\xf1\xa9\x1d\xa2\x81\x00\x00\xc5\xfb\x59\xe0\xc4\xe2\xd1\xb9\xc8\xc4\xe2\xe1\xb9\xcc\xc5\xf3\x59\x0d\xcc\x80\x00\x00\xc5\xfb\x10\x2d\x04\x81\x00\x00\xc4\xe2\xc9\xab\xe9\xf2\x41\x0f\x10\x04\xc1\x48\x8d\x15\x92\x8a\x00\x00\xf2\x0f\x10\x14\xc2\xc5\xeb\x58\xd5\xc4\xe2\xc9\xb9\x05\xd0\x80\x00\x00\xc5\xfb\x58\xc2\xc5\xf9\x6f\x74\x24\x20\x48\x83\xc4\x58\xc3\x90\xc5\xfb\x10\x15\xd8\x80\x00\x00\xc5\xfb\x5c\x05\xe0\x80\x00\x00\xc5\xeb\x58\xd0\xc5\xfb\x5e\xca\xc5\xfb\x10\x25\xe0\x81\x00\x00\xc5\xfb\x10\x2d\xf8\x81\x00\x00\xc5\xfb\x59\xf1\xc5\xf3\x58\xc9\xc5\xf3\x59\xd1\xc4\xe2\xe9\xa9\x25\xb3\x81\x00\x00\xc4\xe2\xe9\xa9\x2d\xca\x81\x00\x00\xc5\xeb\x59\xd1\xc5\xdb\x59\xe2\xc5\xeb\x59\xd2\xc5\xeb\x59\xd1\xc5\xd3\x59\xea\xc5\xdb\x58\xe5\xc5\xdb\x5c\xe6\xc5\xf9\xdb\x1d\xc6\x81\x00\x00\xc5\xfb\x5c\xc3\xc5\xdb\x58\xe0\xc5\xdb\x59\x0d\x26\x80\x00\x00\xc5\xdb\x59\x25\x2e\x80\x00\x00\xc5\xe3\x59\x05\x26\x80\x00\x00\xc5\xe3\x59\x1d\x0e\x80\x00\x00\xc5\xfb\x58\xc4\xc5\xfb\x58\xc1\xc5\xfb\x58\xc3\xc5\xf9\x6f\x74\x24\x20\x48\x83\xc4\x58\xc3\xc5\xe9\xeb\x15\x3f\x80\x00\x00\xc5\xeb\x5c\x15\x37\x80\x00\x00\xc5\xd1\x73\xd2\x34\xc5\xe9\xdb\x15\x9a\x7f\x00\x00\xc5\xf9\x28\xc2\xc5\xd1\xfa\x2d\xbe\x80\x00\x00\xc5\xfa\xe6\xf5\xe9\x40\xfe\xff\xff\x0f\x1f\x44\x00\x00\x75\x2e\xc5\xfb\x10\x0d\x16\x7f\x00\x00\x44\x8b\x05\x4f\x81\x00\x00\xe8\xda\x07\x00\x00\xc5\xf9\x6f\x74\x24\x20\x48\x83\xc4\x58\xc3\x66\x66\x66\x66\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\xc5\xfb\x10\x0d\x08\x7f\x00\x00\x44\x8b\x05\x25\x81\x00\x00\xe8\xac\x07\x00\x00\xc5\xf9\x6f\x74\x24\x20\x48\x83\xc4\x58\xc3\x90\x48\x3b\x05\xd9\x7e\x00\x00\x74\x27\x48\x3b\x05\xc0\x7e\x00\x00\x74\xce\x48\x0b\x05\xe7\x7e\x00\x00\x66\x48\x0f\x6e\xc8\x44\x8b\x05\xf3\x80\x00\x00\xe8\x76\x07\x00\x00\xeb\x04\x0f\x1f\x40\x00\xc5\xf9\x6f\x74\x24\x20\x48\x83\xc4\x58\xc3\xcc\x40\x53\x48\x83\xec\x20\xff\x05\xf8\xcc\x00\x00\x48\x8b\xd9\xb9\x00\x10\x00\x00\xe8\x43\x78\xff\xff\x33\xc9\x48\x89\x43\x08\xe8\xf8\x77\xff\xff\x48\x83\x7b\x08\x00\x74\x0e\xf0\x83\x4b\x14\x40\xc7\x43\x20\x00\x10\x00\x00\xeb\x17\xf0\x81\x4b\x14\x00\x04\x00\x00\x48\x8d\x43\x1c\xc7\x43\x20\x02\x00\x00\x00\x48\x89\x43\x08\x48\x8b\x43\x08\x83\x63\x10\x00\x48\x89\x03\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x48\x83\xec\x48\x48\x83\x64\x24\x30\x00\x48\x8d\x0d\x6f\x80\x00\x00\x83\x64\x24\x28\x00\x41\xb8\x03\x00\x00\x00\x45\x33\xc9\x44\x89\x44\x24\x20\xba\x00\x00\x00\x40\xff\x15\x79\x1b\x00\x00\x48\x89\x05\xaa\xc4\x00\x00\x48\x83\xc4\x48\xc3\xcc\x48\x83\xec\x28\x48\x8b\x0d\x99\xc4\x00\x00\x48\x8d\x41\x02\x48\x83\xf8\x01\x76\x06\xff\x15\x69\x1b\x00\x00\x48\x83\xc4\x28\xc3\x48\x83\xec\x28\x33\xd2\x33\xc9\xe8\xcf\x00\x00\x00\x25\x1f\x03\x00\x00\x48\x83\xc4\x28\xc3\xcc\x48\x83\xec\x28\xe8\xc7\x00\x00\x00\x83\xe0\x1f\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\xba\x1f\x03\x08\x00\xe9\xa6\x00\x00\x00\xcc\xcc\x40\x53\x48\x83\xec\x20\x8b\xd9\xe8\x2f\x07\x00\x00\x83\xe0\xc2\x33\xc9\xf6\xc3\x1f\x74\x2d\x8a\xd3\x44\x8d\x41\x01\x80\xe2\x10\x41\x0f\x45\xc8\xf6\xc3\x08\x74\x03\x83\xc9\x04\xf6\xc3\x04\x74\x03\x83\xc9\x08\xf6\xc3\x02\x74\x03\x83\xc9\x10\x41\x84\xd8\x74\x03\x83\xc9\x20\x0b\xc8\x48\x83\xc4\x20\x5b\xe9\xfc\x06\x00\x00\x40\x53\x48\x83\xec\x20\xe8\xe1\x06\x00\x00\x8b\xd8\xe8\xf4\x06\x00\x00\x33\xc0\xf6\xc3\x3f\x74\x33\x8a\xcb\x8d\x50\x10\x80\xe1\x01\x0f\x45\xc2\xf6\xc3\x04\x74\x03\x83\xc8\x08\xf6\xc3\x08\x74\x03\x83\xc8\x04\x84\xda\x74\x03\x83\xc8\x02\xf6\xc3\x20\x74\x03\x83\xc8\x01\xf6\xc3\x02\x74\x04\x0f\xba\xe8\x13\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\x0f\xba\xf2\x13\xe9\x4b\x00\x00\x00\xcc\xcc\xcc\x0f\xae\x5c\x24\x08\x8b\x54\x24\x08\x33\xc9\xf6\xc2\x3f\x74\x35\x8a\xc2\x44\x8d\x41\x10\x24\x01\x41\x0f\x45\xc8\xf6\xc2\x04\x74\x03\x83\xc9\x08\xf6\xc2\x08\x74\x03\x83\xc9\x04\x41\x84\xd0\x74\x03\x83\xc9\x02\xf6\xc2\x20\x74\x03\x83\xc9\x01\xf6\xc2\x02\x74\x04\x0f\xba\xe9\x13\x8b\xc1\xc3\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7c\x24\x20\x41\x54\x41\x56\x41\x57\x48\x83\xec\x20\x8b\xda\x8b\xf1\x81\xe3\x1f\x03\x08\x03\xe8\x1c\x06\x00\x00\x44\x8b\xc8\x33\xff\x44\x8a\xc0\x41\xbb\x80\x00\x00\x00\x8b\xc7\x8d\x4f\x10\x45\x22\xc3\x0f\x45\xc1\x41\xbc\x00\x02\x00\x00\x45\x85\xcc\x74\x03\x83\xc8\x08\x41\x0f\xba\xe1\x0a\x73\x03\x83\xc8\x04\x41\xb8\x00\x08\x00\x00\x45\x85\xc8\x74\x03\x83\xc8\x02\x41\xba\x00\x10\x00\x00\x45\x85\xca\x74\x03\x83\xc8\x01\x41\xbe\x00\x01\x00\x00\x45\x85\xce\x74\x04\x0f\xba\xe8\x13\x41\x8b\xc9\x41\xbf\x00\x60\x00\x00\x41\x23\xcf\x74\x24\x81\xf9\x00\x20\x00\x00\x74\x19\x81\xf9\x00\x40\x00\x00\x74\x0c\x41\x3b\xcf\x75\x0f\x0d\x00\x03\x00\x00\xeb\x08\x41\x0b\xc4\xeb\x03\x41\x0b\xc6\xba\x40\x80\x00\x00\x44\x23\xca\x41\x83\xe9\x40\x74\x1c\x41\x81\xe9\xc0\x7f\x00\x00\x74\x0c\x41\x83\xf9\x40\x75\x11\x0f\xba\xe8\x18\xeb\x0b\x0d\x00\x00\x00\x03\xeb\x04\x0f\xba\xe8\x19\x8b\xcb\xf7\xd1\x23\xc8\x23\xf3\x0b\xce\x3b\xc8\x0f\x84\x86\x01\x00\x00\x8a\xc1\xbe\x10\x00\x00\x00\x8b\xdf\x40\x22\xc6\x41\x0f\x45\xdb\x89\x5c\x24\x40\xf6\xc1\x08\x74\x07\x41\x0b\xdc\x89\x5c\x24\x40\xf6\xc1\x04\x74\x08\x0f\xba\xeb\x0a\x89\x5c\x24\x40\xf6\xc1\x02\x74\x07\x41\x0b\xd8\x89\x5c\x24\x40\xf6\xc1\x01\x74\x07\x41\x0b\xda\x89\x5c\x24\x40\x0f\xba\xe1\x13\x73\x07\x41\x0b\xde\x89\x5c\x24\x40\x8b\xc1\x25\x00\x03\x00\x00\x74\x24\x41\x3b\xc6\x74\x17\x41\x3b\xc4\x74\x0c\x3d\x00\x03\x00\x00\x75\x13\x41\x0b\xdf\xeb\x0a\x0f\xba\xeb\x0e\xeb\x04\x0f\xba\xeb\x0d\x89\x5c\x24\x40\x81\xe1\x00\x00\x00\x03\x81\xf9\x00\x00\x00\x01\x74\x1b\x81\xf9\x00\x00\x00\x02\x74\x0e\x81\xf9\x00\x00\x00\x03\x75\x11\x0f\xba\xeb\x0f\xeb\x07\x83\xcb\x40\xeb\x02\x0b\xda\x89\x5c\x24\x40\x40\x38\x3d\xb1\xc1\x00\x00\x74\x3c\xf6\xc3\x40\x74\x37\x8b\xcb\xe8\x9b\x04\x00\x00\xeb\x2c\xc6\x05\x9a\xc1\x00\x00\x00\x8b\x5c\x24\x40\x83\xe3\xbf\x8b\xcb\xe8\x84\x04\x00\x00\x33\xff\x8d\x77\x10\x41\xbc\x00\x02\x00\x00\x41\xbe\x00\x01\x00\x00\x41\xbf\x00\x60\x00\x00\xeb\x0a\x83\xe3\xbf\x8b\xcb\xe8\x61\x04\x00\x00\x8a\xc3\x24\x80\x0f\x45\xfe\x41\x85\xdc\x74\x03\x83\xcf\x08\x0f\xba\xe3\x0a\x73\x03\x83\xcf\x04\x0f\xba\xe3\x0b\x73\x03\x83\xcf\x02\x0f\xba\xe3\x0c\x73\x03\x83\xcf\x01\x41\x85\xde\x74\x04\x0f\xba\xef\x13\x8b\xc3\x41\x23\xc7\x74\x23\x3d\x00\x20\x00\x00\x74\x19\x3d\x00\x40\x00\x00\x74\x0d\x41\x3b\xc7\x75\x10\x81\xcf\x00\x03\x00\x00\xeb\x08\x41\x0b\xfc\xeb\x03\x41\x0b\xfe\x81\xe3\x40\x80\x00\x00\x83\xeb\x40\x74\x1b\x81\xeb\xc0\x7f\x00\x00\x74\x0b\x83\xfb\x40\x75\x12\x0f\xba\xef\x18\xeb\x0c\x81\xcf\x00\x00\x00\x03\xeb\x04\x0f\xba\xef\x19\x8b\xc7\x48\x8b\x5c\x24\x48\x48\x8b\x74\x24\x50\x48\x8b\x7c\x24\x58\x48\x83\xc4\x20\x41\x5f\x41\x5e\x41\x5c\xc3\xcc\xcc\x48\x8b\xc4\x53\x48\x83\xec\x50\xf2\x0f\x10\x84\x24\x80\x00\x00\x00\x8b\xd9\xf2\x0f\x10\x8c\x24\x88\x00\x00\x00\xba\xc0\xff\x00\x00\x89\x48\xc8\x48\x8b\x8c\x24\x90\x00\x00\x00\xf2\x0f\x11\x40\xe0\xf2\x0f\x11\x48\xe8\xf2\x0f\x11\x58\xd8\x4c\x89\x40\xd0\xe8\x38\x07\x00\x00\x48\x8d\x4c\x24\x20\xe8\x1a\xb5\xff\xff\x85\xc0\x75\x07\x8b\xcb\xe8\xd3\x06\x00\x00\xf2\x0f\x10\x44\x24\x40\x48\x83\xc4\x50\x5b\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x48\x89\x74\x24\x10\x57\x48\x83\xec\x20\x8b\xd9\x48\x8b\xf2\x83\xe3\x1f\x8b\xf9\xf6\xc1\x08\x74\x13\x84\xd2\x79\x0f\xb9\x01\x00\x00\x00\xe8\x64\x07\x00\x00\x83\xe3\xf7\xeb\x57\xb9\x04\x00\x00\x00\x40\x84\xf9\x74\x11\x48\x0f\xba\xe2\x09\x73\x0a\xe8\x49\x07\x00\x00\x83\xe3\xfb\xeb\x3c\x40\xf6\xc7\x01\x74\x16\x48\x0f\xba\xe2\x0a\x73\x0f\xb9\x08\x00\x00\x00\xe8\x2d\x07\x00\x00\x83\xe3\xfe\xeb\x20\x40\xf6\xc7\x02\x74\x1a\x48\x0f\xba\xe2\x0b\x73\x13\x40\xf6\xc7\x10\x74\x0a\xb9\x10\x00\x00\x00\xe8\x0b\x07\x00\x00\x83\xe3\xfd\x40\xf6\xc7\x10\x74\x14\x48\x0f\xba\xe6\x0c\x73\x0d\xb9\x20\x00\x00\x00\xe8\xf1\x06\x00\x00\x83\xe3\xef\x48\x8b\x74\x24\x38\x33\xc0\x85\xdb\x48\x8b\x5c\x24\x30\x0f\x94\xc0\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x8b\xc4\x55\x53\x56\x57\x41\x56\x48\x8d\x68\xc9\x48\x81\xec\xf0\x00\x00\x00\x0f\x29\x70\xc8\x48\x8b\x05\x19\xb6\x00\x00\x48\x33\xc4\x48\x89\x45\xef\x8b\xf2\x4c\x8b\xf1\xba\xc0\xff\x00\x00\xb9\x80\x1f\x00\x00\x41\x8b\xf9\x49\x8b\xd8\xe8\x18\x06\x00\x00\x8b\x4d\x5f\x48\x89\x44\x24\x40\x48\x89\x5c\x24\x50\xf2\x0f\x10\x44\x24\x50\x48\x8b\x54\x24\x40\xf2\x0f\x11\x44\x24\x48\xe8\xe1\xfe\xff\xff\xf2\x0f\x10\x75\x77\x85\xc0\x75\x40\x83\x7d\x7f\x02\x75\x11\x8b\x45\xbf\x83\xe0\xe3\xf2\x0f\x11\x75\xaf\x83\xc8\x03\x89\x45\xbf\x44\x8b\x45\x5f\x48\x8d\x44\x24\x48\x48\x89\x44\x24\x28\x48\x8d\x54\x24\x40\x48\x8d\x45\x6f\x44\x8b\xce\x48\x8d\x4c\x24\x60\x48\x89\x44\x24\x20\xe8\x2c\x02\x00\x00\xe8\x6b\xb3\xff\xff\x84\xc0\x74\x34\x85\xff\x74\x30\x48\x8b\x44\x24\x40\x4d\x8b\xc6\xf2\x0f\x10\x44\x24\x48\x8b\xcf\xf2\x0f\x10\x5d\x6f\x8b\x55\x67\x48\x89\x44\x24\x30\xf2\x0f\x11\x44\x24\x28\xf2\x0f\x11\x74\x24\x20\xe8\xf5\xfd\xff\xff\xeb\x1c\x8b\xcf\xe8\x18\x05\x00\x00\x48\x8b\x4c\x24\x40\xba\xc0\xff\x00\x00\xe8\x59\x05\x00\x00\xf2\x0f\x10\x44\x24\x48\x48\x8b\x4d\xef\x48\x33\xcc\xe8\x57\x2e\xff\xff\x0f\x28\xb4\x24\xe0\x00\x00\x00\x48\x81\xc4\xf0\x00\x00\x00\x41\x5e\x5f\x5e\x5b\x5d\xc3\xcc\x48\xb8\x00\x00\x00\x00\x00\x00\x08\x00\x48\x0b\xc8\x48\x89\x4c\x24\x08\xf2\x0f\x10\x44\x24\x08\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x40\x53\x48\x83\xec\x10\x45\x33\xc0\x33\xc9\x44\x89\x05\xee\xce\x00\x00\x45\x8d\x48\x01\x41\x8b\xc1\x0f\xa2\x89\x04\x24\xb8\x00\x10\x00\x18\x89\x4c\x24\x08\x23\xc8\x89\x5c\x24\x04\x89\x54\x24\x0c\x3b\xc8\x75\x2c\x33\xc9\x0f\x01\xd0\x48\xc1\xe2\x20\x48\x0b\xd0\x48\x89\x54\x24\x20\x48\x8b\x44\x24\x20\x44\x8b\x05\xae\xce\x00\x00\x24\x06\x3c\x06\x45\x0f\x44\xc1\x44\x89\x05\x9f\xce\x00\x00\x44\x89\x05\x9c\xce\x00\x00\x33\xc0\x48\x83\xc4\x10\x5b\xc3\x48\x83\xec\x38\x48\x8d\x05\xb5\x91\x00\x00\x41\xb9\x1b\x00\x00\x00\x48\x89\x44\x24\x20\xe8\x05\x00\x00\x00\x48\x83\xc4\x38\xc3\x48\x8b\xc4\x48\x83\xec\x68\x0f\x29\x70\xe8\x0f\x28\xf1\x41\x8b\xd1\x0f\x28\xd8\x41\x83\xe8\x01\x74\x2a\x41\x83\xf8\x01\x75\x69\x44\x89\x40\xd8\x0f\x57\xd2\xf2\x0f\x11\x50\xd0\x45\x8b\xc8\xf2\x0f\x11\x40\xc8\xc7\x40\xc0\x21\x00\x00\x00\xc7\x40\xb8\x08\x00\x00\x00\xeb\x2d\xc7\x44\x24\x40\x01\x00\x00\x00\x0f\x57\xc0\xf2\x0f\x11\x44\x24\x38\x41\xb9\x02\x00\x00\x00\xf2\x0f\x11\x5c\x24\x30\xc7\x44\x24\x28\x22\x00\x00\x00\xc7\x44\x24\x20\x04\x00\x00\x00\x48\x8b\x8c\x24\x90\x00\x00\x00\xf2\x0f\x11\x4c\x24\x78\x4c\x8b\x44\x24\x78\xe8\x9f\xfd\xff\xff\x0f\x28\xc6\x0f\x28\x74\x24\x50\x48\x83\xc4\x68\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x83\xec\x08\x0f\xae\x1c\x24\x8b\x04\x24\x48\x83\xc4\x08\xc3\x89\x4c\x24\x08\x0f\xae\x54\x24\x08\xc3\x0f\xae\x5c\x24\x08\xb9\xc0\xff\xff\xff\x21\x4c\x24\x08\x0f\xae\x54\x24\x08\xc3\x66\x0f\x2e\x05\xca\x90\x00\x00\x73\x14\x66\x0f\x2e\x05\xc8\x90\x00\x00\x76\x0a\xf2\x48\x0f\x2d\xc8\xf2\x48\x0f\x2a\xc1\xc3\xcc\xcc\xcc\x48\x83\xec\x48\x83\x64\x24\x30\x00\x48\x8b\x44\x24\x78\x48\x89\x44\x24\x28\x48\x8b\x44\x24\x70\x48\x89\x44\x24\x20\xe8\x06\x00\x00\x00\x48\x83\xc4\x48\xc3\xcc\x48\x8b\xc4\x48\x89\x58\x10\x48\x89\x70\x18\x48\x89\x78\x20\x48\x89\x48\x08\x55\x48\x8b\xec\x48\x83\xec\x20\x48\x8b\xda\x41\x8b\xf1\x33\xd2\xbf\x0d\x00\x00\xc0\x89\x51\x04\x48\x8b\x45\x10\x89\x50\x08\x48\x8b\x45\x10\x89\x50\x0c\x41\xf6\xc0\x10\x74\x0d\x48\x8b\x45\x10\xbf\x8f\x00\x00\xc0\x83\x48\x04\x01\x41\xf6\xc0\x02\x74\x0d\x48\x8b\x45\x10\xbf\x93\x00\x00\xc0\x83\x48\x04\x02\x41\xf6\xc0\x01\x74\x0d\x48\x8b\x45\x10\xbf\x91\x00\x00\xc0\x83\x48\x04\x04\x41\xf6\xc0\x04\x74\x0d\x48\x8b\x45\x10\xbf\x8e\x00\x00\xc0\x83\x48\x04\x08\x41\xf6\xc0\x08\x74\x0d\x48\x8b\x45\x10\xbf\x90\x00\x00\xc0\x83\x48\x04\x10\x48\x8b\x4d\x10\x48\x8b\x03\x48\xc1\xe8\x07\xc1\xe0\x04\xf7\xd0\x33\x41\x08\x83\xe0\x10\x31\x41\x08\x48\x8b\x4d\x10\x48\x8b\x03\x48\xc1\xe8\x09\xc1\xe0\x03\xf7\xd0\x33\x41\x08\x83\xe0\x08\x31\x41\x08\x48\x8b\x4d\x10\x48\x8b\x03\x48\xc1\xe8\x0a\xc1\xe0\x02\xf7\xd0\x33\x41\x08\x83\xe0\x04\x31\x41\x08\x48\x8b\x4d\x10\x48\x8b\x03\x48\xc1\xe8\x0b\x03\xc0\xf7\xd0\x33\x41\x08\x83\xe0\x02\x31\x41\x08\x8b\x03\x48\x8b\x4d\x10\x48\xc1\xe8\x0c\xf7\xd0\x33\x41\x08\x83\xe0\x01\x31\x41\x08\xe8\xdf\x02\x00\x00\x48\x8b\xd0\xa8\x01\x74\x08\x48\x8b\x4d\x10\x83\x49\x0c\x10\xa8\x04\x74\x08\x48\x8b\x4d\x10\x83\x49\x0c\x08\xa8\x08\x74\x08\x48\x8b\x45\x10\x83\x48\x0c\x04\xf6\xc2\x10\x74\x08\x48\x8b\x45\x10\x83\x48\x0c\x02\xf6\xc2\x20\x74\x08\x48\x8b\x45\x10\x83\x48\x0c\x01\x8b\x03\xb9\x00\x60\x00\x00\x48\x23\xc1\x74\x3e\x48\x3d\x00\x20\x00\x00\x74\x26\x48\x3d\x00\x40\x00\x00\x74\x0e\x48\x3b\xc1\x75\x30\x48\x8b\x45\x10\x83\x08\x03\xeb\x27\x48\x8b\x45\x10\x83\x20\xfe\x48\x8b\x45\x10\x83\x08\x02\xeb\x17\x48\x8b\x45\x10\x83\x20\xfd\x48\x8b\x45\x10\x83\x08\x01\xeb\x07\x48\x8b\x45\x10\x83\x20\xfc\x48\x8b\x45\x10\x81\xe6\xff\x0f\x00\x00\xc1\xe6\x05\x81\x20\x1f\x00\xfe\xff\x48\x8b\x45\x10\x09\x30\x48\x8b\x45\x10\x48\x8b\x75\x38\x83\x48\x20\x01\x83\x7d\x40\x00\x74\x33\x48\x8b\x45\x10\xba\xe1\xff\xff\xff\x21\x50\x20\x48\x8b\x45\x30\x8b\x08\x48\x8b\x45\x10\x89\x48\x10\x48\x8b\x45\x10\x83\x48\x60\x01\x48\x8b\x45\x10\x21\x50\x60\x48\x8b\x45\x10\x8b\x0e\x89\x48\x50\xeb\x48\x48\x8b\x4d\x10\x41\xb8\xe3\xff\xff\xff\x8b\x41\x20\x41\x23\xc0\x83\xc8\x02\x89\x41\x20\x48\x8b\x45\x30\x48\x8b\x08\x48\x8b\x45\x10\x48\x89\x48\x10\x48\x8b\x45\x10\x83\x48\x60\x01\x48\x8b\x55\x10\x8b\x42\x60\x41\x23\xc0\x83\xc8\x02\x89\x42\x60\x48\x8b\x45\x10\x48\x8b\x16\x48\x89\x50\x50\xe8\xe6\x00\x00\x00\x33\xd2\x4c\x8d\x4d\x10\x8b\xcf\x44\x8d\x42\x01\xff\x15\xf4\x10\x00\x00\x48\x8b\x4d\x10\xf6\x41\x08\x10\x74\x05\x48\x0f\xba\x33\x07\xf6\x41\x08\x08\x74\x05\x48\x0f\xba\x33\x09\xf6\x41\x08\x04\x74\x05\x48\x0f\xba\x33\x0a\xf6\x41\x08\x02\x74\x05\x48\x0f\xba\x33\x0b\xf6\x41\x08\x01\x74\x05\x48\x0f\xba\x33\x0c\x8b\x01\x83\xe0\x03\x74\x30\x83\xe8\x01\x74\x1f\x83\xe8\x01\x74\x0e\x83\xf8\x01\x75\x28\x48\x81\x0b\x00\x60\x00\x00\xeb\x1f\x48\x0f\xba\x33\x0d\x48\x0f\xba\x2b\x0e\xeb\x13\x48\x0f\xba\x33\x0e\x48\x0f\xba\x2b\x0d\xeb\x07\x48\x81\x23\xff\x9f\xff\xff\x83\x7d\x40\x00\x74\x07\x8b\x41\x50\x89\x06\xeb\x07\x48\x8b\x41\x50\x48\x89\x06\x48\x8b\x5c\x24\x38\x48\x8b\x74\x24\x40\x48\x8b\x7c\x24\x48\x48\x83\xc4\x20\x5d\xc3\xcc\xcc\x48\x83\xec\x28\x83\xf9\x01\x74\x15\x8d\x41\xfe\x83\xf8\x01\x77\x18\xe8\x8e\x74\xff\xff\xc7\x00\x22\x00\x00\x00\xeb\x0b\xe8\x81\x74\xff\xff\xc7\x00\x21\x00\x00\x00\x48\x83\xc4\x28\xc3\xcc\xcc\x40\x53\x48\x83\xec\x20\xe8\x45\xfc\xff\xff\x8b\xd8\x83\xe3\x3f\xe8\x55\xfc\xff\xff\x8b\xc3\x48\x83\xc4\x20\x5b\xc3\xcc\xcc\xcc\x48\x89\x5c\x24\x18\x48\x89\x74\x24\x20\x57\x48\x83\xec\x20\x48\x8b\xda\x48\x8b\xf9\xe8\x16\xfc\xff\xff\x8b\xf0\x89\x44\x24\x38\x8b\xcb\xf7\xd1\x81\xc9\x7f\x80\xff\xff\x23\xc8\x23\xfb\x0b\xcf\x89\x4c\x24\x30\x80\x3d\x15\xb9\x00\x00\x00\x74\x25\xf6\xc1\x40\x74\x20\xe8\xf9\xfb\xff\xff\xeb\x17\xc6\x05\x00\xb9\x00\x00\x00\x8b\x4c\x24\x30\x83\xe1\xbf\xe8\xe4\xfb\xff\xff\x8b\x74\x24\x38\xeb\x08\x83\xe1\xbf\xe8\xd6\xfb\xff\xff\x8b\xc6\x48\x8b\x5c\x24\x40\x48\x8b\x74\x24\x48\x48\x83\xc4\x20\x5f\xc3\x40\x53\x48\x83\xec\x20\x48\x8b\xd9\xe8\xa6\xfb\xff\xff\x83\xe3\x3f\x0b\xc3\x8b\xc8\x48\x83\xc4\x20\x5b\xe9\xa5\xfb\xff\xff\xcc\x48\x83\xec\x28\xe8\x8b\xfb\xff\xff\x83\xe0\x3f\x48\x83\xc4\x28\xc3\xcc\xff\x25\x04\x10\x00\x00\xff\x25\x46\x10\x00\x00\xff\x25\x20\x0f\x00\x00\x48\x83\xec\x28\x4d\x8b\x41\x38\x48\x8b\xca\x49\x8b\xd1\xe8\x0d\x00\x00\x00\xb8\x01\x00\x00\x00\x48\x83\xc4\x28\xc3\xcc\xcc\xcc\x40\x53\x45\x8b\x18\x48\x8b\xda\x41\x83\xe3\xf8\x4c\x8b\xc9\x41\xf6\x00\x04\x4c\x8b\xd1\x74\x13\x41\x8b\x40\x08\x4d\x63\x50\x04\xf7\xd8\x4c\x03\xd1\x48\x63\xc8\x4c\x23\xd1\x49\x63\xc3\x4a\x8b\x14\x10\x48\x8b\x43\x10\x8b\x48\x08\x48\x03\x4b\x08\xf6\x41\x03\x0f\x74\x0c\x0f\xb6\x41\x03\x83\xe0\xf0\x48\x98\x4c\x03\xc8\x4c\x33\xca\x49\x8b\xc9\x5b\xe9\xd5\x27\xff\xff\xcc\xcc\xcc\xcc\xcc\x4c\x63\x41\x3c\x45\x33\xc9\x4c\x03\xc1\x4c\x8b\xd2\x41\x0f\xb7\x40\x14\x45\x0f\xb7\x58\x06\x48\x83\xc0\x18\x49\x03\xc0\x45\x85\xdb\x74\x1e\x8b\x50\x0c\x4c\x3b\xd2\x72\x0a\x8b\x48\x08\x03\xca\x4c\x3b\xd1\x72\x0e\x41\xff\xc1\x48\x83\xc0\x28\x45\x3b\xcb\x72\xe2\x33\xc0\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xd9\x48\x8d\x3d\x3c\x0e\xff\xff\x48\x8b\xcf\xe8\x34\x00\x00\x00\x85\xc0\x74\x22\x48\x2b\xdf\x48\x8b\xd3\x48\x8b\xcf\xe8\x82\xff\xff\xff\x48\x85\xc0\x74\x0f\x8b\x40\x24\xc1\xe8\x1f\xf7\xd0\x83\xe0\x01\xeb\x02\x33\xc0\x48\x8b\x5c\x24\x30\x48\x83\xc4\x20\x5f\xc3\xcc\xcc\xcc\x48\x8b\xc1\xb9\x4d\x5a\x00\x00\x66\x39\x08\x74\x03\x33\xc0\xc3\x48\x63\x48\x3c\x48\x03\xc8\x33\xc0\x81\x39\x50\x45\x00\x00\x75\x0c\xba\x0b\x02\x00\x00\x66\x39\x51\x18\x0f\x94\xc0\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x83\xec\x10\x4c\x89\x14\x24\x4c\x89\x5c\x24\x08\x4d\x33\xdb\x4c\x8d\x54\x24\x18\x4c\x2b\xd0\x4d\x0f\x42\xd3\x65\x4c\x8b\x1c\x25\x10\x00\x00\x00\x4d\x3b\xd3\xf2\x73\x17\x66\x41\x81\xe2\x00\xf0\x4d\x8d\x9b\x00\xf0\xff\xff\x41\xc6\x03\x00\x4d\x3b\xd3\xf2\x75\xef\x4c\x8b\x14\x24\x4c\x8b\x5c\x24\x08\x48\x83\xc4\x10\xf2\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x4c\x8b\xd9\x4c\x8b\xd2\x49\x83\xf8\x10\x0f\x86\x70\x00\x00\x00\x49\x83\xf8\x20\x76\x4a\x48\x2b\xd1\x73\x0f\x49\x8b\xc2\x49\x03\xc0\x48\x3b\xc8\x0f\x8c\x36\x03\x00\x00\x49\x81\xf8\x80\x00\x00\x00\x0f\x86\x69\x02\x00\x00\x0f\xba\x25\x8d\xbc\x00\x00\x01\x0f\x83\xab\x01\x00\x00\x49\x8b\xc3\x4c\x8b\xdf\x48\x8b\xf9\x49\x8b\xc8\x4c\x8b\xc6\x49\x8b\xf2\xf3\xa4\x49\x8b\xf0\x49\x8b\xfb\xc3\x0f\x10\x02\x41\x0f\x10\x4c\x10\xf0\x0f\x11\x01\x41\x0f\x11\x4c\x08\xf0\x48\x8b\xc1\xc3\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x8b\xc1\x4c\x8d\x0d\xc6\x0c\xff\xff\x43\x8b\x8c\x81\x47\xf3\x00\x00\x49\x03\xc9\xff\xe1\x90\xf3\x00\x00\xaf\xf3\x00\x00\x91\xf3\x00\x00\x9f\xf3\x00\x00\xdb\xf3\x00\x00\xe0\xf3\x00\x00\xf0\xf3\x00\x00\x00\xf4\x00\x00\x98\xf3\x00\x00\x30\xf4\x00\x00\x40\xf4\x00\x00\xc0\xf3\x00\x00\x50\xf4\x00\x00\x18\xf4\x00\x00\x60\xf4\x00\x00\x80\xf4\x00\x00\xb5\xf3\x00\x00\x0f\x1f\x44\x00\x00\xc3\x0f\xb7\x0a\x66\x89\x08\xc3\x48\x8b\x0a\x48\x89\x08\xc3\x0f\xb7\x0a\x44\x0f\xb6\x42\x02\x66\x89\x08\x44\x88\x40\x02\xc3\x0f\xb6\x0a\x88\x08\xc3\xf3\x0f\x6f\x02\xf3\x0f\x7f\x00\xc3\x66\x90\x4c\x8b\x02\x0f\xb7\x4a\x08\x44\x0f\xb6\x4a\x0a\x4c\x89\x00\x66\x89\x48\x08\x44\x88\x48\x0a\x49\x8b\xcb\xc3\x8b\x0a\x89\x08\xc3\x8b\x0a\x44\x0f\xb6\x42\x04\x89\x08\x44\x88\x40\x04\xc3\x66\x90\x8b\x0a\x44\x0f\xb7\x42\x04\x89\x08\x66\x44\x89\x40\x04\xc3\x90\x8b\x0a\x44\x0f\xb7\x42\x04\x44\x0f\xb6\x4a\x06\x89\x08\x66\x44\x89\x40\x04\x44\x88\x48\x06\xc3\x4c\x8b\x02\x8b\x4a\x08\x44\x0f\xb6\x4a\x0c\x4c\x89\x00\x89\x48\x08\x44\x88\x48\x0c\xc3\x66\x90\x4c\x8b\x02\x0f\xb6\x4a\x08\x4c\x89\x00\x88\x48\x08\xc3\x66\x90\x4c\x8b\x02\x0f\xb7\x4a\x08\x4c\x89\x00\x66\x89\x48\x08\xc3\x90\x4c\x8b\x02\x8b\x4a\x08\x4c\x89\x00\x89\x48\x08\xc3\x0f\x1f\x00\x4c\x8b\x02\x8b\x4a\x08\x44\x0f\xb7\x4a\x0c\x4c\x89\x00\x89\x48\x08\x66\x44\x89\x48\x0c\xc3\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x4c\x8b\x02\x8b\x4a\x08\x44\x0f\xb7\x4a\x0c\x44\x0f\xb6\x52\x0e\x4c\x89\x00\x89\x48\x08\x66\x44\x89\x48\x0c\x44\x88\x50\x0e\xc3\x0f\x10\x04\x0a\x4c\x03\xc1\x48\x83\xc1\x10\x41\xf6\xc3\x0f\x74\x13\x0f\x28\xc8\x48\x83\xe1\xf0\x0f\x10\x04\x0a\x48\x83\xc1\x10\x41\x0f\x11\x0b\x4c\x2b\xc1\x4d\x8b\xc8\x49\xc1\xe9\x07\x0f\x84\x88\x00\x00\x00\x0f\x29\x41\xf0\x4c\x3b\x0d\x41\xab\x00\x00\x76\x17\xe9\xc2\x00\x00\x00\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x29\x41\xe0\x0f\x29\x49\xf0\x0f\x10\x04\x0a\x0f\x10\x4c\x0a\x10\x48\x81\xc1\x80\x00\x00\x00\x0f\x29\x41\x80\x0f\x29\x49\x90\x0f\x10\x44\x0a\xa0\x0f\x10\x4c\x0a\xb0\x49\xff\xc9\x0f\x29\x41\xa0\x0f\x29\x49\xb0\x0f\x10\x44\x0a\xc0\x0f\x10\x4c\x0a\xd0\x0f\x29\x41\xc0\x0f\x29\x49\xd0\x0f\x10\x44\x0a\xe0\x0f\x10\x4c\x0a\xf0\x75\xad\x0f\x29\x41\xe0\x49\x83\xe0\x7f\x0f\x28\xc1\xeb\x0c\x0f\x10\x04\x0a\x48\x83\xc1\x10\x49\x83\xe8\x10\x4d\x8b\xc8\x49\xc1\xe9\x04\x74\x1c\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x11\x41\xf0\x0f\x10\x04\x0a\x48\x83\xc1\x10\x49\xff\xc9\x75\xef\x49\x83\xe0\x0f\x74\x0d\x49\x8d\x04\x08\x0f\x10\x4c\x02\xf0\x0f\x11\x48\xf0\x0f\x11\x41\xf0\x49\x8b\xc3\xc3\x0f\x1f\x40\x00\x0f\x2b\x41\xe0\x0f\x2b\x49\xf0\x0f\x18\x84\x0a\x00\x02\x00\x00\x0f\x10\x04\x0a\x0f\x10\x4c\x0a\x10\x48\x81\xc1\x80\x00\x00\x00\x0f\x2b\x41\x80\x0f\x2b\x49\x90\x0f\x10\x44\x0a\xa0\x0f\x10\x4c\x0a\xb0\x49\xff\xc9\x0f\x2b\x41\xa0\x0f\x2b\x49\xb0\x0f\x10\x44\x0a\xc0\x0f\x10\x4c\x0a\xd0\x0f\x18\x84\x0a\x40\x02\x00\x00\x0f\x2b\x41\xc0\x0f\x2b\x49\xd0\x0f\x10\x44\x0a\xe0\x0f\x10\x4c\x0a\xf0\x75\x9d\x0f\xae\xf8\xe9\x38\xff\xff\xff\x0f\x1f\x44\x00\x00\x49\x03\xc8\x0f\x10\x44\x0a\xf0\x48\x83\xe9\x10\x49\x83\xe8\x10\xf6\xc1\x0f\x74\x17\x48\x8b\xc1\x48\x83\xe1\xf0\x0f\x10\xc8\x0f\x10\x04\x0a\x0f\x11\x08\x4c\x8b\xc1\x4d\x2b\xc3\x4d\x8b\xc8\x49\xc1\xe9\x07\x74\x68\x0f\x29\x01\xeb\x0d\x66\x0f\x1f\x44\x00\x00\x0f\x29\x41\x10\x0f\x29\x09\x0f\x10\x44\x0a\xf0\x0f\x10\x4c\x0a\xe0\x48\x81\xe9\x80\x00\x00\x00\x0f\x29\x41\x70\x0f\x29\x49\x60\x0f\x10\x44\x0a\x50\x0f\x10\x4c\x0a\x40\x49\xff\xc9\x0f\x29\x41\x50\x0f\x29\x49\x40\x0f\x10\x44\x0a\x30\x0f\x10\x4c\x0a\x20\x0f\x29\x41\x30\x0f\x29\x49\x20\x0f\x10\x44\x0a\x10\x0f\x10\x0c\x0a\x75\xae\x0f\x29\x41\x10\x49\x83\xe0\x7f\x0f\x28\xc1\x4d\x8b\xc8\x49\xc1\xe9\x04\x74\x1a\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x11\x01\x48\x83\xe9\x10\x0f\x10\x04\x0a\x49\xff\xc9\x75\xf0\x49\x83\xe0\x0f\x74\x08\x41\x0f\x10\x0a\x41\x0f\x11\x0b\x0f\x11\x01\x49\x8b\xc3\xc3\xcc\xcc\xcc\x48\x83\xec\x18\x45\x33\xc0\x4c\x8b\xc9\x85\xd2\x75\x48\x41\x83\xe1\x0f\x48\x8b\xd1\x48\x83\xe2\xf0\x41\x8b\xc9\x41\x83\xc9\xff\x0f\x57\xc9\x41\xd3\xe1\x66\x0f\x6f\x02\x66\x0f\x74\xc1\x66\x0f\xd7\xc0\x41\x23\xc1\x75\x14\x48\x83\xc2\x10\x66\x0f\x6f\x02\x66\x0f\x74\xc1\x66\x0f\xd7\xc0\x85\xc0\x74\xec\x0f\xbc\xc0\x48\x03\xc2\xe9\xa6\x00\x00\x00\x83\x3d\xd3\xa8\x00\x00\x02\x0f\x8d\x9e\x00\x00\x00\x4c\x8b\xd1\x0f\xb6\xc2\x41\x83\xe1\x0f\x49\x83\xe2\xf0\x8b\xc8\x0f\x57\xd2\xc1\xe1\x08\x0b\xc8\x66\x0f\x6e\xc1\x41\x8b\xc9\xf2\x0f\x70\xc8\x00\x41\x83\xc9\xff\x41\xd3\xe1\x66\x0f\x6f\xc2\x66\x41\x0f\x74\x02\x66\x0f\xd7\xc8\x66\x0f\x70\xd9\x00\x66\x0f\x6f\xc3\x66\x41\x0f\x74\x02\x66\x0f\xd7\xd0\x41\x23\xd1\x41\x23\xc9\x75\x2e\x0f\xbd\xca\x66\x0f\x6f\xca\x66\x0f\x6f\xc3\x49\x03\xca\x85\xd2\x4c\x0f\x45\xc1\x49\x83\xc2\x10\x66\x41\x0f\x74\x0a\x66\x41\x0f\x74\x02\x66\x0f\xd7\xc9\x66\x0f\xd7\xd0\x85\xc9\x74\xd2\x8b\xc1\xf7\xd8\x23\xc1\xff\xc8\x23\xd0\x0f\xbd\xca\x49\x03\xca\x85\xd2\x4c\x0f\x45\xc1\x49\x8b\xc0\x48\x83\xc4\x18\xc3\xf6\xc1\x0f\x74\x19\x41\x0f\xbe\x01\x3b\xc2\x4d\x0f\x44\xc1\x41\x80\x39\x00\x74\xe3\x49\xff\xc1\x41\xf6\xc1\x0f\x75\xe7\x0f\xb6\xc2\x66\x0f\x6e\xc0\x66\x41\x0f\x3a\x63\x01\x40\x73\x0d\x4c\x63\xc1\x4d\x03\xc1\x66\x41\x0f\x3a\x63\x01\x40\x74\xbb\x49\x83\xc1\x10\xeb\xe2\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x48\x2b\xd1\x49\x83\xf8\x08\x72\x22\xf6\xc1\x07\x74\x14\x66\x90\x8a\x01\x3a\x04\x0a\x75\x2c\x48\xff\xc1\x49\xff\xc8\xf6\xc1\x07\x75\xee\x4d\x8b\xc8\x49\xc1\xe9\x03\x75\x1f\x4d\x85\xc0\x74\x0f\x8a\x01\x3a\x04\x0a\x75\x0c\x48\xff\xc1\x49\xff\xc8\x75\xf1\x48\x33\xc0\xc3\x1b\xc0\x83\xd8\xff\xc3\x90\x49\xc1\xe9\x02\x74\x37\x48\x8b\x01\x48\x3b\x04\x0a\x75\x5b\x48\x8b\x41\x08\x48\x3b\x44\x0a\x08\x75\x4c\x48\x8b\x41\x10\x48\x3b\x44\x0a\x10\x75\x3d\x48\x8b\x41\x18\x48\x3b\x44\x0a\x18\x75\x2e\x48\x83\xc1\x20\x49\xff\xc9\x75\xcd\x49\x83\xe0\x1f\x4d\x8b\xc8\x49\xc1\xe9\x03\x74\x9b\x48\x8b\x01\x48\x3b\x04\x0a\x75\x1b\x48\x83\xc1\x08\x49\xff\xc9\x75\xee\x49\x83\xe0\x07\xeb\x83\x48\x83\xc1\x08\x48\x83\xc1\x08\x48\x83\xc1\x08\x48\x8b\x0c\x11\x48\x0f\xc8\x48\x0f\xc9\x48\x3b\xc1\x1b\xc0\x83\xd8\xff\xc3\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\xff\xe0\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x8a\x4d\x40\x48\x83\xc4\x20\x5d\xe9\x36\x28\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\xe8\x5f\x26\xff\xff\x8a\x4d\x38\x48\x83\xc4\x20\x5d\xe9\x1a\x28\xff\xff\xcc\x40\x55\x48\x83\xec\x30\x48\x8b\xea\x48\x8b\x01\x8b\x10\x48\x89\x4c\x24\x28\x89\x54\x24\x20\x4c\x8d\x0d\xd3\x1f\xff\xff\x4c\x8b\x45\x70\x8b\x55\x68\x48\x8b\x4d\x60\xe8\x8f\x25\xff\xff\x90\x48\x83\xc4\x30\x5d\xc3\xcc\x40\x55\x48\x8b\xea\x48\x8b\x01\x33\xc9\x81\x38\x05\x00\x00\xc0\x0f\x94\xc1\x8b\xc1\x5d\xc3\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x4d\x48\x48\x8b\x09\x48\x83\xc4\x20\x5d\xe9\x35\x3e\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x01\x8b\x08\xe8\x91\x57\xff\xff\x90\x48\x83\xc4\x20\x5d\xc3\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\xb9\x02\x00\x00\x00\x48\x83\xc4\x20\x5d\xe9\xb5\x92\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x85\x88\x00\x00\x00\x8b\x08\x48\x83\xc4\x20\x5d\xe9\x98\x92\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\xb9\x08\x00\x00\x00\x48\x83\xc4\x20\x5d\xe9\x7f\x92\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x4d\x68\xe8\xb8\x3d\xff\xff\x90\x48\x83\xc4\x20\x5d\xc3\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\xb9\x08\x00\x00\x00\x48\x83\xc4\x20\x5d\xe9\x4c\x92\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\xb9\x07\x00\x00\x00\x48\x83\xc4\x20\x5d\xe9\x33\x92\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x45\x48\x8b\x08\x48\x83\xc4\x20\x5d\xe9\x19\x92\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\xb9\x04\x00\x00\x00\x48\x83\xc4\x20\x5d\xe9\x00\x92\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\xb9\x05\x00\x00\x00\x48\x83\xc4\x20\x5d\xe9\xe7\x91\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x33\xc9\x48\x83\xc4\x20\x5d\xe9\xd1\x91\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x80\xbd\x80\x00\x00\x00\x00\x74\x0b\xb9\x03\x00\x00\x00\xe8\xb4\x91\xff\xff\x90\x48\x83\xc4\x20\x5d\xc3\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x4d\x30\x48\x83\xc4\x20\x5d\xe9\xe1\x3c\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x8b\x4d\x50\x48\x83\xc4\x20\x5d\xe9\xa6\xb2\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x45\x48\x8b\x08\x48\x83\xc4\x20\x5d\xe9\x8c\xb2\xff\xff\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x01\x81\x38\x05\x00\x00\xc0\x74\x0c\x81\x38\x1d\x00\x00\xc0\x74\x04\x33\xc0\xeb\x05\xb8\x01\x00\x00\x00\x48\x83\xc4\x20\x5d\xc3\xcc\xcc\xcc\xcc\x40\x55\x48\x83\xec\x20\x48\x8b\xea\x48\x8b\x01\x33\xc9\x81\x38\x05\x00\x00\xc0\x0f\x94\xc1\x8b\xc1\x48\x83\xc4\x20\x5d\xc3\xcc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x9a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\x93\x01\x00\x00\x00\x00\x00\xd0\x93\x01\x00\x00\x00\x00\x00\x0a\x9a\x01\x00\x00\x00\x00\x00\xfc\x99\x01\x00\x00\x00\x00\x00\xec\x99\x01\x00\x00\x00\x00\x00\xd8\x99\x01\x00\x00\x00\x00\x00\xca\x99\x01\x00\x00\x00\x00\x00\xbc\x99\x01\x00\x00\x00\x00\x00\xb0\x99\x01\x00\x00\x00\x00\x00\xa0\x99\x01\x00\x00\x00\x00\x00\x8e\x99\x01\x00\x00\x00\x00\x00\x7e\x99\x01\x00\x00\x00\x00\x00\x72\x99\x01\x00\x00\x00\x00\x00\x5e\x99\x01\x00\x00\x00\x00\x00\x4c\x99\x01\x00\x00\x00\x00\x00\x3a\x99\x01\x00\x00\x00\x00\x00\x28\x99\x01\x00\x00\x00\x00\x00\x16\x99\x01\x00\x00\x00\x00\x00\x9c\x95\x01\x00\x00\x00\x00\x00\xb0\x95\x01\x00\x00\x00\x00\x00\xca\x95\x01\x00\x00\x00\x00\x00\xde\x95\x01\x00\x00\x00\x00\x00\xfa\x95\x01\x00\x00\x00\x00\x00\x18\x96\x01\x00\x00\x00\x00\x00\x2c\x96\x01\x00\x00\x00\x00\x00\x40\x96\x01\x00\x00\x00\x00\x00\x5c\x96\x01\x00\x00\x00\x00\x00\x76\x96\x01\x00\x00\x00\x00\x00\x8c\x96\x01\x00\x00\x00\x00\x00\xa2\x96\x01\x00\x00\x00\x00\x00\xbc\x96\x01\x00\x00\x00\x00\x00\xd2\x96\x01\x00\x00\x00\x00\x00\xe6\x96\x01\x00\x00\x00\x00\x00\xf8\x96\x01\x00\x00\x00\x00\x00\x0e\x97\x01\x00\x00\x00\x00\x00\x1c\x97\x01\x00\x00\x00\x00\x00\x34\x97\x01\x00\x00\x00\x00\x00\x5c\x97\x01\x00\x00\x00\x00\x00\x68\x97\x01\x00\x00\x00\x00\x00\x76\x97\x01\x00\x00\x00\x00\x00\x84\x97\x01\x00\x00\x00\x00\x00\x8e\x97\x01\x00\x00\x00\x00\x00\x9c\x97\x01\x00\x00\x00\x00\x00\xae\x97\x01\x00\x00\x00\x00\x00\xc0\x97\x01\x00\x00\x00\x00\x00\xd0\x97\x01\x00\x00\x00\x00\x00\xe8\x97\x01\x00\x00\x00\x00\x00\x00\x98\x01\x00\x00\x00\x00\x00\x18\x98\x01\x00\x00\x00\x00\x00\x26\x98\x01\x00\x00\x00\x00\x00\x3c\x98\x01\x00\x00\x00\x00\x00\x52\x98\x01\x00\x00\x00\x00\x00\x68\x98\x01\x00\x00\x00\x00\x00\x74\x98\x01\x00\x00\x00\x00\x00\x80\x98\x01\x00\x00\x00\x00\x00\x90\x98\x01\x00\x00\x00\x00\x00\xa0\x98\x01\x00\x00\x00\x00\x00\xae\x98\x01\x00\x00\x00\x00\x00\xb8\x98\x01\x00\x00\x00\x00\x00\xca\x98\x01\x00\x00\x00\x00\x00\xd6\x98\x01\x00\x00\x00\x00\x00\xe2\x98\x01\x00\x00\x00\x00\x00\xfc\x98\x01\x00\x00\x00\x00\x00\xc0\x93\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x95\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x95\x01\x00\x00\x00\x00\x00\x4a\x95\x01\x00\x00\x00\x00\x00\x36\x95\x01\x00\x00\x00\x00\x00\x28\x95\x01\x00\x00\x00\x00\x00\x14\x95\x01\x00\x00\x00\x00\x00\x00\x95\x01\x00\x00\x00\x00\x00\xf2\x94\x01\x00\x00\x00\x00\x00\xe4\x94\x01\x00\x00\x00\x00\x00\xd2\x94\x01\x00\x00\x00\x00\x00\xb4\x94\x01\x00\x00\x00\x00\x00\xa2\x94\x01\x00\x00\x00\x00\x00\x8e\x94\x01\x00\x00\x00\x00\x00\x80\x94\x01\x00\x00\x00\x00\x00\x74\x94\x01\x00\x00\x00\x00\x00\x62\x94\x01\x00\x00\x00\x00\x00\x50\x94\x01\x00\x00\x00\x00\x00\x3c\x94\x01\x00\x00\x00\x00\x00\x2a\x94\x01\x00\x00\x00\x00\x00\x14\x94\x01\x00\x00\x00\x00\x00\x04\x94\x01\x00\x00\x00\x00\x00\xc2\x94\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x26\x00\x80\x01\x00\x00\x00\x20\xf9\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x36\x00\x80\x01\x00\x00\x00\xdc\xd7\x00\x80\x01\x00\x00\x00\x10\xeb\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x8b\x00\x80\x01\x00\x00\x00\xbc\xe4\x00\x80\x01\x00\x00\x00\x98\x37\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\xa9\x01\x80\x01\x00\x00\x00\x40\xaa\x01\x80\x01\x00\x00\x00\x30\xa0\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4d\x61\x69\x6e\x20\x49\x6e\x76\x6f\x6b\x65\x64\x2e\x00\x00\x00\x4d\x61\x69\x6e\x20\x52\x65\x74\x75\x72\x6e\x65\x64\x2e\x00\x00\xc8\x03\x01\x80\x01\x00\x00\x00\xe0\x03\x01\x80\x01\x00\x00\x00\x20\x04\x01\x80\x01\x00\x00\x00\x60\x04\x01\x80\x01\x00\x00\x00\x61\x00\x64\x00\x76\x00\x61\x00\x70\x00\x69\x00\x33\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x66\x00\x69\x00\x62\x00\x65\x00\x72\x00\x73\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x31\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x73\x00\x79\x00\x6e\x00\x63\x00\x68\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x32\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x65\x00\x72\x00\x6e\x00\x65\x00\x6c\x00\x33\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x45\x76\x65\x6e\x74\x52\x65\x67\x69\x73\x74\x65\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x45\x76\x65\x6e\x74\x53\x65\x74\x49\x6e\x66\x6f\x72\x6d\x61\x74\x69\x6f\x6e\x00\x00\x00\x00\x00\x45\x76\x65\x6e\x74\x55\x6e\x72\x65\x67\x69\x73\x74\x65\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x45\x76\x65\x6e\x74\x57\x72\x69\x74\x65\x54\x72\x61\x6e\x73\x66\x65\x72\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x46\x6c\x73\x41\x6c\x6c\x6f\x63\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x46\x6c\x73\x46\x72\x65\x65\x00\x01\x00\x00\x00\x03\x00\x00\x00\x46\x6c\x73\x47\x65\x74\x56\x61\x6c\x75\x65\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x46\x6c\x73\x53\x65\x74\x56\x61\x6c\x75\x65\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x49\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x45\x78\x00\x2d\x00\x00\x00\x2b\x00\x00\x00\x26\x00\x00\x00\x2d\x3e\x2a\x00\x2f\x00\x00\x00\x25\x00\x00\x00\x3c\x00\x00\x00\x3c\x3d\x00\x00\x3e\x00\x00\x00\x3e\x3d\x00\x00\x2c\x00\x00\x00\x28\x29\x00\x00\x7e\x00\x00\x00\x5e\x00\x00\x00\x7c\x00\x00\x00\x26\x26\x00\x00\x7c\x7c\x00\x00\x2a\x3d\x00\x00\x2b\x3d\x00\x00\x2d\x3d\x00\x00\x2f\x3d\x00\x00\x25\x3d\x00\x00\x3e\x3e\x3d\x00\x3c\x3c\x3d\x00\x26\x3d\x00\x00\x7c\x3d\x00\x00\x5e\x3d\x00\x00\x60\x76\x66\x74\x61\x62\x6c\x65\x27\x00\x00\x00\x00\x00\x00\x00\x60\x76\x62\x74\x61\x62\x6c\x65\x27\x00\x00\x00\x00\x00\x00\x00\x60\x76\x63\x61\x6c\x6c\x27\x00\x60\x74\x79\x70\x65\x6f\x66\x27\x00\x00\x00\x00\x00\x00\x00\x00\x60\x6c\x6f\x63\x61\x6c\x20\x73\x74\x61\x74\x69\x63\x20\x67\x75\x61\x72\x64\x27\x00\x00\x00\x00\x60\x73\x74\x72\x69\x6e\x67\x27\x00\x00\x00\x00\x00\x00\x00\x00\x60\x76\x62\x61\x73\x65\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x64\x65\x6c\x65\x74\x69\x6e\x67\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x64\x65\x66\x61\x75\x6c\x74\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x00\x00\x60\x73\x63\x61\x6c\x61\x72\x20\x64\x65\x6c\x65\x74\x69\x6e\x67\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x76\x62\x61\x73\x65\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x60\x76\x69\x72\x74\x75\x61\x6c\x20\x64\x69\x73\x70\x6c\x61\x63\x65\x6d\x65\x6e\x74\x20\x6d\x61\x70\x27\x00\x00\x00\x00\x00\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x00\x00\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x76\x62\x61\x73\x65\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x60\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x00\x00\x00\x00\x00\x60\x75\x64\x74\x20\x72\x65\x74\x75\x72\x6e\x69\x6e\x67\x27\x00\x60\x45\x48\x00\x60\x52\x54\x54\x49\x00\x00\x00\x00\x00\x00\x00\x60\x6c\x6f\x63\x61\x6c\x20\x76\x66\x74\x61\x62\x6c\x65\x27\x00\x60\x6c\x6f\x63\x61\x6c\x20\x76\x66\x74\x61\x62\x6c\x65\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x20\x6e\x65\x77\x5b\x5d\x00\x00\x00\x00\x00\x00\x20\x64\x65\x6c\x65\x74\x65\x5b\x5d\x00\x00\x00\x00\x00\x00\x00\x60\x6f\x6d\x6e\x69\x20\x63\x61\x6c\x6c\x73\x69\x67\x27\x00\x00\x60\x70\x6c\x61\x63\x65\x6d\x65\x6e\x74\x20\x64\x65\x6c\x65\x74\x65\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x00\x00\x00\x00\x00\x60\x70\x6c\x61\x63\x65\x6d\x65\x6e\x74\x20\x64\x65\x6c\x65\x74\x65\x5b\x5d\x20\x63\x6c\x6f\x73\x75\x72\x65\x27\x00\x00\x00\x00\x60\x6d\x61\x6e\x61\x67\x65\x64\x20\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x60\x6d\x61\x6e\x61\x67\x65\x64\x20\x76\x65\x63\x74\x6f\x72\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x60\x65\x68\x20\x76\x65\x63\x74\x6f\x72\x20\x76\x62\x61\x73\x65\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x60\x64\x79\x6e\x61\x6d\x69\x63\x20\x69\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x72\x20\x66\x6f\x72\x20\x27\x00\x00\x00\x00\x00\x00\x60\x64\x79\x6e\x61\x6d\x69\x63\x20\x61\x74\x65\x78\x69\x74\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x66\x6f\x72\x20\x27\x00\x00\x00\x00\x00\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x00\x60\x76\x65\x63\x74\x6f\x72\x20\x76\x62\x61\x73\x65\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x00\x00\x00\x60\x6d\x61\x6e\x61\x67\x65\x64\x20\x76\x65\x63\x74\x6f\x72\x20\x63\x6f\x70\x79\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x20\x69\x74\x65\x72\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x00\x60\x6c\x6f\x63\x61\x6c\x20\x73\x74\x61\x74\x69\x63\x20\x74\x68\x72\x65\x61\x64\x20\x67\x75\x61\x72\x64\x27\x00\x00\x00\x00\x00\x6f\x70\x65\x72\x61\x74\x6f\x72\x20\x22\x22\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x0d\x01\x80\x01\x00\x00\x00\x60\x0d\x01\x80\x01\x00\x00\x00\x80\x0d\x01\x80\x01\x00\x00\x00\x98\x0d\x01\x80\x01\x00\x00\x00\xb8\x0d\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x0d\x01\x80\x01\x00\x00\x00\xe8\x0d\x01\x80\x01\x00\x00\x00\xf0\x0d\x01\x80\x01\x00\x00\x00\x00\x0e\x01\x80\x01\x00\x00\x00\x10\x0e\x01\x80\x01\x00\x00\x00\x20\x0e\x01\x80\x01\x00\x00\x00\x30\x0e\x01\x80\x01\x00\x00\x00\x40\x0e\x01\x80\x01\x00\x00\x00\x4c\x0e\x01\x80\x01\x00\x00\x00\x58\x0e\x01\x80\x01\x00\x00\x00\x60\x0e\x01\x80\x01\x00\x00\x00\x70\x0e\x01\x80\x01\x00\x00\x00\x80\x0e\x01\x80\x01\x00\x00\x00\x80\x03\x01\x80\x01\x00\x00\x00\x8c\x0e\x01\x80\x01\x00\x00\x00\x98\x0e\x01\x80\x01\x00\x00\x00\xa0\x0e\x01\x80\x01\x00\x00\x00\xa4\x0e\x01\x80\x01\x00\x00\x00\xa8\x0e\x01\x80\x01\x00\x00\x00\xac\x0e\x01\x80\x01\x00\x00\x00\xb0\x0e\x01\x80\x01\x00\x00\x00\xb4\x0e\x01\x80\x01\x00\x00\x00\xb8\x0e\x01\x80\x01\x00\x00\x00\xc0\x0e\x01\x80\x01\x00\x00\x00\xcc\x0e\x01\x80\x01\x00\x00\x00\xd0\x0e\x01\x80\x01\x00\x00\x00\xd4\x0e\x01\x80\x01\x00\x00\x00\xd8\x0e\x01\x80\x01\x00\x00\x00\x54\x05\x01\x80\x01\x00\x00\x00\x58\x05\x01\x80\x01\x00\x00\x00\x5c\x05\x01\x80\x01\x00\x00\x00\x60\x05\x01\x80\x01\x00\x00\x00\x64\x05\x01\x80\x01\x00\x00\x00\x68\x05\x01\x80\x01\x00\x00\x00\x6c\x05\x01\x80\x01\x00\x00\x00\x70\x05\x01\x80\x01\x00\x00\x00\x74\x05\x01\x80\x01\x00\x00\x00\x78\x05\x01\x80\x01\x00\x00\x00\x7c\x05\x01\x80\x01\x00\x00\x00\x80\x05\x01\x80\x01\x00\x00\x00\x84\x05\x01\x80\x01\x00\x00\x00\x88\x05\x01\x80\x01\x00\x00\x00\x8c\x05\x01\x80\x01\x00\x00\x00\x90\x05\x01\x80\x01\x00\x00\x00\x94\x05\x01\x80\x01\x00\x00\x00\x98\x05\x01\x80\x01\x00\x00\x00\x9c\x05\x01\x80\x01\x00\x00\x00\xa0\x05\x01\x80\x01\x00\x00\x00\xa4\x05\x01\x80\x01\x00\x00\x00\xa8\x05\x01\x80\x01\x00\x00\x00\xac\x05\x01\x80\x01\x00\x00\x00\xb0\x05\x01\x80\x01\x00\x00\x00\xb4\x05\x01\x80\x01\x00\x00\x00\xb8\x05\x01\x80\x01\x00\x00\x00\xbc\x05\x01\x80\x01\x00\x00\x00\xc0\x05\x01\x80\x01\x00\x00\x00\xd0\x05\x01\x80\x01\x00\x00\x00\xe0\x05\x01\x80\x01\x00\x00\x00\xe8\x05\x01\x80\x01\x00\x00\x00\xf8\x05\x01\x80\x01\x00\x00\x00\x10\x06\x01\x80\x01\x00\x00\x00\x20\x06\x01\x80\x01\x00\x00\x00\x38\x06\x01\x80\x01\x00\x00\x00\x58\x06\x01\x80\x01\x00\x00\x00\x78\x06\x01\x80\x01\x00\x00\x00\x98\x06\x01\x80\x01\x00\x00\x00\xb8\x06\x01\x80\x01\x00\x00\x00\xd8\x06\x01\x80\x01\x00\x00\x00\x00\x07\x01\x80\x01\x00\x00\x00\x20\x07\x01\x80\x01\x00\x00\x00\x48\x07\x01\x80\x01\x00\x00\x00\x68\x07\x01\x80\x01\x00\x00\x00\x90\x07\x01\x80\x01\x00\x00\x00\xb0\x07\x01\x80\x01\x00\x00\x00\xc0\x07\x01\x80\x01\x00\x00\x00\xc4\x07\x01\x80\x01\x00\x00\x00\xd0\x07\x01\x80\x01\x00\x00\x00\xe0\x07\x01\x80\x01\x00\x00\x00\x04\x08\x01\x80\x01\x00\x00\x00\x10\x08\x01\x80\x01\x00\x00\x00\x20\x08\x01\x80\x01\x00\x00\x00\x30\x08\x01\x80\x01\x00\x00\x00\x50\x08\x01\x80\x01\x00\x00\x00\x70\x08\x01\x80\x01\x00\x00\x00\x98\x08\x01\x80\x01\x00\x00\x00\xc0\x08\x01\x80\x01\x00\x00\x00\xe8\x08\x01\x80\x01\x00\x00\x00\x18\x09\x01\x80\x01\x00\x00\x00\x38\x09\x01\x80\x01\x00\x00\x00\x60\x09\x01\x80\x01\x00\x00\x00\x88\x09\x01\x80\x01\x00\x00\x00\xb8\x09\x01\x80\x01\x00\x00\x00\xe8\x09\x01\x80\x01\x00\x00\x00\x08\x0a\x01\x80\x01\x00\x00\x00\x80\x03\x01\x80\x01\x00\x00\x00\x20\x54\x79\x70\x65\x20\x44\x65\x73\x63\x72\x69\x70\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x00\x00\x20\x42\x61\x73\x65\x20\x43\x6c\x61\x73\x73\x20\x44\x65\x73\x63\x72\x69\x70\x74\x6f\x72\x20\x61\x74\x20\x28\x00\x00\x00\x00\x00\x20\x42\x61\x73\x65\x20\x43\x6c\x61\x73\x73\x20\x41\x72\x72\x61\x79\x27\x00\x00\x00\x00\x00\x00\x20\x43\x6c\x61\x73\x73\x20\x48\x69\x65\x72\x61\x72\x63\x68\x79\x20\x44\x65\x73\x63\x72\x69\x70\x74\x6f\x72\x27\x00\x00\x00\x00\x20\x43\x6f\x6d\x70\x6c\x65\x74\x65\x20\x4f\x62\x6a\x65\x63\x74\x20\x4c\x6f\x63\x61\x74\x6f\x72\x27\x00\x00\x00\x00\x00\x00\x00\x5f\x5f\x62\x61\x73\x65\x64\x28\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x5f\x63\x64\x65\x63\x6c\x00\x5f\x5f\x70\x61\x73\x63\x61\x6c\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x5f\x73\x74\x64\x63\x61\x6c\x6c\x00\x00\x00\x00\x00\x00\x00\x5f\x5f\x74\x68\x69\x73\x63\x61\x6c\x6c\x00\x00\x00\x00\x00\x00\x5f\x5f\x66\x61\x73\x74\x63\x61\x6c\x6c\x00\x00\x00\x00\x00\x00\x5f\x5f\x76\x65\x63\x74\x6f\x72\x63\x61\x6c\x6c\x00\x00\x00\x00\x5f\x5f\x63\x6c\x72\x63\x61\x6c\x6c\x00\x00\x00\x5f\x5f\x65\x61\x62\x69\x00\x00\x00\x00\x00\x00\x5f\x5f\x70\x74\x72\x36\x34\x00\x5f\x5f\x72\x65\x73\x74\x72\x69\x63\x74\x00\x00\x00\x00\x00\x00\x5f\x5f\x75\x6e\x61\x6c\x69\x67\x6e\x65\x64\x00\x00\x00\x00\x00\x72\x65\x73\x74\x72\x69\x63\x74\x28\x00\x00\x00\x20\x6e\x65\x77\x00\x00\x00\x00\x00\x00\x00\x00\x20\x64\x65\x6c\x65\x74\x65\x00\x3d\x00\x00\x00\x3e\x3e\x00\x00\x3c\x3c\x00\x00\x21\x00\x00\x00\x3d\x3d\x00\x00\x21\x3d\x00\x00\x5b\x5d\x00\x00\x00\x00\x00\x00\x6f\x70\x65\x72\x61\x74\x6f\x72\x00\x00\x00\x00\x2d\x3e\x00\x00\x2a\x00\x00\x00\x2b\x2b\x00\x00\x2d\x2d\x00\x00\x00\x00\x00\x00\x06\x00\x00\x06\x00\x01\x00\x00\x10\x00\x03\x06\x00\x06\x02\x10\x04\x45\x45\x45\x05\x05\x05\x05\x05\x35\x30\x00\x50\x00\x00\x00\x00\x28\x20\x38\x50\x58\x07\x08\x00\x37\x30\x30\x57\x50\x07\x00\x00\x20\x20\x08\x07\x00\x00\x00\x08\x60\x68\x60\x60\x60\x60\x00\x00\x78\x70\x78\x78\x78\x78\x08\x07\x08\x07\x00\x07\x00\x08\x08\x08\x00\x00\x08\x07\x08\x00\x07\x08\x00\x07\x00\x28\x6e\x75\x6c\x6c\x29\x00\x00\x00\x00\x00\x00\x28\x00\x6e\x00\x75\x00\x6c\x00\x6c\x00\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\xc0\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\xc0\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\x00\x00\xc0\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x00\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x02\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\x02\x00\xc0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x73\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x65\x00\x2e\x00\x64\x00\x6c\x00\x6c\x00\x00\x00\x43\x6f\x72\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x00\x7c\x5a\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\x5a\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x74\x69\x00\x80\x01\x00\x00\x00\x34\x6a\x00\x80\x01\x00\x00\x00\xb0\x5b\x00\x80\x01\x00\x00\x00\xb0\x5b\x00\x80\x01\x00\x00\x00\x18\x8c\x00\x80\x01\x00\x00\x00\x7c\x8c\x00\x80\x01\x00\x00\x00\x00\x99\x00\x80\x01\x00\x00\x00\x1c\x99\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x5b\x00\x80\x01\x00\x00\x00\x1c\x7d\x00\x80\x01\x00\x00\x00\x58\x7d\x00\x80\x01\x00\x00\x00\x08\x6f\x00\x80\x01\x00\x00\x00\x44\x6f\x00\x80\x01\x00\x00\x00\x28\x99\x00\x80\x01\x00\x00\x00\xb0\x5b\x00\x80\x01\x00\x00\x00\xcc\x93\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x5b\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x5b\x00\x80\x01\x00\x00\x00\xb0\x5b\x00\x80\x01\x00\x00\x00\xb4\x5a\x00\x80\x01\x00\x00\x00\x90\x5a\x00\x80\x01\x00\x00\x00\xb0\x5b\x00\x80\x01\x00\x00\x00\x01\x00\x00\x00\x16\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x18\x00\x00\x00\x05\x00\x00\x00\x0d\x00\x00\x00\x06\x00\x00\x00\x09\x00\x00\x00\x07\x00\x00\x00\x0c\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x09\x00\x00\x00\x0c\x00\x00\x00\x0a\x00\x00\x00\x07\x00\x00\x00\x0b\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x16\x00\x00\x00\x0d\x00\x00\x00\x16\x00\x00\x00\x0f\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x0d\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x21\x00\x00\x00\x0d\x00\x00\x00\x35\x00\x00\x00\x02\x00\x00\x00\x41\x00\x00\x00\x0d\x00\x00\x00\x43\x00\x00\x00\x02\x00\x00\x00\x50\x00\x00\x00\x11\x00\x00\x00\x52\x00\x00\x00\x0d\x00\x00\x00\x53\x00\x00\x00\x0d\x00\x00\x00\x57\x00\x00\x00\x16\x00\x00\x00\x59\x00\x00\x00\x0b\x00\x00\x00\x6c\x00\x00\x00\x0d\x00\x00\x00\x6d\x00\x00\x00\x20\x00\x00\x00\x70\x00\x00\x00\x1c\x00\x00\x00\x72\x00\x00\x00\x09\x00\x00\x00\x06\x00\x00\x00\x16\x00\x00\x00\x80\x00\x00\x00\x0a\x00\x00\x00\x81\x00\x00\x00\x0a\x00\x00\x00\x82\x00\x00\x00\x09\x00\x00\x00\x83\x00\x00\x00\x16\x00\x00\x00\x84\x00\x00\x00\x0d\x00\x00\x00\x91\x00\x00\x00\x29\x00\x00\x00\x9e\x00\x00\x00\x0d\x00\x00\x00\xa1\x00\x00\x00\x02\x00\x00\x00\xa4\x00\x00\x00\x0b\x00\x00\x00\xa7\x00\x00\x00\x0d\x00\x00\x00\xb7\x00\x00\x00\x11\x00\x00\x00\xce\x00\x00\x00\x02\x00\x00\x00\xd7\x00\x00\x00\x0b\x00\x00\x00\x18\x07\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x13\x01\x80\x01\x00\x00\x00\xb0\x13\x01\x80\x01\x00\x00\x00\xe0\x03\x01\x80\x01\x00\x00\x00\xf0\x13\x01\x80\x01\x00\x00\x00\x30\x14\x01\x80\x01\x00\x00\x00\x80\x14\x01\x80\x01\x00\x00\x00\xe0\x14\x01\x80\x01\x00\x00\x00\x30\x15\x01\x80\x01\x00\x00\x00\x20\x04\x01\x80\x01\x00\x00\x00\x70\x15\x01\x80\x01\x00\x00\x00\xb0\x15\x01\x80\x01\x00\x00\x00\xf0\x15\x01\x80\x01\x00\x00\x00\x30\x16\x01\x80\x01\x00\x00\x00\x80\x16\x01\x80\x01\x00\x00\x00\xe0\x16\x01\x80\x01\x00\x00\x00\x40\x17\x01\x80\x01\x00\x00\x00\x90\x17\x01\x80\x01\x00\x00\x00\xc8\x03\x01\x80\x01\x00\x00\x00\x60\x04\x01\x80\x01\x00\x00\x00\xe0\x17\x01\x80\x01\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x61\x00\x70\x00\x70\x00\x6d\x00\x6f\x00\x64\x00\x65\x00\x6c\x00\x2d\x00\x72\x00\x75\x00\x6e\x00\x74\x00\x69\x00\x6d\x00\x65\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x64\x00\x61\x00\x74\x00\x65\x00\x74\x00\x69\x00\x6d\x00\x65\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x31\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x66\x00\x69\x00\x6c\x00\x65\x00\x2d\x00\x6c\x00\x32\x00\x2d\x00\x31\x00\x2d\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x69\x00\x7a\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x32\x00\x2d\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x69\x00\x7a\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x62\x00\x73\x00\x6f\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x32\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x70\x00\x72\x00\x6f\x00\x63\x00\x65\x00\x73\x00\x73\x00\x74\x00\x68\x00\x72\x00\x65\x00\x61\x00\x64\x00\x73\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x32\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x73\x00\x74\x00\x72\x00\x69\x00\x6e\x00\x67\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x73\x00\x79\x00\x73\x00\x69\x00\x6e\x00\x66\x00\x6f\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x32\x00\x2d\x00\x31\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x72\x00\x74\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x78\x00\x73\x00\x74\x00\x61\x00\x74\x00\x65\x00\x2d\x00\x6c\x00\x32\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x72\x00\x74\x00\x63\x00\x6f\x00\x72\x00\x65\x00\x2d\x00\x6e\x00\x74\x00\x75\x00\x73\x00\x65\x00\x72\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x61\x00\x70\x00\x69\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x73\x00\x65\x00\x63\x00\x75\x00\x72\x00\x69\x00\x74\x00\x79\x00\x2d\x00\x73\x00\x79\x00\x73\x00\x74\x00\x65\x00\x6d\x00\x66\x00\x75\x00\x6e\x00\x63\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x00\x78\x00\x74\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x6b\x00\x65\x00\x72\x00\x6e\x00\x65\x00\x6c\x00\x33\x00\x32\x00\x2d\x00\x70\x00\x61\x00\x63\x00\x6b\x00\x61\x00\x67\x00\x65\x00\x2d\x00\x63\x00\x75\x00\x72\x00\x72\x00\x65\x00\x6e\x00\x74\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x00\x78\x00\x74\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x6e\x00\x74\x00\x75\x00\x73\x00\x65\x00\x72\x00\x2d\x00\x64\x00\x69\x00\x61\x00\x6c\x00\x6f\x00\x67\x00\x62\x00\x6f\x00\x78\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x00\x78\x00\x74\x00\x2d\x00\x6d\x00\x73\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x2d\x00\x6e\x00\x74\x00\x75\x00\x73\x00\x65\x00\x72\x00\x2d\x00\x77\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x74\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2d\x00\x6c\x00\x31\x00\x2d\x00\x31\x00\x2d\x00\x30\x00\x00\x00\x00\x00\x75\x00\x73\x00\x65\x00\x72\x00\x33\x00\x32\x00\x00\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x47\x65\x74\x43\x75\x72\x72\x65\x6e\x74\x50\x61\x63\x6b\x61\x67\x65\x49\x64\x00\x00\x00\x00\x00\x08\x00\x00\x00\x12\x00\x00\x00\x04\x00\x00\x00\x12\x00\x00\x00\x4c\x43\x4d\x61\x70\x53\x74\x72\x69\x6e\x67\x45\x78\x00\x00\x00\x04\x00\x00\x00\x12\x00\x00\x00\x4c\x6f\x63\x61\x6c\x65\x4e\x61\x6d\x65\x54\x6f\x4c\x43\x49\x44\x00\x00\x00\x00\x49\x4e\x46\x00\x69\x6e\x66\x00\x4e\x41\x4e\x00\x6e\x61\x6e\x00\x00\x00\x00\x00\x4e\x41\x4e\x28\x53\x4e\x41\x4e\x29\x00\x00\x00\x00\x00\x00\x00\x6e\x61\x6e\x28\x73\x6e\x61\x6e\x29\x00\x00\x00\x00\x00\x00\x00\x4e\x41\x4e\x28\x49\x4e\x44\x29\x00\x00\x00\x00\x00\x00\x00\x00\x6e\x61\x6e\x28\x69\x6e\x64\x29\x00\x00\x00\x00\x65\x2b\x30\x30\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x1b\x01\x80\x01\x00\x00\x00\x94\x1b\x01\x80\x01\x00\x00\x00\x98\x1b\x01\x80\x01\x00\x00\x00\x9c\x1b\x01\x80\x01\x00\x00\x00\xa0\x1b\x01\x80\x01\x00\x00\x00\xa4\x1b\x01\x80\x01\x00\x00\x00\xa8\x1b\x01\x80\x01\x00\x00\x00\xac\x1b\x01\x80\x01\x00\x00\x00\xb4\x1b\x01\x80\x01\x00\x00\x00\xc0\x1b\x01\x80\x01\x00\x00\x00\xc8\x1b\x01\x80\x01\x00\x00\x00\xd8\x1b\x01\x80\x01\x00\x00\x00\xe4\x1b\x01\x80\x01\x00\x00\x00\xf0\x1b\x01\x80\x01\x00\x00\x00\xfc\x1b\x01\x80\x01\x00\x00\x00\x00\x1c\x01\x80\x01\x00\x00\x00\x04\x1c\x01\x80\x01\x00\x00\x00\x08\x1c\x01\x80\x01\x00\x00\x00\x0c\x1c\x01\x80\x01\x00\x00\x00\x10\x1c\x01\x80\x01\x00\x00\x00\x14\x1c\x01\x80\x01\x00\x00\x00\x18\x1c\x01\x80\x01\x00\x00\x00\x1c\x1c\x01\x80\x01\x00\x00\x00\x20\x1c\x01\x80\x01\x00\x00\x00\x24\x1c\x01\x80\x01\x00\x00\x00\x28\x1c\x01\x80\x01\x00\x00\x00\x30\x1c\x01\x80\x01\x00\x00\x00\x38\x1c\x01\x80\x01\x00\x00\x00\x44\x1c\x01\x80\x01\x00\x00\x00\x4c\x1c\x01\x80\x01\x00\x00\x00\x0c\x1c\x01\x80\x01\x00\x00\x00\x54\x1c\x01\x80\x01\x00\x00\x00\x5c\x1c\x01\x80\x01\x00\x00\x00\x64\x1c\x01\x80\x01\x00\x00\x00\x70\x1c\x01\x80\x01\x00\x00\x00\x80\x1c\x01\x80\x01\x00\x00\x00\x88\x1c\x01\x80\x01\x00\x00\x00\x98\x1c\x01\x80\x01\x00\x00\x00\xa4\x1c\x01\x80\x01\x00\x00\x00\xa8\x1c\x01\x80\x01\x00\x00\x00\xb0\x1c\x01\x80\x01\x00\x00\x00\xc0\x1c\x01\x80\x01\x00\x00\x00\xd8\x1c\x01\x80\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xe8\x1c\x01\x80\x01\x00\x00\x00\xf0\x1c\x01\x80\x01\x00\x00\x00\xf8\x1c\x01\x80\x01\x00\x00\x00\x00\x1d\x01\x80\x01\x00\x00\x00\x08\x1d\x01\x80\x01\x00\x00\x00\x10\x1d\x01\x80\x01\x00\x00\x00\x18\x1d\x01\x80\x01\x00\x00\x00\x20\x1d\x01\x80\x01\x00\x00\x00\x30\x1d\x01\x80\x01\x00\x00\x00\x40\x1d\x01\x80\x01\x00\x00\x00\x50\x1d\x01\x80\x01\x00\x00\x00\x68\x1d\x01\x80\x01\x00\x00\x00\x80\x1d\x01\x80\x01\x00\x00\x00\x90\x1d\x01\x80\x01\x00\x00\x00\xa8\x1d\x01\x80\x01\x00\x00\x00\xb0\x1d\x01\x80\x01\x00\x00\x00\xb8\x1d\x01\x80\x01\x00\x00\x00\xc0\x1d\x01\x80\x01\x00\x00\x00\xc8\x1d\x01\x80\x01\x00\x00\x00\xd0\x1d\x01\x80\x01\x00\x00\x00\xd8\x1d\x01\x80\x01\x00\x00\x00\xe0\x1d\x01\x80\x01\x00\x00\x00\xe8\x1d\x01\x80\x01\x00\x00\x00\xf0\x1d\x01\x80\x01\x00\x00\x00\xf8\x1d\x01\x80\x01\x00\x00\x00\x00\x1e\x01\x80\x01\x00\x00\x00\x08\x1e\x01\x80\x01\x00\x00\x00\x18\x1e\x01\x80\x01\x00\x00\x00\x30\x1e\x01\x80\x01\x00\x00\x00\x40\x1e\x01\x80\x01\x00\x00\x00\xc8\x1d\x01\x80\x01\x00\x00\x00\x50\x1e\x01\x80\x01\x00\x00\x00\x60\x1e\x01\x80\x01\x00\x00\x00\x70\x1e\x01\x80\x01\x00\x00\x00\x80\x1e\x01\x80\x01\x00\x00\x00\x98\x1e\x01\x80\x01\x00\x00\x00\xa8\x1e\x01\x80\x01\x00\x00\x00\xc0\x1e\x01\x80\x01\x00\x00\x00\xd4\x1e\x01\x80\x01\x00\x00\x00\xdc\x1e\x01\x80\x01\x00\x00\x00\xe8\x1e\x01\x80\x01\x00\x00\x00\x00\x1f\x01\x80\x01\x00\x00\x00\x28\x1f\x01\x80\x01\x00\x00\x00\x40\x1f\x01\x80\x01\x00\x00\x00\x53\x75\x6e\x00\x4d\x6f\x6e\x00\x54\x75\x65\x00\x57\x65\x64\x00\x54\x68\x75\x00\x46\x72\x69\x00\x53\x61\x74\x00\x53\x75\x6e\x64\x61\x79\x00\x00\x4d\x6f\x6e\x64\x61\x79\x00\x00\x00\x00\x00\x00\x54\x75\x65\x73\x64\x61\x79\x00\x57\x65\x64\x6e\x65\x73\x64\x61\x79\x00\x00\x00\x00\x00\x00\x00\x54\x68\x75\x72\x73\x64\x61\x79\x00\x00\x00\x00\x46\x72\x69\x64\x61\x79\x00\x00\x00\x00\x00\x00\x53\x61\x74\x75\x72\x64\x61\x79\x00\x00\x00\x00\x4a\x61\x6e\x00\x46\x65\x62\x00\x4d\x61\x72\x00\x41\x70\x72\x00\x4d\x61\x79\x00\x4a\x75\x6e\x00\x4a\x75\x6c\x00\x41\x75\x67\x00\x53\x65\x70\x00\x4f\x63\x74\x00\x4e\x6f\x76\x00\x44\x65\x63\x00\x00\x00\x00\x00\x4a\x61\x6e\x75\x61\x72\x79\x00\x46\x65\x62\x72\x75\x61\x72\x79\x00\x00\x00\x00\x4d\x61\x72\x63\x68\x00\x00\x00\x41\x70\x72\x69\x6c\x00\x00\x00\x4a\x75\x6e\x65\x00\x00\x00\x00\x4a\x75\x6c\x79\x00\x00\x00\x00\x41\x75\x67\x75\x73\x74\x00\x00\x00\x00\x00\x00\x53\x65\x70\x74\x65\x6d\x62\x65\x72\x00\x00\x00\x00\x00\x00\x00\x4f\x63\x74\x6f\x62\x65\x72\x00\x4e\x6f\x76\x65\x6d\x62\x65\x72\x00\x00\x00\x00\x00\x00\x00\x00\x44\x65\x63\x65\x6d\x62\x65\x72\x00\x00\x00\x00\x41\x4d\x00\x00\x50\x4d\x00\x00\x00\x00\x00\x00\x4d\x4d\x2f\x64\x64\x2f\x79\x79\x00\x00\x00\x00\x00\x00\x00\x00\x64\x64\x64\x64\x2c\x20\x4d\x4d\x4d\x4d\x20\x64\x64\x2c\x20\x79\x79\x79\x79\x00\x00\x00\x00\x00\x48\x48\x3a\x6d\x6d\x3a\x73\x73\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x75\x00\x6e\x00\x00\x00\x4d\x00\x6f\x00\x6e\x00\x00\x00\x54\x00\x75\x00\x65\x00\x00\x00\x57\x00\x65\x00\x64\x00\x00\x00\x54\x00\x68\x00\x75\x00\x00\x00\x46\x00\x72\x00\x69\x00\x00\x00\x53\x00\x61\x00\x74\x00\x00\x00\x53\x00\x75\x00\x6e\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x4d\x00\x6f\x00\x6e\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x54\x00\x75\x00\x65\x00\x73\x00\x64\x00\x61\x00\x79\x00\x00\x00\x57\x00\x65\x00\x64\x00\x6e\x00\x65\x00\x73\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x00\x00\x54\x00\x68\x00\x75\x00\x72\x00\x73\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x00\x00\x00\x00\x46\x00\x72\x00\x69\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x53\x00\x61\x00\x74\x00\x75\x00\x72\x00\x64\x00\x61\x00\x79\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x61\x00\x6e\x00\x00\x00\x46\x00\x65\x00\x62\x00\x00\x00\x4d\x00\x61\x00\x72\x00\x00\x00\x41\x00\x70\x00\x72\x00\x00\x00\x4d\x00\x61\x00\x79\x00\x00\x00\x4a\x00\x75\x00\x6e\x00\x00\x00\x4a\x00\x75\x00\x6c\x00\x00\x00\x41\x00\x75\x00\x67\x00\x00\x00\x53\x00\x65\x00\x70\x00\x00\x00\x4f\x00\x63\x00\x74\x00\x00\x00\x4e\x00\x6f\x00\x76\x00\x00\x00\x44\x00\x65\x00\x63\x00\x00\x00\x4a\x00\x61\x00\x6e\x00\x75\x00\x61\x00\x72\x00\x79\x00\x00\x00\x46\x00\x65\x00\x62\x00\x72\x00\x75\x00\x61\x00\x72\x00\x79\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4d\x00\x61\x00\x72\x00\x63\x00\x68\x00\x00\x00\x00\x00\x00\x00\x41\x00\x70\x00\x72\x00\x69\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x75\x00\x6e\x00\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x75\x00\x6c\x00\x79\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\x00\x75\x00\x67\x00\x75\x00\x73\x00\x74\x00\x00\x00\x00\x00\x53\x00\x65\x00\x70\x00\x74\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00\x00\x00\x00\x00\x00\x00\x4f\x00\x63\x00\x74\x00\x6f\x00\x62\x00\x65\x00\x72\x00\x00\x00\x4e\x00\x6f\x00\x76\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x65\x00\x63\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00\x00\x00\x00\x00\x41\x00\x4d\x00\x00\x00\x00\x00\x50\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4d\x00\x4d\x00\x2f\x00\x64\x00\x64\x00\x2f\x00\x79\x00\x79\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x00\x64\x00\x64\x00\x64\x00\x2c\x00\x20\x00\x4d\x00\x4d\x00\x4d\x00\x4d\x00\x20\x00\x64\x00\x64\x00\x2c\x00\x20\x00\x79\x00\x79\x00\x79\x00\x79\x00\x00\x00\x48\x00\x48\x00\x3a\x00\x6d\x00\x6d\x00\x3a\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x55\x00\x53\x00\x00\x00\x00\x00\x00\x00\x70\x1f\x01\x80\x01\x00\x00\x00\x80\x1f\x01\x80\x01\x00\x00\x00\x90\x1f\x01\x80\x01\x00\x00\x00\xa0\x1f\x01\x80\x01\x00\x00\x00\x6a\x00\x61\x00\x2d\x00\x4a\x00\x50\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x43\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x2d\x00\x4b\x00\x52\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x54\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x20\x00\x48\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x84\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x10\x00\x10\x00\x10\x00\x10\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x01\x00\x00\x00\x00\x00\x00\x00\xf0\x33\x01\x80\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xf8\x33\x01\x80\x01\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x34\x01\x80\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x08\x34\x01\x80\x01\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x18\x34\x01\x80\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x20\x34\x01\x80\x01\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x28\x34\x01\x80\x01\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x30\x34\x01\x80\x01\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x38\x34\x01\x80\x01\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x40\x34\x01\x80\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x48\x34\x01\x80\x01\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x50\x34\x01\x80\x01\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x58\x34\x01\x80\x01\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x60\x34\x01\x80\x01\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x68\x34\x01\x80\x01\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x70\x34\x01\x80\x01\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x78\x34\x01\x80\x01\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x80\x34\x01\x80\x01\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x88\x34\x01\x80\x01\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x90\x34\x01\x80\x01\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x98\x34\x01\x80\x01\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\xa0\x34\x01\x80\x01\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\xa8\x34\x01\x80\x01\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\xb0\x34\x01\x80\x01\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\xb8\x34\x01\x80\x01\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\xc0\x34\x01\x80\x01\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\xc8\x34\x01\x80\x01\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\xd0\x34\x01\x80\x01\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\xd8\x34\x01\x80\x01\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\xe0\x34\x01\x80\x01\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\xe8\x34\x01\x80\x01\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\xf0\x34\x01\x80\x01\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\xf8\x34\x01\x80\x01\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x00\x35\x01\x80\x01\x00\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x08\x35\x01\x80\x01\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x10\x35\x01\x80\x01\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x18\x35\x01\x80\x01\x00\x00\x00\x27\x00\x00\x00\x00\x00\x00\x00\x20\x35\x01\x80\x01\x00\x00\x00\x29\x00\x00\x00\x00\x00\x00\x00\x28\x35\x01\x80\x01\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x30\x35\x01\x80\x01\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x38\x35\x01\x80\x01\x00\x00\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x40\x35\x01\x80\x01\x00\x00\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x48\x35\x01\x80\x01\x00\x00\x00\x2f\x00\x00\x00\x00\x00\x00\x00\x50\x35\x01\x80\x01\x00\x00\x00\x36\x00\x00\x00\x00\x00\x00\x00\x58\x35\x01\x80\x01\x00\x00\x00\x37\x00\x00\x00\x00\x00\x00\x00\x60\x35\x01\x80\x01\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\x68\x35\x01\x80\x01\x00\x00\x00\x39\x00\x00\x00\x00\x00\x00\x00\x70\x35\x01\x80\x01\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x78\x35\x01\x80\x01\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x80\x35\x01\x80\x01\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x88\x35\x01\x80\x01\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x90\x35\x01\x80\x01\x00\x00\x00\x43\x00\x00\x00\x00\x00\x00\x00\x98\x35\x01\x80\x01\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\xa0\x35\x01\x80\x01\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\xa8\x35\x01\x80\x01\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\xb0\x35\x01\x80\x01\x00\x00\x00\x49\x00\x00\x00\x00\x00\x00\x00\xb8\x35\x01\x80\x01\x00\x00\x00\x4a\x00\x00\x00\x00\x00\x00\x00\xc0\x35\x01\x80\x01\x00\x00\x00\x4b\x00\x00\x00\x00\x00\x00\x00\xc8\x35\x01\x80\x01\x00\x00\x00\x4e\x00\x00\x00\x00\x00\x00\x00\xd0\x35\x01\x80\x01\x00\x00\x00\x4f\x00\x00\x00\x00\x00\x00\x00\xd8\x35\x01\x80\x01\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\xe0\x35\x01\x80\x01\x00\x00\x00\x56\x00\x00\x00\x00\x00\x00\x00\xe8\x35\x01\x80\x01\x00\x00\x00\x57\x00\x00\x00\x00\x00\x00\x00\xf0\x35\x01\x80\x01\x00\x00\x00\x5a\x00\x00\x00\x00\x00\x00\x00\xf8\x35\x01\x80\x01\x00\x00\x00\x65\x00\x00\x00\x00\x00\x00\x00\x00\x36\x01\x80\x01\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\xac\x7d\x01\x80\x01\x00\x00\x00\x01\x04\x00\x00\x00\x00\x00\x00\x08\x36\x01\x80\x01\x00\x00\x00\x02\x04\x00\x00\x00\x00\x00\x00\x18\x36\x01\x80\x01\x00\x00\x00\x03\x04\x00\x00\x00\x00\x00\x00\x28\x36\x01\x80\x01\x00\x00\x00\x04\x04\x00\x00\x00\x00\x00\x00\xa0\x1f\x01\x80\x01\x00\x00\x00\x05\x04\x00\x00\x00\x00\x00\x00\x38\x36\x01\x80\x01\x00\x00\x00\x06\x04\x00\x00\x00\x00\x00\x00\x48\x36\x01\x80\x01\x00\x00\x00\x07\x04\x00\x00\x00\x00\x00\x00\x58\x36\x01\x80\x01\x00\x00\x00\x08\x04\x00\x00\x00\x00\x00\x00\x68\x36\x01\x80\x01\x00\x00\x00\x09\x04\x00\x00\x00\x00\x00\x00\x40\x1f\x01\x80\x01\x00\x00\x00\x0b\x04\x00\x00\x00\x00\x00\x00\x78\x36\x01\x80\x01\x00\x00\x00\x0c\x04\x00\x00\x00\x00\x00\x00\x88\x36\x01\x80\x01\x00\x00\x00\x0d\x04\x00\x00\x00\x00\x00\x00\x98\x36\x01\x80\x01\x00\x00\x00\x0e\x04\x00\x00\x00\x00\x00\x00\xa8\x36\x01\x80\x01\x00\x00\x00\x0f\x04\x00\x00\x00\x00\x00\x00\xb8\x36\x01\x80\x01\x00\x00\x00\x10\x04\x00\x00\x00\x00\x00\x00\xc8\x36\x01\x80\x01\x00\x00\x00\x11\x04\x00\x00\x00\x00\x00\x00\x70\x1f\x01\x80\x01\x00\x00\x00\x12\x04\x00\x00\x00\x00\x00\x00\x90\x1f\x01\x80\x01\x00\x00\x00\x13\x04\x00\x00\x00\x00\x00\x00\xd8\x36\x01\x80\x01\x00\x00\x00\x14\x04\x00\x00\x00\x00\x00\x00\xe8\x36\x01\x80\x01\x00\x00\x00\x15\x04\x00\x00\x00\x00\x00\x00\xf8\x36\x01\x80\x01\x00\x00\x00\x16\x04\x00\x00\x00\x00\x00\x00\x08\x37\x01\x80\x01\x00\x00\x00\x18\x04\x00\x00\x00\x00\x00\x00\x18\x37\x01\x80\x01\x00\x00\x00\x19\x04\x00\x00\x00\x00\x00\x00\x28\x37\x01\x80\x01\x00\x00\x00\x1a\x04\x00\x00\x00\x00\x00\x00\x38\x37\x01\x80\x01\x00\x00\x00\x1b\x04\x00\x00\x00\x00\x00\x00\x48\x37\x01\x80\x01\x00\x00\x00\x1c\x04\x00\x00\x00\x00\x00\x00\x58\x37\x01\x80\x01\x00\x00\x00\x1d\x04\x00\x00\x00\x00\x00\x00\x68\x37\x01\x80\x01\x00\x00\x00\x1e\x04\x00\x00\x00\x00\x00\x00\x78\x37\x01\x80\x01\x00\x00\x00\x1f\x04\x00\x00\x00\x00\x00\x00\x88\x37\x01\x80\x01\x00\x00\x00\x20\x04\x00\x00\x00\x00\x00\x00\x98\x37\x01\x80\x01\x00\x00\x00\x21\x04\x00\x00\x00\x00\x00\x00\xa8\x37\x01\x80\x01\x00\x00\x00\x22\x04\x00\x00\x00\x00\x00\x00\xb8\x37\x01\x80\x01\x00\x00\x00\x23\x04\x00\x00\x00\x00\x00\x00\xc8\x37\x01\x80\x01\x00\x00\x00\x24\x04\x00\x00\x00\x00\x00\x00\xd8\x37\x01\x80\x01\x00\x00\x00\x25\x04\x00\x00\x00\x00\x00\x00\xe8\x37\x01\x80\x01\x00\x00\x00\x26\x04\x00\x00\x00\x00\x00\x00\xf8\x37\x01\x80\x01\x00\x00\x00\x27\x04\x00\x00\x00\x00\x00\x00\x08\x38\x01\x80\x01\x00\x00\x00\x29\x04\x00\x00\x00\x00\x00\x00\x18\x38\x01\x80\x01\x00\x00\x00\x2a\x04\x00\x00\x00\x00\x00\x00\x28\x38\x01\x80\x01\x00\x00\x00\x2b\x04\x00\x00\x00\x00\x00\x00\x38\x38\x01\x80\x01\x00\x00\x00\x2c\x04\x00\x00\x00\x00\x00\x00\x48\x38\x01\x80\x01\x00\x00\x00\x2d\x04\x00\x00\x00\x00\x00\x00\x60\x38\x01\x80\x01\x00\x00\x00\x2f\x04\x00\x00\x00\x00\x00\x00\x70\x38\x01\x80\x01\x00\x00\x00\x32\x04\x00\x00\x00\x00\x00\x00\x80\x38\x01\x80\x01\x00\x00\x00\x34\x04\x00\x00\x00\x00\x00\x00\x90\x38\x01\x80\x01\x00\x00\x00\x35\x04\x00\x00\x00\x00\x00\x00\xa0\x38\x01\x80\x01\x00\x00\x00\x36\x04\x00\x00\x00\x00\x00\x00\xb0\x38\x01\x80\x01\x00\x00\x00\x37\x04\x00\x00\x00\x00\x00\x00\xc0\x38\x01\x80\x01\x00\x00\x00\x38\x04\x00\x00\x00\x00\x00\x00\xd0\x38\x01\x80\x01\x00\x00\x00\x39\x04\x00\x00\x00\x00\x00\x00\xe0\x38\x01\x80\x01\x00\x00\x00\x3a\x04\x00\x00\x00\x00\x00\x00\xf0\x38\x01\x80\x01\x00\x00\x00\x3b\x04\x00\x00\x00\x00\x00\x00\x00\x39\x01\x80\x01\x00\x00\x00\x3e\x04\x00\x00\x00\x00\x00\x00\x10\x39\x01\x80\x01\x00\x00\x00\x3f\x04\x00\x00\x00\x00\x00\x00\x20\x39\x01\x80\x01\x00\x00\x00\x40\x04\x00\x00\x00\x00\x00\x00\x30\x39\x01\x80\x01\x00\x00\x00\x41\x04\x00\x00\x00\x00\x00\x00\x40\x39\x01\x80\x01\x00\x00\x00\x43\x04\x00\x00\x00\x00\x00\x00\x50\x39\x01\x80\x01\x00\x00\x00\x44\x04\x00\x00\x00\x00\x00\x00\x68\x39\x01\x80\x01\x00\x00\x00\x45\x04\x00\x00\x00\x00\x00\x00\x78\x39\x01\x80\x01\x00\x00\x00\x46\x04\x00\x00\x00\x00\x00\x00\x88\x39\x01\x80\x01\x00\x00\x00\x47\x04\x00\x00\x00\x00\x00\x00\x98\x39\x01\x80\x01\x00\x00\x00\x49\x04\x00\x00\x00\x00\x00\x00\xa8\x39\x01\x80\x01\x00\x00\x00\x4a\x04\x00\x00\x00\x00\x00\x00\xb8\x39\x01\x80\x01\x00\x00\x00\x4b\x04\x00\x00\x00\x00\x00\x00\xc8\x39\x01\x80\x01\x00\x00\x00\x4c\x04\x00\x00\x00\x00\x00\x00\xd8\x39\x01\x80\x01\x00\x00\x00\x4e\x04\x00\x00\x00\x00\x00\x00\xe8\x39\x01\x80\x01\x00\x00\x00\x4f\x04\x00\x00\x00\x00\x00\x00\xf8\x39\x01\x80\x01\x00\x00\x00\x50\x04\x00\x00\x00\x00\x00\x00\x08\x3a\x01\x80\x01\x00\x00\x00\x52\x04\x00\x00\x00\x00\x00\x00\x18\x3a\x01\x80\x01\x00\x00\x00\x56\x04\x00\x00\x00\x00\x00\x00\x28\x3a\x01\x80\x01\x00\x00\x00\x57\x04\x00\x00\x00\x00\x00\x00\x38\x3a\x01\x80\x01\x00\x00\x00\x5a\x04\x00\x00\x00\x00\x00\x00\x48\x3a\x01\x80\x01\x00\x00\x00\x65\x04\x00\x00\x00\x00\x00\x00\x58\x3a\x01\x80\x01\x00\x00\x00\x6b\x04\x00\x00\x00\x00\x00\x00\x68\x3a\x01\x80\x01\x00\x00\x00\x6c\x04\x00\x00\x00\x00\x00\x00\x78\x3a\x01\x80\x01\x00\x00\x00\x81\x04\x00\x00\x00\x00\x00\x00\x88\x3a\x01\x80\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00\x00\x00\x98\x3a\x01\x80\x01\x00\x00\x00\x04\x08\x00\x00\x00\x00\x00\x00\x80\x1f\x01\x80\x01\x00\x00\x00\x07\x08\x00\x00\x00\x00\x00\x00\xa8\x3a\x01\x80\x01\x00\x00\x00\x09\x08\x00\x00\x00\x00\x00\x00\xb8\x3a\x01\x80\x01\x00\x00\x00\x0a\x08\x00\x00\x00\x00\x00\x00\xc8\x3a\x01\x80\x01\x00\x00\x00\x0c\x08\x00\x00\x00\x00\x00\x00\xd8\x3a\x01\x80\x01\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\xe8\x3a\x01\x80\x01\x00\x00\x00\x13\x08\x00\x00\x00\x00\x00\x00\xf8\x3a\x01\x80\x01\x00\x00\x00\x14\x08\x00\x00\x00\x00\x00\x00\x08\x3b\x01\x80\x01\x00\x00\x00\x16\x08\x00\x00\x00\x00\x00\x00\x18\x3b\x01\x80\x01\x00\x00\x00\x1a\x08\x00\x00\x00\x00\x00\x00\x28\x3b\x01\x80\x01\x00\x00\x00\x1d\x08\x00\x00\x00\x00\x00\x00\x40\x3b\x01\x80\x01\x00\x00\x00\x2c\x08\x00\x00\x00\x00\x00\x00\x50\x3b\x01\x80\x01\x00\x00\x00\x3b\x08\x00\x00\x00\x00\x00\x00\x68\x3b\x01\x80\x01\x00\x00\x00\x3e\x08\x00\x00\x00\x00\x00\x00\x78\x3b\x01\x80\x01\x00\x00\x00\x43\x08\x00\x00\x00\x00\x00\x00\x88\x3b\x01\x80\x01\x00\x00\x00\x6b\x08\x00\x00\x00\x00\x00\x00\xa0\x3b\x01\x80\x01\x00\x00\x00\x01\x0c\x00\x00\x00\x00\x00\x00\xb0\x3b\x01\x80\x01\x00\x00\x00\x04\x0c\x00\x00\x00\x00\x00\x00\xc0\x3b\x01\x80\x01\x00\x00\x00\x07\x0c\x00\x00\x00\x00\x00\x00\xd0\x3b\x01\x80\x01\x00\x00\x00\x09\x0c\x00\x00\x00\x00\x00\x00\xe0\x3b\x01\x80\x01\x00\x00\x00\x0a\x0c\x00\x00\x00\x00\x00\x00\xf0\x3b\x01\x80\x01\x00\x00\x00\x0c\x0c\x00\x00\x00\x00\x00\x00\x00\x3c\x01\x80\x01\x00\x00\x00\x1a\x0c\x00\x00\x00\x00\x00\x00\x10\x3c\x01\x80\x01\x00\x00\x00\x3b\x0c\x00\x00\x00\x00\x00\x00\x28\x3c\x01\x80\x01\x00\x00\x00\x6b\x0c\x00\x00\x00\x00\x00\x00\x38\x3c\x01\x80\x01\x00\x00\x00\x01\x10\x00\x00\x00\x00\x00\x00\x48\x3c\x01\x80\x01\x00\x00\x00\x04\x10\x00\x00\x00\x00\x00\x00\x58\x3c\x01\x80\x01\x00\x00\x00\x07\x10\x00\x00\x00\x00\x00\x00\x68\x3c\x01\x80\x01\x00\x00\x00\x09\x10\x00\x00\x00\x00\x00\x00\x78\x3c\x01\x80\x01\x00\x00\x00\x0a\x10\x00\x00\x00\x00\x00\x00\x88\x3c\x01\x80\x01\x00\x00\x00\x0c\x10\x00\x00\x00\x00\x00\x00\x98\x3c\x01\x80\x01\x00\x00\x00\x1a\x10\x00\x00\x00\x00\x00\x00\xa8\x3c\x01\x80\x01\x00\x00\x00\x3b\x10\x00\x00\x00\x00\x00\x00\xb8\x3c\x01\x80\x01\x00\x00\x00\x01\x14\x00\x00\x00\x00\x00\x00\xc8\x3c\x01\x80\x01\x00\x00\x00\x04\x14\x00\x00\x00\x00\x00\x00\xd8\x3c\x01\x80\x01\x00\x00\x00\x07\x14\x00\x00\x00\x00\x00\x00\xe8\x3c\x01\x80\x01\x00\x00\x00\x09\x14\x00\x00\x00\x00\x00\x00\xf8\x3c\x01\x80\x01\x00\x00\x00\x0a\x14\x00\x00\x00\x00\x00\x00\x08\x3d\x01\x80\x01\x00\x00\x00\x0c\x14\x00\x00\x00\x00\x00\x00\x18\x3d\x01\x80\x01\x00\x00\x00\x1a\x14\x00\x00\x00\x00\x00\x00\x28\x3d\x01\x80\x01\x00\x00\x00\x3b\x14\x00\x00\x00\x00\x00\x00\x40\x3d\x01\x80\x01\x00\x00\x00\x01\x18\x00\x00\x00\x00\x00\x00\x50\x3d\x01\x80\x01\x00\x00\x00\x09\x18\x00\x00\x00\x00\x00\x00\x60\x3d\x01\x80\x01\x00\x00\x00\x0a\x18\x00\x00\x00\x00\x00\x00\x70\x3d\x01\x80\x01\x00\x00\x00\x0c\x18\x00\x00\x00\x00\x00\x00\x80\x3d\x01\x80\x01\x00\x00\x00\x1a\x18\x00\x00\x00\x00\x00\x00\x90\x3d\x01\x80\x01\x00\x00\x00\x3b\x18\x00\x00\x00\x00\x00\x00\xa8\x3d\x01\x80\x01\x00\x00\x00\x01\x1c\x00\x00\x00\x00\x00\x00\xb8\x3d\x01\x80\x01\x00\x00\x00\x09\x1c\x00\x00\x00\x00\x00\x00\xc8\x3d\x01\x80\x01\x00\x00\x00\x0a\x1c\x00\x00\x00\x00\x00\x00\xd8\x3d\x01\x80\x01\x00\x00\x00\x1a\x1c\x00\x00\x00\x00\x00\x00\xe8\x3d\x01\x80\x01\x00\x00\x00\x3b\x1c\x00\x00\x00\x00\x00\x00\x00\x3e\x01\x80\x01\x00\x00\x00\x01\x20\x00\x00\x00\x00\x00\x00\x10\x3e\x01\x80\x01\x00\x00\x00\x09\x20\x00\x00\x00\x00\x00\x00\x20\x3e\x01\x80\x01\x00\x00\x00\x0a\x20\x00\x00\x00\x00\x00\x00\x30\x3e\x01\x80\x01\x00\x00\x00\x3b\x20\x00\x00\x00\x00\x00\x00\x40\x3e\x01\x80\x01\x00\x00\x00\x01\x24\x00\x00\x00\x00\x00\x00\x50\x3e\x01\x80\x01\x00\x00\x00\x09\x24\x00\x00\x00\x00\x00\x00\x60\x3e\x01\x80\x01\x00\x00\x00\x0a\x24\x00\x00\x00\x00\x00\x00\x70\x3e\x01\x80\x01\x00\x00\x00\x3b\x24\x00\x00\x00\x00\x00\x00\x80\x3e\x01\x80\x01\x00\x00\x00\x01\x28\x00\x00\x00\x00\x00\x00\x90\x3e\x01\x80\x01\x00\x00\x00\x09\x28\x00\x00\x00\x00\x00\x00\xa0\x3e\x01\x80\x01\x00\x00\x00\x0a\x28\x00\x00\x00\x00\x00\x00\xb0\x3e\x01\x80\x01\x00\x00\x00\x01\x2c\x00\x00\x00\x00\x00\x00\xc0\x3e\x01\x80\x01\x00\x00\x00\x09\x2c\x00\x00\x00\x00\x00\x00\xd0\x3e\x01\x80\x01\x00\x00\x00\x0a\x2c\x00\x00\x00\x00\x00\x00\xe0\x3e\x01\x80\x01\x00\x00\x00\x01\x30\x00\x00\x00\x00\x00\x00\xf0\x3e\x01\x80\x01\x00\x00\x00\x09\x30\x00\x00\x00\x00\x00\x00\x00\x3f\x01\x80\x01\x00\x00\x00\x0a\x30\x00\x00\x00\x00\x00\x00\x10\x3f\x01\x80\x01\x00\x00\x00\x01\x34\x00\x00\x00\x00\x00\x00\x20\x3f\x01\x80\x01\x00\x00\x00\x09\x34\x00\x00\x00\x00\x00\x00\x30\x3f\x01\x80\x01\x00\x00\x00\x0a\x34\x00\x00\x00\x00\x00\x00\x40\x3f\x01\x80\x01\x00\x00\x00\x01\x38\x00\x00\x00\x00\x00\x00\x50\x3f\x01\x80\x01\x00\x00\x00\x0a\x38\x00\x00\x00\x00\x00\x00\x60\x3f\x01\x80\x01\x00\x00\x00\x01\x3c\x00\x00\x00\x00\x00\x00\x70\x3f\x01\x80\x01\x00\x00\x00\x0a\x3c\x00\x00\x00\x00\x00\x00\x80\x3f\x01\x80\x01\x00\x00\x00\x01\x40\x00\x00\x00\x00\x00\x00\x90\x3f\x01\x80\x01\x00\x00\x00\x0a\x40\x00\x00\x00\x00\x00\x00\xa0\x3f\x01\x80\x01\x00\x00\x00\x0a\x44\x00\x00\x00\x00\x00\x00\xb0\x3f\x01\x80\x01\x00\x00\x00\x0a\x48\x00\x00\x00\x00\x00\x00\xc0\x3f\x01\x80\x01\x00\x00\x00\x0a\x4c\x00\x00\x00\x00\x00\x00\xd0\x3f\x01\x80\x01\x00\x00\x00\x0a\x50\x00\x00\x00\x00\x00\x00\xe0\x3f\x01\x80\x01\x00\x00\x00\x04\x7c\x00\x00\x00\x00\x00\x00\xf0\x3f\x01\x80\x01\x00\x00\x00\x1a\x7c\x00\x00\x00\x00\x00\x00\x00\x40\x01\x80\x01\x00\x00\x00\x61\x00\x72\x00\x00\x00\x00\x00\x62\x00\x67\x00\x00\x00\x00\x00\x63\x00\x61\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x43\x00\x48\x00\x53\x00\x00\x00\x00\x00\x63\x00\x73\x00\x00\x00\x00\x00\x64\x00\x61\x00\x00\x00\x00\x00\x64\x00\x65\x00\x00\x00\x00\x00\x65\x00\x6c\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x00\x00\x00\x00\x65\x00\x73\x00\x00\x00\x00\x00\x66\x00\x69\x00\x00\x00\x00\x00\x66\x00\x72\x00\x00\x00\x00\x00\x68\x00\x65\x00\x00\x00\x00\x00\x68\x00\x75\x00\x00\x00\x00\x00\x69\x00\x73\x00\x00\x00\x00\x00\x69\x00\x74\x00\x00\x00\x00\x00\x6a\x00\x61\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x00\x00\x00\x00\x6e\x00\x6c\x00\x00\x00\x00\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x70\x00\x6c\x00\x00\x00\x00\x00\x70\x00\x74\x00\x00\x00\x00\x00\x72\x00\x6f\x00\x00\x00\x00\x00\x72\x00\x75\x00\x00\x00\x00\x00\x68\x00\x72\x00\x00\x00\x00\x00\x73\x00\x6b\x00\x00\x00\x00\x00\x73\x00\x71\x00\x00\x00\x00\x00\x73\x00\x76\x00\x00\x00\x00\x00\x74\x00\x68\x00\x00\x00\x00\x00\x74\x00\x72\x00\x00\x00\x00\x00\x75\x00\x72\x00\x00\x00\x00\x00\x69\x00\x64\x00\x00\x00\x00\x00\x75\x00\x6b\x00\x00\x00\x00\x00\x62\x00\x65\x00\x00\x00\x00\x00\x73\x00\x6c\x00\x00\x00\x00\x00\x65\x00\x74\x00\x00\x00\x00\x00\x6c\x00\x76\x00\x00\x00\x00\x00\x6c\x00\x74\x00\x00\x00\x00\x00\x66\x00\x61\x00\x00\x00\x00\x00\x76\x00\x69\x00\x00\x00\x00\x00\x68\x00\x79\x00\x00\x00\x00\x00\x61\x00\x7a\x00\x00\x00\x00\x00\x65\x00\x75\x00\x00\x00\x00\x00\x6d\x00\x6b\x00\x00\x00\x00\x00\x61\x00\x66\x00\x00\x00\x00\x00\x6b\x00\x61\x00\x00\x00\x00\x00\x66\x00\x6f\x00\x00\x00\x00\x00\x68\x00\x69\x00\x00\x00\x00\x00\x6d\x00\x73\x00\x00\x00\x00\x00\x6b\x00\x6b\x00\x00\x00\x00\x00\x6b\x00\x79\x00\x00\x00\x00\x00\x73\x00\x77\x00\x00\x00\x00\x00\x75\x00\x7a\x00\x00\x00\x00\x00\x74\x00\x74\x00\x00\x00\x00\x00\x70\x00\x61\x00\x00\x00\x00\x00\x67\x00\x75\x00\x00\x00\x00\x00\x74\x00\x61\x00\x00\x00\x00\x00\x74\x00\x65\x00\x00\x00\x00\x00\x6b\x00\x6e\x00\x00\x00\x00\x00\x6d\x00\x72\x00\x00\x00\x00\x00\x73\x00\x61\x00\x00\x00\x00\x00\x6d\x00\x6e\x00\x00\x00\x00\x00\x67\x00\x6c\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x6b\x00\x00\x00\x73\x00\x79\x00\x72\x00\x00\x00\x64\x00\x69\x00\x76\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x53\x00\x41\x00\x00\x00\x00\x00\x00\x00\x62\x00\x67\x00\x2d\x00\x42\x00\x47\x00\x00\x00\x00\x00\x00\x00\x63\x00\x61\x00\x2d\x00\x45\x00\x53\x00\x00\x00\x00\x00\x00\x00\x63\x00\x73\x00\x2d\x00\x43\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x64\x00\x61\x00\x2d\x00\x44\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x44\x00\x45\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6c\x00\x2d\x00\x47\x00\x52\x00\x00\x00\x00\x00\x00\x00\x66\x00\x69\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x46\x00\x52\x00\x00\x00\x00\x00\x00\x00\x68\x00\x65\x00\x2d\x00\x49\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x68\x00\x75\x00\x2d\x00\x48\x00\x55\x00\x00\x00\x00\x00\x00\x00\x69\x00\x73\x00\x2d\x00\x49\x00\x53\x00\x00\x00\x00\x00\x00\x00\x69\x00\x74\x00\x2d\x00\x49\x00\x54\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x6c\x00\x2d\x00\x4e\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x62\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x70\x00\x6c\x00\x2d\x00\x50\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x70\x00\x74\x00\x2d\x00\x42\x00\x52\x00\x00\x00\x00\x00\x00\x00\x72\x00\x6f\x00\x2d\x00\x52\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x72\x00\x75\x00\x2d\x00\x52\x00\x55\x00\x00\x00\x00\x00\x00\x00\x68\x00\x72\x00\x2d\x00\x48\x00\x52\x00\x00\x00\x00\x00\x00\x00\x73\x00\x6b\x00\x2d\x00\x53\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x73\x00\x71\x00\x2d\x00\x41\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x73\x00\x76\x00\x2d\x00\x53\x00\x45\x00\x00\x00\x00\x00\x00\x00\x74\x00\x68\x00\x2d\x00\x54\x00\x48\x00\x00\x00\x00\x00\x00\x00\x74\x00\x72\x00\x2d\x00\x54\x00\x52\x00\x00\x00\x00\x00\x00\x00\x75\x00\x72\x00\x2d\x00\x50\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x69\x00\x64\x00\x2d\x00\x49\x00\x44\x00\x00\x00\x00\x00\x00\x00\x75\x00\x6b\x00\x2d\x00\x55\x00\x41\x00\x00\x00\x00\x00\x00\x00\x62\x00\x65\x00\x2d\x00\x42\x00\x59\x00\x00\x00\x00\x00\x00\x00\x73\x00\x6c\x00\x2d\x00\x53\x00\x49\x00\x00\x00\x00\x00\x00\x00\x65\x00\x74\x00\x2d\x00\x45\x00\x45\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x76\x00\x2d\x00\x4c\x00\x56\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x74\x00\x2d\x00\x4c\x00\x54\x00\x00\x00\x00\x00\x00\x00\x66\x00\x61\x00\x2d\x00\x49\x00\x52\x00\x00\x00\x00\x00\x00\x00\x76\x00\x69\x00\x2d\x00\x56\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x68\x00\x79\x00\x2d\x00\x41\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x61\x00\x7a\x00\x2d\x00\x41\x00\x5a\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x65\x00\x75\x00\x2d\x00\x45\x00\x53\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6b\x00\x2d\x00\x4d\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x74\x00\x6e\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x00\x00\x00\x00\x78\x00\x68\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x75\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x00\x00\x00\x00\x61\x00\x66\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x61\x00\x2d\x00\x47\x00\x45\x00\x00\x00\x00\x00\x00\x00\x66\x00\x6f\x00\x2d\x00\x46\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x68\x00\x69\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x74\x00\x2d\x00\x4d\x00\x54\x00\x00\x00\x00\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x73\x00\x2d\x00\x4d\x00\x59\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6b\x00\x2d\x00\x4b\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x79\x00\x2d\x00\x4b\x00\x47\x00\x00\x00\x00\x00\x00\x00\x73\x00\x77\x00\x2d\x00\x4b\x00\x45\x00\x00\x00\x00\x00\x00\x00\x75\x00\x7a\x00\x2d\x00\x55\x00\x5a\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x74\x00\x74\x00\x2d\x00\x52\x00\x55\x00\x00\x00\x00\x00\x00\x00\x62\x00\x6e\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x70\x00\x61\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x67\x00\x75\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x74\x00\x61\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x74\x00\x65\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6e\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6c\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x72\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x73\x00\x61\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6e\x00\x2d\x00\x4d\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x63\x00\x79\x00\x2d\x00\x47\x00\x42\x00\x00\x00\x00\x00\x00\x00\x67\x00\x6c\x00\x2d\x00\x45\x00\x53\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x6b\x00\x2d\x00\x49\x00\x4e\x00\x00\x00\x00\x00\x73\x00\x79\x00\x72\x00\x2d\x00\x53\x00\x59\x00\x00\x00\x00\x00\x64\x00\x69\x00\x76\x00\x2d\x00\x4d\x00\x56\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x42\x00\x4f\x00\x00\x00\x00\x00\x6e\x00\x73\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x69\x00\x2d\x00\x4e\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x49\x00\x51\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x43\x00\x48\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x47\x00\x42\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x4d\x00\x58\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x42\x00\x45\x00\x00\x00\x00\x00\x00\x00\x69\x00\x74\x00\x2d\x00\x43\x00\x48\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x6c\x00\x2d\x00\x42\x00\x45\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x6e\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x70\x00\x74\x00\x2d\x00\x50\x00\x54\x00\x00\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x53\x00\x50\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x76\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x00\x00\x00\x00\x61\x00\x7a\x00\x2d\x00\x41\x00\x5a\x00\x2d\x00\x43\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x53\x00\x45\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x73\x00\x2d\x00\x42\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x75\x00\x7a\x00\x2d\x00\x55\x00\x5a\x00\x2d\x00\x43\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x45\x00\x43\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x45\x00\x47\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x48\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x41\x00\x54\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x41\x00\x55\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x45\x00\x53\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x43\x00\x41\x00\x00\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x53\x00\x50\x00\x2d\x00\x43\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x50\x00\x45\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4c\x00\x59\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x53\x00\x47\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x4c\x00\x55\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x43\x00\x41\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x47\x00\x54\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x43\x00\x48\x00\x00\x00\x00\x00\x00\x00\x68\x00\x72\x00\x2d\x00\x42\x00\x41\x00\x00\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6a\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x44\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x4d\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x4c\x00\x49\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x4e\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x43\x00\x52\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x4c\x00\x55\x00\x00\x00\x00\x00\x00\x00\x62\x00\x73\x00\x2d\x00\x42\x00\x41\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6a\x00\x2d\x00\x53\x00\x45\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4d\x00\x41\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x49\x00\x45\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x50\x00\x41\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x4d\x00\x43\x00\x00\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x42\x00\x41\x00\x2d\x00\x4c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x61\x00\x2d\x00\x4e\x00\x4f\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x54\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x5a\x00\x41\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x44\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x42\x00\x41\x00\x2d\x00\x43\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x61\x00\x2d\x00\x53\x00\x45\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4f\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x4a\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x56\x00\x45\x00\x00\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x73\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x59\x00\x45\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x43\x00\x42\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x43\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6e\x00\x2d\x00\x46\x00\x49\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x53\x00\x59\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x42\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x50\x00\x45\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4a\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x41\x00\x52\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4c\x00\x42\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x5a\x00\x57\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x45\x00\x43\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x4b\x00\x57\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x50\x00\x48\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x43\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x41\x00\x45\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x55\x00\x59\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x42\x00\x48\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x50\x00\x59\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x51\x00\x41\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x42\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x53\x00\x56\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x48\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x4e\x00\x49\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x50\x00\x52\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x43\x00\x48\x00\x54\x00\x00\x00\x00\x00\x73\x00\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x7d\x01\x80\x01\x00\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00\x58\x35\x01\x80\x01\x00\x00\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x50\x4e\x01\x80\x01\x00\x00\x00\x71\x00\x00\x00\x00\x00\x00\x00\xf0\x33\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x4e\x01\x80\x01\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x00\x00\x70\x4e\x01\x80\x01\x00\x00\x00\xda\x00\x00\x00\x00\x00\x00\x00\x80\x4e\x01\x80\x01\x00\x00\x00\xb1\x00\x00\x00\x00\x00\x00\x00\x90\x4e\x01\x80\x01\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\xa0\x4e\x01\x80\x01\x00\x00\x00\x8f\x00\x00\x00\x00\x00\x00\x00\xb0\x4e\x01\x80\x01\x00\x00\x00\xcf\x00\x00\x00\x00\x00\x00\x00\xc0\x4e\x01\x80\x01\x00\x00\x00\xd5\x00\x00\x00\x00\x00\x00\x00\xd0\x4e\x01\x80\x01\x00\x00\x00\xd2\x00\x00\x00\x00\x00\x00\x00\xe0\x4e\x01\x80\x01\x00\x00\x00\xa9\x00\x00\x00\x00\x00\x00\x00\xf0\x4e\x01\x80\x01\x00\x00\x00\xb9\x00\x00\x00\x00\x00\x00\x00\x00\x4f\x01\x80\x01\x00\x00\x00\xc4\x00\x00\x00\x00\x00\x00\x00\x10\x4f\x01\x80\x01\x00\x00\x00\xdc\x00\x00\x00\x00\x00\x00\x00\x20\x4f\x01\x80\x01\x00\x00\x00\x43\x00\x00\x00\x00\x00\x00\x00\x30\x4f\x01\x80\x01\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x00\x00\x40\x4f\x01\x80\x01\x00\x00\x00\xbf\x00\x00\x00\x00\x00\x00\x00\x50\x4f\x01\x80\x01\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00\x00\x40\x35\x01\x80\x01\x00\x00\x00\x29\x00\x00\x00\x00\x00\x00\x00\x60\x4f\x01\x80\x01\x00\x00\x00\x9b\x00\x00\x00\x00\x00\x00\x00\x78\x4f\x01\x80\x01\x00\x00\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x00\x35\x01\x80\x01\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x90\x4f\x01\x80\x01\x00\x00\x00\x63\x00\x00\x00\x00\x00\x00\x00\xf8\x33\x01\x80\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xa0\x4f\x01\x80\x01\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\xb0\x4f\x01\x80\x01\x00\x00\x00\x7d\x00\x00\x00\x00\x00\x00\x00\xc0\x4f\x01\x80\x01\x00\x00\x00\xb7\x00\x00\x00\x00\x00\x00\x00\x00\x34\x01\x80\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xd8\x4f\x01\x80\x01\x00\x00\x00\x45\x00\x00\x00\x00\x00\x00\x00\x18\x34\x01\x80\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\xe8\x4f\x01\x80\x01\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\xf8\x4f\x01\x80\x01\x00\x00\x00\x87\x00\x00\x00\x00\x00\x00\x00\x20\x34\x01\x80\x01\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x08\x50\x01\x80\x01\x00\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00\x28\x34\x01\x80\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x18\x50\x01\x80\x01\x00\x00\x00\xa2\x00\x00\x00\x00\x00\x00\x00\x28\x50\x01\x80\x01\x00\x00\x00\x91\x00\x00\x00\x00\x00\x00\x00\x38\x50\x01\x80\x01\x00\x00\x00\x49\x00\x00\x00\x00\x00\x00\x00\x48\x50\x01\x80\x01\x00\x00\x00\xb3\x00\x00\x00\x00\x00\x00\x00\x58\x50\x01\x80\x01\x00\x00\x00\xab\x00\x00\x00\x00\x00\x00\x00\x00\x36\x01\x80\x01\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x68\x50\x01\x80\x01\x00\x00\x00\x8b\x00\x00\x00\x00\x00\x00\x00\x30\x34\x01\x80\x01\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x78\x50\x01\x80\x01\x00\x00\x00\x4a\x00\x00\x00\x00\x00\x00\x00\x38\x34\x01\x80\x01\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x88\x50\x01\x80\x01\x00\x00\x00\xa3\x00\x00\x00\x00\x00\x00\x00\x98\x50\x01\x80\x01\x00\x00\x00\xcd\x00\x00\x00\x00\x00\x00\x00\xa8\x50\x01\x80\x01\x00\x00\x00\xac\x00\x00\x00\x00\x00\x00\x00\xb8\x50\x01\x80\x01\x00\x00\x00\xc9\x00\x00\x00\x00\x00\x00\x00\xc8\x50\x01\x80\x01\x00\x00\x00\x92\x00\x00\x00\x00\x00\x00\x00\xd8\x50\x01\x80\x01\x00\x00\x00\xba\x00\x00\x00\x00\x00\x00\x00\xe8\x50\x01\x80\x01\x00\x00\x00\xc5\x00\x00\x00\x00\x00\x00\x00\xf8\x50\x01\x80\x01\x00\x00\x00\xb4\x00\x00\x00\x00\x00\x00\x00\x08\x51\x01\x80\x01\x00\x00\x00\xd6\x00\x00\x00\x00\x00\x00\x00\x18\x51\x01\x80\x01\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x00\x00\x28\x51\x01\x80\x01\x00\x00\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x38\x51\x01\x80\x01\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x48\x51\x01\x80\x01\x00\x00\x00\xd3\x00\x00\x00\x00\x00\x00\x00\x40\x34\x01\x80\x01\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x58\x51\x01\x80\x01\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\x68\x51\x01\x80\x01\x00\x00\x00\xdd\x00\x00\x00\x00\x00\x00\x00\x78\x51\x01\x80\x01\x00\x00\x00\xd7\x00\x00\x00\x00\x00\x00\x00\x88\x51\x01\x80\x01\x00\x00\x00\xca\x00\x00\x00\x00\x00\x00\x00\x98\x51\x01\x80\x01\x00\x00\x00\xb5\x00\x00\x00\x00\x00\x00\x00\xa8\x51\x01\x80\x01\x00\x00\x00\xc1\x00\x00\x00\x00\x00\x00\x00\xb8\x51\x01\x80\x01\x00\x00\x00\xd4\x00\x00\x00\x00\x00\x00\x00\xc8\x51\x01\x80\x01\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x00\x00\xd8\x51\x01\x80\x01\x00\x00\x00\xad\x00\x00\x00\x00\x00\x00\x00\xe8\x51\x01\x80\x01\x00\x00\x00\xdf\x00\x00\x00\x00\x00\x00\x00\xf8\x51\x01\x80\x01\x00\x00\x00\x93\x00\x00\x00\x00\x00\x00\x00\x08\x52\x01\x80\x01\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00\x18\x52\x01\x80\x01\x00\x00\x00\xbb\x00\x00\x00\x00\x00\x00\x00\x28\x52\x01\x80\x01\x00\x00\x00\xce\x00\x00\x00\x00\x00\x00\x00\x38\x52\x01\x80\x01\x00\x00\x00\xe1\x00\x00\x00\x00\x00\x00\x00\x48\x52\x01\x80\x01\x00\x00\x00\xdb\x00\x00\x00\x00\x00\x00\x00\x58\x52\x01\x80\x01\x00\x00\x00\xde\x00\x00\x00\x00\x00\x00\x00\x68\x52\x01\x80\x01\x00\x00\x00\xd9\x00\x00\x00\x00\x00\x00\x00\x78\x52\x01\x80\x01\x00\x00\x00\xc6\x00\x00\x00\x00\x00\x00\x00\x10\x35\x01\x80\x01\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x88\x52\x01\x80\x01\x00\x00\x00\x65\x00\x00\x00\x00\x00\x00\x00\x48\x35\x01\x80\x01\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x98\x52\x01\x80\x01\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x28\x35\x01\x80\x01\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\xa8\x52\x01\x80\x01\x00\x00\x00\x68\x00\x00\x00\x00\x00\x00\x00\x48\x34\x01\x80\x01\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\xb8\x52\x01\x80\x01\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x68\x35\x01\x80\x01\x00\x00\x00\x2e\x00\x00\x00\x00\x00\x00\x00\xc8\x52\x01\x80\x01\x00\x00\x00\x73\x00\x00\x00\x00\x00\x00\x00\x50\x34\x01\x80\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\xd8\x52\x01\x80\x01\x00\x00\x00\x94\x00\x00\x00\x00\x00\x00\x00\xe8\x52\x01\x80\x01\x00\x00\x00\xa5\x00\x00\x00\x00\x00\x00\x00\xf8\x52\x01\x80\x01\x00\x00\x00\xae\x00\x00\x00\x00\x00\x00\x00\x08\x53\x01\x80\x01\x00\x00\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x18\x53\x01\x80\x01\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x00\x00\x28\x53\x01\x80\x01\x00\x00\x00\xbc\x00\x00\x00\x00\x00\x00\x00\xe8\x35\x01\x80\x01\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x38\x53\x01\x80\x01\x00\x00\x00\x88\x00\x00\x00\x00\x00\x00\x00\xb0\x35\x01\x80\x01\x00\x00\x00\x37\x00\x00\x00\x00\x00\x00\x00\x48\x53\x01\x80\x01\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x58\x34\x01\x80\x01\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x58\x53\x01\x80\x01\x00\x00\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x70\x35\x01\x80\x01\x00\x00\x00\x2f\x00\x00\x00\x00\x00\x00\x00\x68\x53\x01\x80\x01\x00\x00\x00\x74\x00\x00\x00\x00\x00\x00\x00\xb8\x34\x01\x80\x01\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x78\x53\x01\x80\x01\x00\x00\x00\xaf\x00\x00\x00\x00\x00\x00\x00\x88\x53\x01\x80\x01\x00\x00\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x60\x34\x01\x80\x01\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x98\x53\x01\x80\x01\x00\x00\x00\x4f\x00\x00\x00\x00\x00\x00\x00\x38\x35\x01\x80\x01\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\xa8\x53\x01\x80\x01\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00\x00\xf0\x34\x01\x80\x01\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\xb8\x53\x01\x80\x01\x00\x00\x00\x61\x00\x00\x00\x00\x00\x00\x00\x68\x34\x01\x80\x01\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\xc8\x53\x01\x80\x01\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x70\x34\x01\x80\x01\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\xd8\x53\x01\x80\x01\x00\x00\x00\x95\x00\x00\x00\x00\x00\x00\x00\xe8\x53\x01\x80\x01\x00\x00\x00\x51\x00\x00\x00\x00\x00\x00\x00\x78\x34\x01\x80\x01\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\xf8\x53\x01\x80\x01\x00\x00\x00\x52\x00\x00\x00\x00\x00\x00\x00\x60\x35\x01\x80\x01\x00\x00\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x08\x54\x01\x80\x01\x00\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00\x80\x35\x01\x80\x01\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x18\x54\x01\x80\x01\x00\x00\x00\x78\x00\x00\x00\x00\x00\x00\x00\xc8\x35\x01\x80\x01\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x00\x00\x28\x54\x01\x80\x01\x00\x00\x00\x82\x00\x00\x00\x00\x00\x00\x00\x80\x34\x01\x80\x01\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\xf0\x35\x01\x80\x01\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x38\x54\x01\x80\x01\x00\x00\x00\x89\x00\x00\x00\x00\x00\x00\x00\x48\x54\x01\x80\x01\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x88\x35\x01\x80\x01\x00\x00\x00\x32\x00\x00\x00\x00\x00\x00\x00\x58\x54\x01\x80\x01\x00\x00\x00\x79\x00\x00\x00\x00\x00\x00\x00\x20\x35\x01\x80\x01\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x68\x54\x01\x80\x01\x00\x00\x00\x67\x00\x00\x00\x00\x00\x00\x00\x18\x35\x01\x80\x01\x00\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x78\x54\x01\x80\x01\x00\x00\x00\x66\x00\x00\x00\x00\x00\x00\x00\x88\x54\x01\x80\x01\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x00\x00\x50\x35\x01\x80\x01\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x98\x54\x01\x80\x01\x00\x00\x00\x6d\x00\x00\x00\x00\x00\x00\x00\xa8\x54\x01\x80\x01\x00\x00\x00\x83\x00\x00\x00\x00\x00\x00\x00\xe0\x35\x01\x80\x01\x00\x00\x00\x3d\x00\x00\x00\x00\x00\x00\x00\xb8\x54\x01\x80\x01\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\xd0\x35\x01\x80\x01\x00\x00\x00\x3b\x00\x00\x00\x00\x00\x00\x00\xc8\x54\x01\x80\x01\x00\x00\x00\x84\x00\x00\x00\x00\x00\x00\x00\x78\x35\x01\x80\x01\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\xd8\x54\x01\x80\x01\x00\x00\x00\x9d\x00\x00\x00\x00\x00\x00\x00\xe8\x54\x01\x80\x01\x00\x00\x00\x77\x00\x00\x00\x00\x00\x00\x00\xf8\x54\x01\x80\x01\x00\x00\x00\x75\x00\x00\x00\x00\x00\x00\x00\x08\x55\x01\x80\x01\x00\x00\x00\x55\x00\x00\x00\x00\x00\x00\x00\x88\x34\x01\x80\x01\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x18\x55\x01\x80\x01\x00\x00\x00\x96\x00\x00\x00\x00\x00\x00\x00\x28\x55\x01\x80\x01\x00\x00\x00\x54\x00\x00\x00\x00\x00\x00\x00\x38\x55\x01\x80\x01\x00\x00\x00\x97\x00\x00\x00\x00\x00\x00\x00\x90\x34\x01\x80\x01\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x48\x55\x01\x80\x01\x00\x00\x00\x8d\x00\x00\x00\x00\x00\x00\x00\xa8\x35\x01\x80\x01\x00\x00\x00\x36\x00\x00\x00\x00\x00\x00\x00\x58\x55\x01\x80\x01\x00\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x98\x34\x01\x80\x01\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x68\x55\x01\x80\x01\x00\x00\x00\x56\x00\x00\x00\x00\x00\x00\x00\xa0\x34\x01\x80\x01\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x78\x55\x01\x80\x01\x00\x00\x00\x57\x00\x00\x00\x00\x00\x00\x00\x88\x55\x01\x80\x01\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x98\x55\x01\x80\x01\x00\x00\x00\x8c\x00\x00\x00\x00\x00\x00\x00\xa8\x55\x01\x80\x01\x00\x00\x00\x9f\x00\x00\x00\x00\x00\x00\x00\xb8\x55\x01\x80\x01\x00\x00\x00\xa8\x00\x00\x00\x00\x00\x00\x00\xa8\x34\x01\x80\x01\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\xc8\x55\x01\x80\x01\x00\x00\x00\x58\x00\x00\x00\x00\x00\x00\x00\xb0\x34\x01\x80\x01\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\xd8\x55\x01\x80\x01\x00\x00\x00\x59\x00\x00\x00\x00\x00\x00\x00\xd8\x35\x01\x80\x01\x00\x00\x00\x3c\x00\x00\x00\x00\x00\x00\x00\xe8\x55\x01\x80\x01\x00\x00\x00\x85\x00\x00\x00\x00\x00\x00\x00\xf8\x55\x01\x80\x01\x00\x00\x00\xa7\x00\x00\x00\x00\x00\x00\x00\x08\x56\x01\x80\x01\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x18\x56\x01\x80\x01\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x00\xc0\x34\x01\x80\x01\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x28\x56\x01\x80\x01\x00\x00\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x08\x35\x01\x80\x01\x00\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x38\x56\x01\x80\x01\x00\x00\x00\x64\x00\x00\x00\x00\x00\x00\x00\x48\x56\x01\x80\x01\x00\x00\x00\xbe\x00\x00\x00\x00\x00\x00\x00\x58\x56\x01\x80\x01\x00\x00\x00\xc3\x00\x00\x00\x00\x00\x00\x00\x68\x56\x01\x80\x01\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x00\x00\x78\x56\x01\x80\x01\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00\x88\x56\x01\x80\x01\x00\x00\x00\xcb\x00\x00\x00\x00\x00\x00\x00\x98\x56\x01\x80\x01\x00\x00\x00\xc7\x00\x00\x00\x00\x00\x00\x00\xc8\x34\x01\x80\x01\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\xa8\x56\x01\x80\x01\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x00\x40\x01\x80\x01\x00\x00\x00\xe3\x00\x00\x00\x00\x00\x00\x00\xb8\x56\x01\x80\x01\x00\x00\x00\xc2\x00\x00\x00\x00\x00\x00\x00\xd0\x56\x01\x80\x01\x00\x00\x00\xbd\x00\x00\x00\x00\x00\x00\x00\xe8\x56\x01\x80\x01\x00\x00\x00\xa6\x00\x00\x00\x00\x00\x00\x00\x00\x57\x01\x80\x01\x00\x00\x00\x99\x00\x00\x00\x00\x00\x00\x00\xd0\x34\x01\x80\x01\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x18\x57\x01\x80\x01\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x00\x00\x28\x57\x01\x80\x01\x00\x00\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x90\x35\x01\x80\x01\x00\x00\x00\x33\x00\x00\x00\x00\x00\x00\x00\x38\x57\x01\x80\x01\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x00\x00\xf8\x35\x01\x80\x01\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x48\x57\x01\x80\x01\x00\x00\x00\x8a\x00\x00\x00\x00\x00\x00\x00\xb8\x35\x01\x80\x01\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\x58\x57\x01\x80\x01\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\xc0\x35\x01\x80\x01\x00\x00\x00\x39\x00\x00\x00\x00\x00\x00\x00\x68\x57\x01\x80\x01\x00\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00\xd8\x34\x01\x80\x01\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x78\x57\x01\x80\x01\x00\x00\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x88\x57\x01\x80\x01\x00\x00\x00\x6e\x00\x00\x00\x00\x00\x00\x00\xe0\x34\x01\x80\x01\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x98\x57\x01\x80\x01\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\xa0\x35\x01\x80\x01\x00\x00\x00\x35\x00\x00\x00\x00\x00\x00\x00\xa8\x57\x01\x80\x01\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x00\x00\xf8\x34\x01\x80\x01\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\xb8\x57\x01\x80\x01\x00\x00\x00\x62\x00\x00\x00\x00\x00\x00\x00\xe8\x34\x01\x80\x01\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\xc8\x57\x01\x80\x01\x00\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x98\x35\x01\x80\x01\x00\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\xd8\x57\x01\x80\x01\x00\x00\x00\x9e\x00\x00\x00\x00\x00\x00\x00\xf0\x57\x01\x80\x01\x00\x00\x00\x7b\x00\x00\x00\x00\x00\x00\x00\x30\x35\x01\x80\x01\x00\x00\x00\x27\x00\x00\x00\x00\x00\x00\x00\x08\x58\x01\x80\x01\x00\x00\x00\x69\x00\x00\x00\x00\x00\x00\x00\x18\x58\x01\x80\x01\x00\x00\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x28\x58\x01\x80\x01\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x38\x58\x01\x80\x01\x00\x00\x00\xe2\x00\x00\x00\x00\x00\x00\x00\x48\x58\x01\x80\x01\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x58\x58\x01\x80\x01\x00\x00\x00\xa1\x00\x00\x00\x00\x00\x00\x00\x68\x58\x01\x80\x01\x00\x00\x00\xb2\x00\x00\x00\x00\x00\x00\x00\x78\x58\x01\x80\x01\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x00\x00\x88\x58\x01\x80\x01\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x98\x58\x01\x80\x01\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x61\x00\x66\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x61\x00\x65\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x62\x00\x68\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x64\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x65\x00\x67\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x69\x00\x71\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6a\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6b\x00\x77\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6c\x00\x62\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6c\x00\x79\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6d\x00\x61\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x6f\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x71\x00\x61\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x73\x00\x61\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x73\x00\x79\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x61\x00\x72\x00\x2d\x00\x79\x00\x65\x00\x00\x00\x00\x00\x00\x00\x61\x00\x7a\x00\x2d\x00\x61\x00\x7a\x00\x2d\x00\x63\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x61\x00\x7a\x00\x2d\x00\x61\x00\x7a\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x62\x00\x65\x00\x2d\x00\x62\x00\x79\x00\x00\x00\x00\x00\x00\x00\x62\x00\x67\x00\x2d\x00\x62\x00\x67\x00\x00\x00\x00\x00\x00\x00\x62\x00\x6e\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x62\x00\x73\x00\x2d\x00\x62\x00\x61\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x63\x00\x61\x00\x2d\x00\x65\x00\x73\x00\x00\x00\x00\x00\x00\x00\x63\x00\x73\x00\x2d\x00\x63\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x63\x00\x79\x00\x2d\x00\x67\x00\x62\x00\x00\x00\x00\x00\x00\x00\x64\x00\x61\x00\x2d\x00\x64\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x61\x00\x74\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x63\x00\x68\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x64\x00\x65\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x6c\x00\x69\x00\x00\x00\x00\x00\x00\x00\x64\x00\x65\x00\x2d\x00\x6c\x00\x75\x00\x00\x00\x00\x00\x00\x00\x64\x00\x69\x00\x76\x00\x2d\x00\x6d\x00\x76\x00\x00\x00\x00\x00\x65\x00\x6c\x00\x2d\x00\x67\x00\x72\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x61\x00\x75\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x62\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x63\x00\x61\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x63\x00\x62\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x67\x00\x62\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x69\x00\x65\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x6a\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x6e\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x70\x00\x68\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x74\x00\x74\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x75\x00\x73\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x00\x00\x00\x00\x65\x00\x6e\x00\x2d\x00\x7a\x00\x77\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x61\x00\x72\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x62\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x63\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x63\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x63\x00\x72\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x64\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x65\x00\x63\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x65\x00\x73\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x67\x00\x74\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x68\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x6d\x00\x78\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x6e\x00\x69\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x70\x00\x61\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x70\x00\x65\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x70\x00\x72\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x70\x00\x79\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x73\x00\x76\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x75\x00\x79\x00\x00\x00\x00\x00\x00\x00\x65\x00\x73\x00\x2d\x00\x76\x00\x65\x00\x00\x00\x00\x00\x00\x00\x65\x00\x74\x00\x2d\x00\x65\x00\x65\x00\x00\x00\x00\x00\x00\x00\x65\x00\x75\x00\x2d\x00\x65\x00\x73\x00\x00\x00\x00\x00\x00\x00\x66\x00\x61\x00\x2d\x00\x69\x00\x72\x00\x00\x00\x00\x00\x00\x00\x66\x00\x69\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x00\x00\x00\x00\x66\x00\x6f\x00\x2d\x00\x66\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x62\x00\x65\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x63\x00\x61\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x63\x00\x68\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x66\x00\x72\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x6c\x00\x75\x00\x00\x00\x00\x00\x00\x00\x66\x00\x72\x00\x2d\x00\x6d\x00\x63\x00\x00\x00\x00\x00\x00\x00\x67\x00\x6c\x00\x2d\x00\x65\x00\x73\x00\x00\x00\x00\x00\x00\x00\x67\x00\x75\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x68\x00\x65\x00\x2d\x00\x69\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x68\x00\x69\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x68\x00\x72\x00\x2d\x00\x62\x00\x61\x00\x00\x00\x00\x00\x00\x00\x68\x00\x72\x00\x2d\x00\x68\x00\x72\x00\x00\x00\x00\x00\x00\x00\x68\x00\x75\x00\x2d\x00\x68\x00\x75\x00\x00\x00\x00\x00\x00\x00\x68\x00\x79\x00\x2d\x00\x61\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x69\x00\x64\x00\x2d\x00\x69\x00\x64\x00\x00\x00\x00\x00\x00\x00\x69\x00\x73\x00\x2d\x00\x69\x00\x73\x00\x00\x00\x00\x00\x00\x00\x69\x00\x74\x00\x2d\x00\x63\x00\x68\x00\x00\x00\x00\x00\x00\x00\x69\x00\x74\x00\x2d\x00\x69\x00\x74\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x61\x00\x2d\x00\x6a\x00\x70\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x61\x00\x2d\x00\x67\x00\x65\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6b\x00\x2d\x00\x6b\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6e\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x6b\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x6b\x00\x6f\x00\x2d\x00\x6b\x00\x72\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x79\x00\x2d\x00\x6b\x00\x67\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x74\x00\x2d\x00\x6c\x00\x74\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x76\x00\x2d\x00\x6c\x00\x76\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x69\x00\x2d\x00\x6e\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6b\x00\x2d\x00\x6d\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6c\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x6e\x00\x2d\x00\x6d\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x72\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x73\x00\x2d\x00\x62\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x73\x00\x2d\x00\x6d\x00\x79\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x74\x00\x2d\x00\x6d\x00\x74\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x62\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x6c\x00\x2d\x00\x62\x00\x65\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x6c\x00\x2d\x00\x6e\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x6e\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x73\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x00\x00\x00\x00\x70\x00\x61\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x70\x00\x6c\x00\x2d\x00\x70\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x70\x00\x74\x00\x2d\x00\x62\x00\x72\x00\x00\x00\x00\x00\x00\x00\x70\x00\x74\x00\x2d\x00\x70\x00\x74\x00\x00\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x62\x00\x6f\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x65\x00\x63\x00\x00\x00\x00\x00\x71\x00\x75\x00\x7a\x00\x2d\x00\x70\x00\x65\x00\x00\x00\x00\x00\x72\x00\x6f\x00\x2d\x00\x72\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x72\x00\x75\x00\x2d\x00\x72\x00\x75\x00\x00\x00\x00\x00\x00\x00\x73\x00\x61\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x00\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x73\x00\x65\x00\x2d\x00\x73\x00\x65\x00\x00\x00\x00\x00\x00\x00\x73\x00\x6b\x00\x2d\x00\x73\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x73\x00\x6c\x00\x2d\x00\x73\x00\x69\x00\x00\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x61\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x61\x00\x2d\x00\x73\x00\x65\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6a\x00\x2d\x00\x6e\x00\x6f\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6a\x00\x2d\x00\x73\x00\x65\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x6e\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x73\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x00\x00\x73\x00\x71\x00\x2d\x00\x61\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x62\x00\x61\x00\x2d\x00\x63\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x62\x00\x61\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x73\x00\x70\x00\x2d\x00\x63\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x73\x00\x72\x00\x2d\x00\x73\x00\x70\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x73\x00\x76\x00\x2d\x00\x66\x00\x69\x00\x00\x00\x00\x00\x00\x00\x73\x00\x76\x00\x2d\x00\x73\x00\x65\x00\x00\x00\x00\x00\x00\x00\x73\x00\x77\x00\x2d\x00\x6b\x00\x65\x00\x00\x00\x00\x00\x00\x00\x73\x00\x79\x00\x72\x00\x2d\x00\x73\x00\x79\x00\x00\x00\x00\x00\x74\x00\x61\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x74\x00\x65\x00\x2d\x00\x69\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x74\x00\x68\x00\x2d\x00\x74\x00\x68\x00\x00\x00\x00\x00\x00\x00\x74\x00\x6e\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x00\x00\x00\x00\x74\x00\x72\x00\x2d\x00\x74\x00\x72\x00\x00\x00\x00\x00\x00\x00\x74\x00\x74\x00\x2d\x00\x72\x00\x75\x00\x00\x00\x00\x00\x00\x00\x75\x00\x6b\x00\x2d\x00\x75\x00\x61\x00\x00\x00\x00\x00\x00\x00\x75\x00\x72\x00\x2d\x00\x70\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x75\x00\x7a\x00\x2d\x00\x75\x00\x7a\x00\x2d\x00\x63\x00\x79\x00\x72\x00\x6c\x00\x00\x00\x00\x00\x75\x00\x7a\x00\x2d\x00\x75\x00\x7a\x00\x2d\x00\x6c\x00\x61\x00\x74\x00\x6e\x00\x00\x00\x00\x00\x76\x00\x69\x00\x2d\x00\x76\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x78\x00\x68\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x63\x00\x68\x00\x73\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x63\x00\x68\x00\x74\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x63\x00\x6e\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x68\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x6d\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x73\x00\x67\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x68\x00\x2d\x00\x74\x00\x77\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x75\x00\x2d\x00\x7a\x00\x61\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0b\x54\x02\x00\x00\x00\x00\x00\x10\x63\x2d\x5e\xc7\x6b\x05\x00\x00\x00\x00\x00\x00\x40\xea\xed\x74\x46\xd0\x9c\x2c\x9f\x0c\x00\x00\x00\x00\x61\xf5\xb9\xab\xbf\xa4\x5c\xc3\xf1\x29\x63\x1d\x00\x00\x00\x00\x00\x64\xb5\xfd\x34\x05\xc4\xd2\x87\x66\x92\xf9\x15\x3b\x6c\x44\x00\x00\x00\x00\x00\x00\x10\xd9\x90\x65\x94\x2c\x42\x62\xd7\x01\x45\x22\x9a\x17\x26\x27\x4f\x9f\x00\x00\x00\x40\x02\x95\x07\xc1\x89\x56\x24\x1c\xa7\xfa\xc5\x67\x6d\xc8\x73\xdc\x6d\xad\xeb\x72\x01\x00\x00\x00\x00\xc1\xce\x64\x27\xa2\x63\xca\x18\xa4\xef\x25\x7b\xd1\xcd\x70\xef\xdf\x6b\x1f\x3e\xea\x9d\x5f\x03\x00\x00\x00\x00\x00\xe4\x6e\xfe\xc3\xcd\x6a\x0c\xbc\x66\x32\x1f\x39\x2e\x03\x02\x45\x5a\x25\xf8\xd2\x71\x56\x4a\xc2\xc3\xda\x07\x00\x00\x10\x8f\x2e\xa8\x08\x43\xb2\xaa\x7c\x1a\x21\x8e\x40\xce\x8a\xf3\x0b\xce\xc4\x84\x27\x0b\xeb\x7c\xc3\x94\x25\xad\x49\x12\x00\x00\x00\x40\x1a\xdd\xda\x54\x9f\xcc\xbf\x61\x59\xdc\xab\xab\x5c\xc7\x0c\x44\x05\xf5\x67\x16\xbc\xd1\x52\xaf\xb7\xfb\x29\x8d\x8f\x60\x94\x2a\x00\x00\x00\x00\x00\x21\x0c\x8a\xbb\x17\xa4\x8e\xaf\x56\xa9\x9f\x47\x06\x36\xb2\x4b\x5d\xe0\x5f\xdc\x80\x0a\xaa\xfe\xf0\x40\xd9\x8e\xa8\xd0\x80\x1a\x6b\x23\x63\x00\x00\x64\x38\x4c\x32\x96\xc7\x57\x83\xd5\x42\x4a\xe4\x61\x22\xa9\xd9\x3d\x10\x3c\xbd\x72\xf3\xe5\x91\x74\x15\x59\xc0\x0d\xa6\x1d\xec\x6c\xd9\x2a\x10\xd3\xe6\x00\x00\x00\x10\x85\x1e\x5b\x61\x4f\x6e\x69\x2a\x7b\x18\x1c\xe2\x50\x04\x2b\x34\xdd\x2f\xee\x27\x50\x63\x99\x71\xc9\xa6\x16\xe9\x4a\x8e\x28\x2e\x08\x17\x6f\x6e\x49\x1a\x6e\x19\x02\x00\x00\x00\x40\x32\x26\x40\xad\x04\x50\x72\x1e\xf9\xd5\xd1\x94\x29\xbb\xcd\x5b\x66\x96\x2e\x3b\xa2\xdb\x7d\xfa\x65\xac\x53\xde\x77\x9b\xa2\x20\xb0\x53\xf9\xbf\xc6\xab\x25\x94\x4b\x4d\xe3\x04\x00\x81\x2d\xc3\xfb\xf4\xd0\x22\x52\x50\x28\x0f\xb7\xf3\xf2\x13\x57\x13\x14\x42\xdc\x7d\x5d\x39\xd6\x99\x19\x59\xf8\x1c\x38\x92\x00\xd6\x14\xb3\x86\xb9\x77\xa5\x7a\x61\xfe\xb7\x12\x6a\x61\x0b\x00\x00\xe4\x11\x1d\x8d\x67\xc3\x56\x20\x1f\x94\x3a\x8b\x36\x09\x9b\x08\x69\x70\xbd\xbe\x65\x76\x20\xeb\xc4\x26\x9b\x9d\xe8\x67\x15\x6e\x09\x15\x9d\x2b\xf2\x32\x71\x13\x51\x48\xbe\xce\xa2\xe5\x45\x52\x7f\x1a\x00\x00\x00\x10\xbb\x78\x94\xf7\x02\xc0\x74\x1b\x8c\x00\x5d\xf0\xb0\x75\xc6\xdb\xa9\x14\xb9\xd9\xe2\xdf\x72\x0f\x65\x4c\x4b\x28\x77\x16\xe0\xf6\x6d\xc2\x91\x43\x51\xcf\xc9\x95\x27\x55\xab\xe2\xd6\x27\xe6\xa8\x9c\xa6\xb1\x3d\x00\x00\x00\x00\x40\x4a\xd0\xec\xf4\xf0\x88\x23\x7f\xc5\x6d\x0a\x58\x6f\x04\xbf\x43\xc3\x5d\x2d\xf8\x48\x08\x11\xee\x1c\x59\xa0\xfa\x28\xf0\xf4\xcd\x3f\xa5\x2e\x19\xa0\x71\xd6\xbc\x87\x44\x69\x7d\x01\x6e\xf9\x10\x9d\x56\x1a\x79\x75\xa4\x8f\x00\x00\xe1\xb2\xb9\x3c\x75\x88\x82\x93\x16\x3f\xcd\x6b\x3a\xb4\x89\xde\x87\x9e\x08\x46\x45\x4d\x68\x0c\xa6\xdb\xfd\x91\x93\x24\xdf\x13\xec\x68\x30\x27\x44\xb4\x99\xee\x41\x81\xb6\xc3\xca\x02\x58\xf1\x51\x68\xd9\xa2\x25\x76\x7d\x8d\x71\x4e\x01\x00\x00\x64\xfb\xe6\x83\x5a\xf2\x0f\xad\x57\x94\x11\xb5\x80\x00\x66\xb5\x29\x20\xcf\xd2\xc5\xd7\x7d\x6d\x3f\xa5\x1c\x4d\xb7\xcd\xde\x70\x9d\xda\x3d\x41\x16\xb7\x4e\xca\xd0\x71\x98\x13\xe4\xd7\x90\x3a\x40\x4f\xe2\x3f\xab\xf9\x6f\x77\x4d\x26\xe6\xaf\x0a\x03\x00\x00\x00\x10\x31\x55\xab\x09\xd2\x58\x0c\xa6\xcb\x26\x61\x56\x87\x83\x1c\x6a\xc1\xf4\x87\x75\x76\xe8\x44\x2c\xcf\x47\xa0\x41\x9e\x05\x08\xc9\x3e\x06\xba\xa0\xe8\xc8\xcf\xe7\x55\xc0\xfa\xe1\xb2\x44\x01\xef\xb0\x7e\x20\x24\x73\x25\x72\xd1\x81\xf9\xb8\xe4\xae\x05\x15\x07\x40\x62\x3b\x7a\x4f\x5d\xa4\xce\x33\x41\xe2\x4f\x6d\x6d\x0f\x21\xf2\x33\x56\xe5\x56\x13\xc1\x25\x97\xd7\xeb\x28\x84\xeb\x96\xd3\x77\x3b\x49\x1e\xae\x2d\x1f\x47\x20\x38\xad\x96\xd1\xce\xfa\x8a\xdb\xcd\xde\x4e\x86\xc0\x68\x55\xa1\x5d\x69\xb2\x89\x3c\x12\x24\x71\x45\x7d\x10\x00\x00\x41\x1c\x27\x4a\x17\x6e\x57\xae\x62\xec\xaa\x89\x22\xef\xdd\xfb\xa2\xb6\xe4\xef\xe1\x17\xf2\xbd\x66\x33\x80\x88\xb4\x37\x3e\x2c\xb8\xbf\x91\xde\xac\x19\x08\x64\xf4\xd4\x4e\x6a\xff\x35\x0e\x6a\x56\x67\x14\xb9\xdb\x40\xca\x3b\x2a\x78\x68\x9b\x32\x6b\xd9\xc5\xaf\xf5\xbc\x69\x64\x26\x00\x00\x00\xe4\xf4\x5f\x80\xfb\xaf\xd1\x55\xed\xa8\x20\x4a\x9b\xf8\x57\x97\xab\x0a\xfe\xae\x01\x7b\xa6\x2c\x4a\x69\x95\xbf\x1e\x29\x1c\xc4\xc7\xaa\xd2\xd5\xd8\x76\xc7\x36\xd1\x0c\x55\xda\x93\x90\x9d\xc7\x9a\xa8\xcb\x4b\x25\x18\x76\xf0\x0d\x09\x88\xa8\xf7\x74\x10\x1f\x3a\xfc\x11\x48\xe5\xad\x8e\x63\x59\x10\xe7\xcb\x97\xe8\x69\xd7\x26\x3e\x72\xe4\xb4\x86\xaa\x90\x5b\x22\x39\x33\x9c\x75\x07\x7a\x4b\x91\xe9\x47\x2d\x77\xf9\x6e\x9a\xe7\x40\x0b\x16\xc4\xf8\x92\x0c\x10\xf0\x5f\xf2\x11\x6c\xc3\x25\x42\x8b\xf9\xc9\x9d\x91\x0b\x73\xaf\x7c\xff\x05\x85\x2d\x43\xb0\x69\x75\x2b\x2d\x2c\x84\x57\xa6\x10\xef\x1f\xd0\x00\x40\x7a\xc7\xe5\x62\xb8\xe8\x6a\x88\xd8\x10\xe5\x98\xcd\xc8\xc5\x55\x89\x10\x55\xb6\x59\xd0\xd4\xbe\xfb\x58\x31\x82\xb8\x03\x19\x45\x4c\x03\x39\xc9\x4d\x19\xac\x00\xc5\x1f\xe2\xc0\x4c\x79\xa1\x80\xc9\x3b\xd1\x2d\xb1\xe9\xf8\x22\x6d\x5e\x9a\x89\x38\x7b\xd8\x19\x79\xce\x72\x76\xc6\x78\x9f\xb9\xe5\x79\x4e\x03\x94\xe4\x01\x00\x00\x00\x00\x00\x00\xa1\xe9\xd4\x5c\x6c\x6f\x7d\xe4\x9b\xe7\xd9\x3b\xf9\xa1\x6f\x62\x77\x51\x34\x8b\xc6\xe8\x59\x2b\xde\x58\xde\x3c\xcf\x58\xff\x46\x22\x15\x7c\x57\xa8\x59\x75\xe7\x26\x53\x67\x77\x17\x63\xb7\xe6\xeb\x5f\x0a\xfd\xe3\x69\x39\xe8\x33\x35\xa0\x05\xa8\x87\xb9\x31\xf6\x43\x0f\x1f\x21\xdb\x43\x5a\xd8\x96\xf5\x1b\xab\xa2\x19\x3f\x68\x04\x00\x00\x00\x64\xfe\x7d\xbe\x2f\x04\xc9\x4b\xb0\xed\xf5\xe1\xda\x4e\xa1\x8f\x73\xdb\x09\xe4\x9c\xee\x4f\x67\x0d\x9f\x15\xa9\xd6\xb5\xb5\xf6\x0e\x96\x38\x73\x91\xc2\x49\xeb\xcc\x97\x2b\x5f\x95\x3f\x38\x0f\xf6\xb3\x91\x20\x14\x37\x78\xd1\xdf\x42\xd1\xc1\xde\x22\x3e\x15\x57\xdf\xaf\x8a\x5f\xe5\xf5\x77\x8b\xca\xe7\xa3\x5b\x52\x2f\x03\x3d\x4f\xe7\x42\x0a\x00\x00\x00\x00\x10\xdd\xf4\x52\x09\x45\x5d\xe1\x42\xb4\xae\x2e\x34\xb3\xa3\x6f\xa3\xcd\x3f\x6e\x7a\x28\xb4\xf7\x77\xc1\x4b\xd0\xc8\xd2\x67\xe0\xf8\xa8\xae\x67\x3b\xc9\xad\xb3\x56\xc8\x6c\x0b\x9d\x9d\x95\x00\xc1\x48\x5b\x3d\x8a\xbe\x4a\xf4\x36\xd9\x52\x4d\xe8\xdb\x71\xc5\x21\x1c\xf9\x09\x81\x45\x4a\x6a\xd8\xaa\xd7\x7c\x4c\xe1\x08\x9c\xa5\x9b\x75\x00\x88\x3c\xe4\x17\x00\x00\x00\x00\x00\x40\x92\xd4\x10\xf1\x04\xbe\x72\x64\x18\x0c\xc1\x36\x87\xfb\xab\x78\x14\x29\xaf\x51\xfc\x39\x97\xeb\x25\x15\x30\x2b\x4c\x0b\x0e\x03\xa1\x3b\x3c\xfe\x28\xba\xfc\x88\x77\x58\x43\x9e\xb8\xa4\xe4\x3d\x73\xc2\xf2\x46\x7c\x98\x62\x74\x8f\x0f\x21\x19\xdb\xae\xb6\xa3\x2e\xb2\x14\x50\xaa\x8d\xab\x39\xea\x42\x34\x96\x97\xa9\xdf\xdf\x01\xfe\xd3\xf3\xd2\x80\x02\x79\xa0\x37\x00\x00\x00\x01\x9b\x9c\x50\xf1\xad\xdc\xc7\x2c\xad\x3d\x38\x37\x4d\xc6\x73\xd0\x67\x6d\xea\x06\xa8\x9b\x51\xf8\xf2\x03\xc4\xa2\xe1\x52\xa0\x3a\x23\x10\xd7\xa9\x73\x85\x44\xba\xd9\x12\xcf\x03\x18\x87\x70\x9b\x3a\xdc\x52\xe8\x52\xb2\xe5\x4e\xfb\x17\x07\x2f\xa6\x4d\xbe\xe1\xd7\xab\x0a\x4f\xed\x62\x8c\x7b\xec\xb9\xce\x21\x40\x66\xd4\x00\x83\x15\xa1\xe6\x75\xe3\xcc\xf2\x29\x2f\x84\x81\x00\x00\x00\x00\xe4\x17\x77\x64\xfb\xf5\xd3\x71\x3d\x76\xa0\xe9\x2f\x14\x7d\x66\x4c\xf4\x33\x2e\xf1\xb8\xf3\x8e\x0d\x0f\x13\x69\x94\x4c\x73\xa8\x0f\x26\x60\x40\x13\x01\x3c\x0a\x88\x71\xcc\x21\x2d\xa5\x37\xef\xc9\xda\x8a\xb4\x31\xbb\x42\x41\x4c\xf9\xd6\x6c\x05\x8b\xc8\xb8\x01\x05\xe2\x7c\xed\x97\x52\xc4\x61\xc3\x62\xaa\xd8\xda\x87\xde\xea\x33\xb8\x61\x68\xf0\x94\xbd\x9a\xcc\x13\x6a\xd5\xc1\x8d\x2d\x01\x00\x00\x00\x00\x10\x13\xe8\x36\x7a\xc6\x9e\x29\x16\xf4\x0a\x3f\x49\xf3\xcf\xa6\xa5\x77\xa3\x23\xbe\xa4\x82\x5b\xa2\xcc\x2f\x72\x10\x35\x7f\x44\x9d\xbe\xb8\x13\xc2\xa8\x4e\x32\x4c\xc9\xad\x33\x9e\xbc\xba\xfe\xac\x76\x32\x21\x4c\x2e\x32\xcd\x13\x3e\xb4\x91\xfe\x70\x36\xd9\x5c\xbb\x85\x97\x14\x42\xfd\x1a\xcc\x46\xf8\xdd\x38\xe6\xd2\x87\x07\x69\x17\xd1\x02\x1a\xfe\xf1\xb5\x3e\xae\xab\xb9\xc3\x6f\xee\x08\x1c\xbe\x02\x00\x00\x00\x00\x00\x40\xaa\xc2\x40\x81\xd9\x77\xf8\x2c\x3d\xd7\xe1\x71\x98\x2f\xe7\xd5\x09\x63\x51\x72\xdd\x19\xa8\xaf\x46\x5a\x2a\xd6\xce\xdc\x02\x2a\xfe\xdd\x46\xce\x8d\x24\x13\x27\xad\xd2\x23\xb7\x19\xbb\x04\xc4\x2b\xcc\x06\xb7\xca\xeb\xb1\x47\xdc\x4b\x09\x9d\xca\x02\xdc\xc5\x8e\x51\xe6\x31\x80\x56\xc3\x8e\xa8\x58\x2f\x34\x42\x1e\x04\x8b\x14\xe5\xbf\xfe\x13\xfc\xff\x05\x0f\x79\x63\x67\xfd\x36\xd5\x66\x76\x50\xe1\xb9\x62\x06\x00\x00\x00\x61\xb0\x67\x1a\x0a\x01\xd2\xc0\xe1\x05\xd0\x3b\x73\x12\xdb\x3f\x2e\x9f\xa3\xe2\x9d\xb2\x61\xe2\xdc\x63\x2a\xbc\x04\x26\x94\x9b\xd5\x70\x61\x96\x25\xe3\xc2\xb9\x75\x0b\x14\x21\x2c\x1d\x1f\x60\x6a\x13\xb8\xa2\x3b\xd2\x89\x73\x7d\xf1\x60\xdf\xd7\xca\xc6\x2b\xdf\x69\x06\x37\x87\xb8\x24\xed\x06\x93\x66\xeb\x6e\x49\x19\x6f\xdb\x8d\x93\x75\x82\x74\x5e\x36\x9a\x6e\xc5\x31\xb7\x90\x36\xc5\x42\x28\xc8\x8e\x79\xae\x24\xde\x0e\x00\x00\x00\x00\x64\x41\xc1\x9a\x88\xd5\x99\x2c\x43\xd9\x1a\xe7\x80\xa2\x2e\x3d\xf6\x6b\x3d\x79\x49\x82\x43\xa9\xe7\x79\x4a\xe6\xfd\x22\x9a\x70\xd6\xe0\xef\xcf\xca\x05\xd7\xa4\x8d\xbd\x6c\x00\x64\xe3\xb3\xdc\x4e\xa5\x6e\x08\xa8\xa1\x9e\x45\x8f\x74\xc8\x54\x8e\xfc\x57\xc6\x74\xcc\xd4\xc3\xb8\x42\x6e\x63\xd9\x57\xcc\x5b\xb5\x35\xe9\xfe\x13\x6c\x61\x51\xc4\x1a\xdb\xba\x95\xb5\x9d\x4e\xf1\xa1\x50\xe7\xf9\xdc\x71\x7f\x63\x07\x2b\x9f\x2f\xde\x9d\x22\x00\x00\x00\x00\x00\x10\x89\xbd\x5e\x3c\x56\x37\x77\xe3\x38\xa3\xcb\x3d\x4f\x9e\xd2\x81\x2c\x9e\xf7\xa4\x74\xc7\xf9\xc3\x97\xe7\x1c\x6a\x38\xe4\x5f\xac\x9c\x8b\xf3\x07\xfa\xec\x88\xd5\xac\xc1\x5a\x3e\xce\xcc\xaf\x85\x70\x3f\x1f\x9d\xd3\x6d\x2d\xe8\x0c\x18\x7d\x17\x6f\x94\x69\x5e\xe1\x2c\x8e\x64\x48\x39\xa1\x95\x11\xe0\x0f\x34\x58\x3c\x17\xb4\x94\xf6\x48\x27\xbd\x57\x26\x7c\x2e\xda\x8b\x75\xa0\x90\x80\x3b\x13\xb6\xdb\x2d\x90\x48\xcf\x6d\x7e\x04\xe4\x24\x99\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x00\x00\x03\x05\x00\x00\x04\x09\x00\x01\x04\x0d\x00\x01\x05\x12\x00\x01\x06\x18\x00\x02\x06\x1e\x00\x02\x07\x25\x00\x02\x08\x2d\x00\x03\x08\x35\x00\x03\x09\x3e\x00\x03\x0a\x48\x00\x04\x0a\x52\x00\x04\x0b\x5d\x00\x04\x0c\x69\x00\x05\x0c\x75\x00\x05\x0d\x82\x00\x05\x0e\x90\x00\x05\x0f\x9f\x00\x06\x0f\xae\x00\x06\x10\xbe\x00\x06\x11\xcf\x00\x07\x11\xe0\x00\x07\x12\xf2\x00\x07\x13\x05\x01\x08\x13\x18\x01\x08\x15\x2d\x01\x08\x16\x43\x01\x09\x16\x59\x01\x09\x17\x70\x01\x09\x18\x88\x01\x0a\x18\xa0\x01\x0a\x19\xb9\x01\x0a\x1a\xd3\x01\x0a\x1b\xee\x01\x0b\x1b\x09\x02\x0b\x1c\x25\x02\x0b\x1d\x0a\x00\x00\x00\x64\x00\x00\x00\xe8\x03\x00\x00\x10\x27\x00\x00\xa0\x86\x01\x00\x40\x42\x0f\x00\x80\x96\x98\x00\x00\xe1\xf5\x05\x00\xca\x9a\x3b\x30\x00\x00\x00\x31\x23\x49\x4e\x46\x00\x00\x00\x31\x23\x51\x4e\x41\x4e\x00\x00\x31\x23\x53\x4e\x41\x4e\x00\x00\x31\x23\x49\x4e\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\xe5\x26\x15\x7b\xcb\xdb\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x78\xcb\xdb\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x35\x95\x71\x28\x37\xa9\xa8\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x13\x44\xd3\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x25\x3e\x62\xde\x3f\xef\x03\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x55\x55\x55\x55\x55\x55\xd5\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x99\x99\x99\x99\x99\xc9\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x55\x55\x55\x55\x55\x55\xc5\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x8f\xc0\x00\x00\x00\x00\x00\x00\x00\x00\xfd\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x54\x55\x55\x55\x55\xb5\x3f\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xc6\xba\x99\x99\x99\x89\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x51\xf1\x07\x23\x49\x62\x3f\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x5d\xc8\x34\x80\x3c\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x43\x00\x4f\x00\x4e\x00\x4f\x00\x55\x00\x54\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x9e\xbd\x5b\x3f\x00\x00\x00\x70\xd4\xaf\x6b\x3f\x00\x00\x00\x60\x95\xb9\x74\x3f\x00\x00\x00\xa0\x76\x94\x7b\x3f\x00\x00\x00\xa0\x4d\x34\x81\x3f\x00\x00\x00\x50\x08\x9b\x84\x3f\x00\x00\x00\xc0\x71\xfe\x87\x3f\x00\x00\x00\x80\x90\x5e\x8b\x3f\x00\x00\x00\xf0\x6a\xbb\x8e\x3f\x00\x00\x00\xa0\x83\x0a\x91\x3f\x00\x00\x00\xe0\xb5\xb5\x92\x3f\x00\x00\x00\x50\x4f\x5f\x94\x3f\x00\x00\x00\x00\x53\x07\x96\x3f\x00\x00\x00\xd0\xc3\xad\x97\x3f\x00\x00\x00\xf0\xa4\x52\x99\x3f\x00\x00\x00\x20\xf9\xf5\x9a\x3f\x00\x00\x00\x70\xc3\x97\x9c\x3f\x00\x00\x00\xa0\x06\x38\x9e\x3f\x00\x00\x00\xb0\xc5\xd6\x9f\x3f\x00\x00\x00\xa0\x01\xba\xa0\x3f\x00\x00\x00\x20\xe1\x87\xa1\x3f\x00\x00\x00\xc0\x02\x55\xa2\x3f\x00\x00\x00\xc0\x67\x21\xa3\x3f\x00\x00\x00\x90\x11\xed\xa3\x3f\x00\x00\x00\x80\x01\xb8\xa4\x3f\x00\x00\x00\xe0\x38\x82\xa5\x3f\x00\x00\x00\x10\xb9\x4b\xa6\x3f\x00\x00\x00\x40\x83\x14\xa7\x3f\x00\x00\x00\xc0\x98\xdc\xa7\x3f\x00\x00\x00\xd0\xfa\xa3\xa8\x3f\x00\x00\x00\xc0\xaa\x6a\xa9\x3f\x00\x00\x00\xd0\xa9\x30\xaa\x3f\x00\x00\x00\x20\xf9\xf5\xaa\x3f\x00\x00\x00\x00\x9a\xba\xab\x3f\x00\x00\x00\x90\x8d\x7e\xac\x3f\x00\x00\x00\x10\xd5\x41\xad\x3f\x00\x00\x00\xa0\x71\x04\xae\x3f\x00\x00\x00\x70\x64\xc6\xae\x3f\x00\x00\x00\xb0\xae\x87\xaf\x3f\x00\x00\x00\xc0\x28\x24\xb0\x3f\x00\x00\x00\xf0\x26\x84\xb0\x3f\x00\x00\x00\x90\xd2\xe3\xb0\x3f\x00\x00\x00\x30\x2c\x43\xb1\x3f\x00\x00\x00\x40\x34\xa2\xb1\x3f\x00\x00\x00\x60\xeb\x00\xb2\x3f\x00\x00\x00\x10\x52\x5f\xb2\x3f\x00\x00\x00\xe0\x68\xbd\xb2\x3f\x00\x00\x00\x50\x30\x1b\xb3\x3f\x00\x00\x00\xe0\xa8\x78\xb3\x3f\x00\x00\x00\x30\xd3\xd5\xb3\x3f\x00\x00\x00\xa0\xaf\x32\xb4\x3f\x00\x00\x00\xd0\x3e\x8f\xb4\x3f\x00\x00\x00\x20\x81\xeb\xb4\x3f\x00\x00\x00\x30\x77\x47\xb5\x3f\x00\x00\x00\x60\x21\xa3\xb5\x3f\x00\x00\x00\x40\x80\xfe\xb5\x3f\x00\x00\x00\x40\x94\x59\xb6\x3f\x00\x00\x00\xf0\x5d\xb4\xb6\x3f\x00\x00\x00\xb0\xdd\x0e\xb7\x3f\x00\x00\x00\x00\x14\x69\xb7\x3f\x00\x00\x00\x60\x01\xc3\xb7\x3f\x00\x00\x00\x30\xa6\x1c\xb8\x3f\x00\x00\x00\x00\x03\x76\xb8\x3f\x00\x00\x00\x30\x18\xcf\xb8\x3f\x00\x00\x00\x40\xe6\x27\xb9\x3f\x00\x00\x00\x90\x6d\x80\xb9\x3f\x00\x00\x00\xa0\xae\xd8\xb9\x3f\x00\x00\x00\xd0\xa9\x30\xba\x3f\x00\x00\x00\xa0\x5f\x88\xba\x3f\x00\x00\x00\x70\xd0\xdf\xba\x3f\x00\x00\x00\xb0\xfc\x36\xbb\x3f\x00\x00\x00\xd0\xe4\x8d\xbb\x3f\x00\x00\x00\x30\x89\xe4\xbb\x3f\x00\x00\x00\x40\xea\x3a\xbc\x3f\x00\x00\x00\x70\x08\x91\xbc\x3f\x00\x00\x00\x10\xe4\xe6\xbc\x3f\x00\x00\x00\xa0\x7d\x3c\xbd\x3f\x00\x00\x00\x80\xd5\x91\xbd\x3f\x00\x00\x00\x00\xec\xe6\xbd\x3f\x00\x00\x00\xa0\xc1\x3b\xbe\x3f\x00\x00\x00\xb0\x56\x90\xbe\x3f\x00\x00\x00\xa0\xab\xe4\xbe\x3f\x00\x00\x00\xc0\xc0\x38\xbf\x3f\x00\x00\x00\x80\x96\x8c\xbf\x3f\x00\x00\x00\x30\x2d\xe0\xbf\x3f\x00\x00\x00\xa0\xc2\x19\xc0\x3f\x00\x00\x00\x70\x4f\x43\xc0\x3f\x00\x00\x00\x60\xbd\x6c\xc0\x3f\x00\x00\x00\x80\x0c\x96\xc0\x3f\x00\x00\x00\x00\x3d\xbf\xc0\x3f\x00\x00\x00\x10\x4f\xe8\xc0\x3f\x00\x00\x00\xf0\x42\x11\xc1\x3f\x00\x00\x00\xa0\x18\x3a\xc1\x3f\x00\x00\x00\x80\xd0\x62\xc1\x3f\x00\x00\x00\x90\x6a\x8b\xc1\x3f\x00\x00\x00\x10\xe7\xb3\xc1\x3f\x00\x00\x00\x30\x46\xdc\xc1\x3f\x00\x00\x00\x10\x88\x04\xc2\x3f\x00\x00\x00\xe0\xac\x2c\xc2\x3f\x00\x00\x00\xd0\xb4\x54\xc2\x3f\x00\x00\x00\xf0\x9f\x7c\xc2\x3f\x00\x00\x00\x80\x6e\xa4\xc2\x3f\x00\x00\x00\xb0\x20\xcc\xc2\x3f\x00\x00\x00\x90\xb6\xf3\xc2\x3f\x00\x00\x00\x50\x30\x1b\xc3\x3f\x00\x00\x00\x20\x8e\x42\xc3\x3f\x00\x00\x00\x20\xd0\x69\xc3\x3f\x00\x00\x00\x80\xf6\x90\xc3\x3f\x00\x00\x00\x60\x01\xb8\xc3\x3f\x00\x00\x00\xe0\xf0\xde\xc3\x3f\x00\x00\x00\x30\xc5\x05\xc4\x3f\x00\x00\x00\x70\x7e\x2c\xc4\x3f\x00\x00\x00\xd0\x1c\x53\xc4\x3f\x00\x00\x00\x70\xa0\x79\xc4\x3f\x00\x00\x00\x70\x09\xa0\xc4\x3f\x00\x00\x00\x00\x58\xc6\xc4\x3f\x00\x00\x00\x30\x8c\xec\xc4\x3f\x00\x00\x00\x40\xa6\x12\xc5\x3f\x00\x00\x00\x30\xa6\x38\xc5\x3f\x00\x00\x00\x50\x8c\x5e\xc5\x3f\x00\x00\x00\x90\x58\x84\xc5\x3f\x00\x00\x00\x40\x0b\xaa\xc5\x3f\x00\x00\x00\x70\xa4\xcf\xc5\x3f\x00\x00\x00\x40\x24\xf5\xc5\x3f\x00\x00\x00\xd0\x8a\x1a\xc6\x3f\x00\x00\x00\x50\xd8\x3f\xc6\x3f\x00\x00\x00\xd0\x0c\x65\xc6\x3f\x00\x00\x00\x80\x28\x8a\xc6\x3f\x00\x00\x00\x80\x2b\xaf\xc6\x3f\x00\x00\x00\xe0\x15\xd4\xc6\x3f\x00\x00\x00\xd0\xe7\xf8\xc6\x3f\x00\x00\x00\x70\xa1\x1d\xc7\x3f\x00\x00\x00\xe0\x42\x42\xc7\x3f\x00\x00\x00\x40\xcc\x66\xc7\x3f\x00\x00\x00\xa0\x3d\x8b\xc7\x3f\x00\x00\x00\x30\x97\xaf\xc7\x3f\x00\x00\x00\x10\xd9\xd3\xc7\x3f\x00\x00\x00\x50\x03\xf8\xc7\x3f\x00\x00\x00\x20\x16\x1c\xc8\x3f\x00\x00\x00\x90\x11\x40\xc8\x3f\x00\x00\x00\xc0\xf5\x63\xc8\x3f\x00\x00\x00\xe0\xc2\x87\xc8\x3f\x00\x00\x00\x00\x79\xab\xc8\x3f\x00\x00\x00\x30\x18\xcf\xc8\x3f\x00\x00\x00\xa0\xa0\xf2\xc8\x3f\x00\x00\x00\x70\x12\x16\xc9\x3f\x00\x00\x00\xb0\x6d\x39\xc9\x3f\x00\x00\x00\x80\xb2\x5c\xc9\x3f\x00\x00\x00\x00\xe1\x7f\xc9\x3f\x00\x00\x00\x50\xf9\xa2\xc9\x3f\x00\x00\x00\x70\xfb\xc5\xc9\x3f\x00\x00\x00\xb0\xe7\xe8\xc9\x3f\x00\x00\x00\xf0\xbd\x0b\xca\x3f\x00\x00\x00\x80\x7e\x2e\xca\x3f\x00\x00\x00\x60\x29\x51\xca\x3f\x00\x00\x00\xa0\xbe\x73\xca\x3f\x00\x00\x00\x70\x3e\x96\xca\x3f\x00\x00\x00\xf0\xa8\xb8\xca\x3f\x00\x00\x00\x20\xfe\xda\xca\x3f\x00\x00\x00\x30\x3e\xfd\xca\x3f\x00\x00\x00\x30\x69\x1f\xcb\x3f\x00\x00\x00\x40\x7f\x41\xcb\x3f\x00\x00\x00\x70\x80\x63\xcb\x3f\x00\x00\x00\xf0\x6c\x85\xcb\x3f\x00\x00\x00\xb0\x44\xa7\xcb\x3f\x00\x00\x00\xf0\x07\xc9\xcb\x3f\x00\x00\x00\xc0\xb6\xea\xcb\x3f\x00\x00\x00\x30\x51\x0c\xcc\x3f\x00\x00\x00\x50\xd7\x2d\xcc\x3f\x00\x00\x00\x50\x49\x4f\xcc\x3f\x00\x00\x00\x40\xa7\x70\xcc\x3f\x00\x00\x00\x30\xf1\x91\xcc\x3f\x00\x00\x00\x40\x27\xb3\xcc\x3f\x00\x00\x00\x80\x49\xd4\xcc\x3f\x00\x00\x00\x10\x58\xf5\xcc\x3f\x00\x00\x00\x00\x53\x16\xcd\x3f\x00\x00\x00\x60\x3a\x37\xcd\x3f\x00\x00\x00\x60\x0e\x58\xcd\x3f\x00\x00\x00\x00\xcf\x78\xcd\x3f\x00\x00\x00\x70\x7c\x99\xcd\x3f\x00\x00\x00\xa0\x16\xba\xcd\x3f\x00\x00\x00\xd0\x9d\xda\xcd\x3f\x00\x00\x00\xf0\x11\xfb\xcd\x3f\x00\x00\x00\x30\x73\x1b\xce\x3f\x00\x00\x00\xa0\xc1\x3b\xce\x3f\x00\x00\x00\x50\xfd\x5b\xce\x3f\x00\x00\x00\x60\x26\x7c\xce\x3f\x00\x00\x00\xe0\x3c\x9c\xce\x3f\x00\x00\x00\xe0\x40\xbc\xce\x3f\x00\x00\x00\x80\x32\xdc\xce\x3f\x00\x00\x00\xd0\x11\xfc\xce\x3f\x00\x00\x00\xe0\xde\x1b\xcf\x3f\x00\x00\x00\xd0\x99\x3b\xcf\x3f\x00\x00\x00\xa0\x42\x5b\xcf\x3f\x00\x00\x00\x80\xd9\x7a\xcf\x3f\x00\x00\x00\x70\x5e\x9a\xcf\x3f\x00\x00\x00\x90\xd1\xb9\xcf\x3f\x00\x00\x00\xf0\x32\xd9\xcf\x3f\x00\x00\x00\xa0\x82\xf8\xcf\x3f\x00\x00\x00\x50\xe0\x0b\xd0\x3f\x00\x00\x00\xa0\x76\x1b\xd0\x3f\x00\x00\x00\x30\x04\x2b\xd0\x3f\x00\x00\x00\x10\x89\x3a\xd0\x3f\x00\x00\x00\x40\x05\x4a\xd0\x3f\x00\x00\x00\xe0\x78\x59\xd0\x3f\x00\x00\x00\xf0\xe3\x68\xd0\x3f\x00\x00\x00\x70\x46\x78\xd0\x3f\x00\x00\x00\x80\xa0\x87\xd0\x3f\x00\x00\x00\x10\xf2\x96\xd0\x3f\x00\x00\x00\x30\x3b\xa6\xd0\x3f\x00\x00\x00\xf0\x7b\xb5\xd0\x3f\x00\x00\x00\x50\xb4\xc4\xd0\x3f\x00\x00\x00\x60\xe4\xd3\xd0\x3f\x00\x00\x00\x30\x0c\xe3\xd0\x3f\x00\x00\x00\xc0\x2b\xf2\xd0\x3f\x00\x00\x00\x10\x43\x01\xd1\x3f\x00\x00\x00\x40\x52\x10\xd1\x3f\x00\x00\x00\x40\x59\x1f\xd1\x3f\x00\x00\x00\x30\x58\x2e\xd1\x3f\x00\x00\x00\x00\x4f\x3d\xd1\x3f\x00\x00\x00\xd0\x3d\x4c\xd1\x3f\x00\x00\x00\xa0\x24\x5b\xd1\x3f\x00\x00\x00\x70\x03\x6a\xd1\x3f\x00\x00\x00\x50\xda\x78\xd1\x3f\x00\x00\x00\x40\xa9\x87\xd1\x3f\x00\x00\x00\x60\x70\x96\xd1\x3f\x00\x00\x00\xa0\x2f\xa5\xd1\x3f\x00\x00\x00\x10\xe7\xb3\xd1\x3f\x00\x00\x00\xc0\x96\xc2\xd1\x3f\x00\x00\x00\xb0\x3e\xd1\xd1\x3f\x00\x00\x00\xf0\xde\xdf\xd1\x3f\x00\x00\x00\x70\x77\xee\xd1\x3f\x00\x00\x00\x60\x08\xfd\xd1\x3f\x00\x00\x00\xa0\x91\x0b\xd2\x3f\x00\x00\x00\x50\x13\x1a\xd2\x3f\x00\x00\x00\x70\x8d\x28\xd2\x3f\x00\x00\x00\x10\x00\x37\xd2\x3f\x00\x00\x00\x30\x6b\x45\xd2\x3f\x00\x00\x00\xd0\xce\x53\xd2\x3f\x00\x00\x00\x00\x2b\x62\xd2\x3f\x00\x00\x00\xd0\x7f\x70\xd2\x3f\x00\x00\x00\x40\xcd\x7e\xd2\x3f\x00\x00\x00\x60\x13\x8d\xd2\x3f\x00\x00\x00\x20\x52\x9b\xd2\x3f\x00\x00\x00\xa0\x89\xa9\xd2\x3f\x00\x00\x00\xe0\xb9\xb7\xd2\x3f\x00\x00\x00\xe0\xe2\xc5\xd2\x3f\x00\x00\x00\xb0\x04\xd4\xd2\x3f\x00\x00\x00\x50\x1f\xe2\xd2\x3f\x00\x00\x00\xc0\x32\xf0\xd2\x3f\x00\x00\x00\x20\x3f\xfe\xd2\x3f\x00\x00\x00\x70\x44\x0c\xd3\x3f\x00\x00\x00\xb0\x42\x1a\xd3\x3f\x00\x00\x00\xe0\x39\x28\xd3\x3f\x00\x00\x00\x10\x2a\x36\xd3\x3f\x00\x00\x00\x50\x13\x44\xd3\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x20\xb2\x22\xbc\x0a\xb2\x3d\xd4\x0d\x2e\x33\x69\x0f\xb1\x3d\x57\xd2\x7e\xe8\x0d\x95\xce\x3d\x69\x6d\x62\x3b\x44\xf3\xd3\x3d\x57\x3e\x36\xa5\xea\x5a\xf4\x3d\x0b\xbf\xe1\x3c\x68\x43\xc4\x3d\x11\xa5\xc6\x60\xcd\x89\xf9\x3d\x9f\x2e\x1f\x20\x6f\x62\xfd\x3d\xcd\xbd\xda\xb8\x8b\x4f\xe9\x3d\x15\x30\x42\xef\xd8\x88\x00\x3e\xad\x79\x2b\xa6\x13\x04\x08\x3e\xc4\xd3\xee\xc0\x17\x97\x05\x3e\x02\x49\xd4\xad\x77\x4a\xad\x3d\x0e\x30\x37\xf0\x3f\x76\x0e\x3e\xc3\xf6\x06\x47\xd7\x62\xe1\x3d\x14\xbc\x4d\x1f\xcc\x01\x06\x3e\xbf\xe5\xf6\x51\xe0\xf3\xea\x3d\xeb\xf3\x1a\x1e\x0b\x7a\x09\x3e\xc7\x02\xc0\x70\x89\xa3\xc0\x3d\x51\xc7\x57\x00\x00\x2e\x10\x3e\x0e\x6e\xcd\xee\x00\x5b\x15\x3e\xaf\xb5\x03\x70\x29\x86\xdf\x3d\x6d\xa3\x36\xb3\xb9\x57\x10\x3e\x4f\xea\x06\x4a\xc8\x4b\x13\x3e\xad\xbc\xa1\x9e\xda\x43\x16\x3e\x2a\xea\xf7\xb4\xa7\x66\x1d\x3e\xef\xfc\xf7\x38\xe0\xb2\xf6\x3d\x88\xf0\x70\xc6\x54\xe9\xf3\x3d\xb3\xca\x3a\x09\x09\x72\x04\x3e\xa7\x5d\x27\xe7\x8f\x70\x1d\x3e\xe7\xb9\x71\x77\x9e\xdf\x1f\x3e\x60\x06\x0a\xa7\xbf\x27\x08\x3e\x14\xbc\x4d\x1f\xcc\x01\x16\x3e\x5b\x5e\x6a\x10\xf6\x37\x06\x3e\x4b\x62\x7c\xf1\x13\x6a\x12\x3e\x3a\x62\x80\xce\xb2\x3e\x09\x3e\xde\x94\x15\xe9\xd1\x30\x14\x3e\x31\xa0\x8f\x10\x10\x6b\x1d\x3e\x41\xf2\xba\x0b\x9c\x87\x16\x3e\x2b\xbc\xa6\x5e\x01\x08\xff\x3d\x6c\x67\xc6\xcd\x3d\xb6\x29\x3e\x2c\xab\xc4\xbc\x2c\x02\x2b\x3e\x44\x65\xdd\x7d\xd0\x17\xf9\x3d\x9e\x37\x03\x57\x60\x40\x15\x3e\x60\x1b\x7a\x94\x8b\xd1\x0c\x3e\x7e\xa9\x7c\x27\x65\xad\x17\x3e\xa9\x5f\x9f\xc5\x4d\x88\x11\x3e\x82\xd0\x06\x60\xc4\x11\x17\x3e\xf8\x08\x31\x3c\x2e\x09\x2f\x3e\x3a\xe1\x2b\xe3\xc5\x14\x17\x3e\x9a\x4f\x73\xfd\xa7\xbb\x26\x3e\x83\x84\xe0\xb5\x8f\xf4\xfd\x3d\x95\x0b\x4d\xc7\x9b\x2f\x23\x3e\x13\x0c\x79\x48\xe8\x73\xf9\x3d\x6e\x58\xc6\x08\xbc\xcc\x1e\x3e\x98\x4a\x52\xf9\xe9\x15\x21\x3e\xb8\x31\x31\x59\x40\x17\x2f\x3e\x35\x38\x64\x25\x8b\xcf\x1b\x3e\x80\xed\x8b\x1d\xa8\x5f\x1f\x3e\xe4\xd9\x29\xf9\x4d\x4a\x24\x3e\x94\x0c\x22\xd8\x20\x98\x12\x3e\x09\xe3\x04\x93\x48\x0b\x2a\x3e\xfe\x65\xa6\xab\x56\x4d\x1f\x3e\x63\x51\x36\x19\x90\x0c\x21\x3e\x36\x27\x59\xfe\x78\x0f\xf8\x3d\xca\x1c\xc8\x25\x88\x52\x10\x3e\x6a\x74\x6d\x7d\x53\x95\xe0\x3d\x60\x06\x0a\xa7\xbf\x27\x18\x3e\x3c\x93\x45\xec\xa8\xb0\x06\x3e\xa9\xdb\xf5\x1b\xf8\x5a\x10\x3e\x15\xd5\x55\x26\xfa\xe2\x17\x3e\xbf\xe4\xae\xbf\xec\x59\x0d\x3e\xa3\x3f\x68\xda\x2f\x8b\x1d\x3e\x37\x37\x3a\xfd\xdd\xb8\x24\x3e\x04\x12\xae\x61\x7e\x82\x13\x3e\x9f\x0f\xe9\x49\x7b\x8c\x2c\x3e\x1d\x59\x97\x15\xf0\xea\x29\x3e\x36\x7b\x31\x6e\xa6\xaa\x19\x3e\x55\x06\x72\x09\x56\x72\x2e\x3e\x54\xac\x7a\xfc\x33\x1c\x26\x3e\x52\xa2\x61\xcf\x2b\x66\x29\x3e\x30\x27\xc4\x11\xc8\x43\x18\x3e\x36\xcb\x5a\x0b\xbb\x64\x20\x3e\xa4\x01\x27\x84\x0c\x34\x0a\x3e\xd6\x79\x8f\xb5\x55\x8e\x1a\x3e\x9a\x9d\x5e\x9c\x21\x2d\xe9\x3d\x6a\xfd\x7f\x0d\xe6\x63\x3f\x3e\x14\x63\x51\xd9\x0e\x9b\x2e\x3e\x0c\x35\x62\x19\x90\x23\x29\x3e\x81\x5e\x78\x38\x88\x6f\x32\x3e\xaf\xa6\xab\x4c\x6a\x5b\x3b\x3e\x1c\x76\x8e\xdc\x6a\x22\xf0\x3d\xed\x1a\x3a\x31\xd7\x4a\x3c\x3e\x17\x8d\x73\x7c\xe8\x64\x15\x3e\x18\x66\x8a\xf1\xec\x8f\x33\x3e\x66\x76\x77\xf5\x9e\x92\x3d\x3e\xb8\xa0\x8d\xf0\x3b\x48\x39\x3e\x26\x58\xaa\xee\x0e\xdd\x3b\x3e\xba\x37\x02\x59\xdd\xc4\x39\x3e\xc7\xca\xeb\xe0\xe9\xf3\x1a\x3e\xac\x0d\x27\x82\x53\xce\x35\x3e\xba\xb9\x2a\x53\x74\x4f\x39\x3e\x54\x86\x88\x95\x27\x34\x07\x3e\xf0\x4b\xe3\x0b\x00\x5a\x0c\x3e\x82\xd0\x06\x60\xc4\x11\x27\x3e\xf8\x8c\xed\xb4\x25\x00\x25\x3e\xa0\xd2\xf2\xce\x8b\xd1\x2e\x3e\x54\x75\x0a\x0c\x2e\x28\x21\x3e\xca\xa7\x59\x33\xf3\x70\x0d\x3e\x25\x40\xa8\x13\x7e\x7f\x2b\x3e\x1e\x89\x21\xc3\x6e\x30\x33\x3e\x50\x75\x8b\x03\xf8\xc7\x3f\x3e\x64\x1d\xd7\x8c\x35\xb0\x3e\x3e\x74\x94\x85\x22\xc8\x76\x3a\x3e\xe3\x86\xde\x52\xc6\x0e\x3d\x3e\xaf\x58\x86\xe0\xcc\xa4\x2f\x3e\x9e\x0a\xc0\xd2\xa2\x84\x3b\x3e\xd1\x5b\xc2\xf2\xb0\xa5\x20\x3e\x99\xf6\x5b\x22\x60\xd6\x3d\x3e\x37\xf0\x9b\x85\x0f\xb1\x08\x3e\xe1\xcb\x90\xb5\x23\x88\x3e\x3e\xf6\x96\x1e\xf3\x11\x13\x36\x3e\x9a\x0f\xa2\x5c\x87\x1f\x2e\x3e\xa5\xb9\x39\x49\x72\x95\x2c\x3e\xe2\x58\x3e\x7a\x95\x05\x38\x3e\x34\x03\x9f\xea\x26\xf1\x2f\x3e\x09\x56\x8e\x59\xf5\x53\x39\x3e\x48\xc4\x56\xf8\x6f\xc1\x36\x3e\xf4\x61\xf2\x0f\x22\xcb\x24\x3e\xa2\x53\x3d\xd5\x20\xe1\x35\x3e\x56\xf2\x89\x61\x7f\x52\x3a\x3e\x0f\x9c\xd4\xff\xfc\x56\x38\x3e\xda\xd7\x28\x82\x2e\x0c\x30\x3e\xe0\xdf\x44\x94\xd0\x13\xf1\x3d\xa6\x59\xea\x0e\x63\x10\x25\x3e\x11\xd7\x32\x0f\x78\x2e\x26\x3e\xcf\xf8\x10\x1a\xd9\x3e\xed\x3d\x85\xcd\x4b\x7e\x4a\x65\x23\x3e\x21\xad\x80\x49\x78\x5b\x05\x3e\x64\x6e\xb1\xd4\x2d\x2f\x21\x3e\x0c\xf5\x39\xd9\xad\xc4\x37\x3e\xfc\x80\x71\x62\x84\x17\x28\x3e\x61\x49\xe1\xc7\x62\x51\xea\x3d\x63\x51\x36\x19\x90\x0c\x31\x3e\x88\x76\xa1\x2b\x4d\x3c\x37\x3e\x81\x3d\xe9\xe0\xa5\xe8\x2a\x3e\xaf\x21\x16\xf0\xc6\xb0\x2a\x3e\x66\x5b\xdd\x74\x8b\x1e\x30\x3e\x94\x54\xbb\xec\x6f\x20\x2d\x3e\x00\xcc\x4f\x72\x8b\xb4\xf0\x3d\x29\xe2\x61\x0b\x1f\x83\x3f\x3e\xaf\xbc\x07\xc4\x97\x1a\xf8\x3d\xaa\xb7\xcb\x1c\x6c\x28\x3e\x3e\x93\x0a\x22\x49\x0b\x63\x28\x3e\x5c\x2c\xa2\xc1\x15\x0b\xff\x3d\x46\x09\x1c\xe7\x45\x54\x35\x3e\x85\x6d\x06\xf8\x30\xe6\x3b\x3e\x39\x6c\xd9\xf0\xdf\x99\x25\x3e\x81\xb0\x8f\xb1\x85\xcc\x36\x3e\xc8\xa8\x1e\x00\x6d\x47\x34\x3e\x1f\xd3\x16\x9e\x88\x3f\x37\x3e\x87\x2a\x79\x0d\x10\x57\x33\x3e\xf6\x01\x61\xae\x79\xd1\x3b\x3e\xe2\xf6\xc3\x56\x10\xa3\x0c\x3e\xfb\x08\x9c\x62\x70\x28\x3d\x3e\x3f\x67\xd2\x80\x38\xba\x3a\x3e\xa6\x7d\x29\xcb\x33\x36\x2c\x3e\x02\xea\xef\x99\x38\x84\x21\x3e\xe6\x08\x20\x9d\xc9\xcc\x3b\x3e\x50\xd3\xbd\x44\x05\x00\x38\x3e\xe1\x6a\x60\x26\xc2\x91\x2b\x3e\xdf\x2b\xb6\x26\xdf\x7a\x2a\x3e\xc9\x6e\x82\xc8\x4f\x76\x18\x3e\xf0\x68\x0f\xe5\x3d\x4f\x1f\x3e\xe3\x95\x79\x75\xca\x60\xf7\x3d\x47\x51\x80\xd3\x7e\x66\xfc\x3d\x6f\xdf\x6a\x19\xf6\x33\x37\x3e\x6b\x83\x3e\xf3\x10\xb7\x2f\x3e\x13\x10\x64\xba\x6e\x88\x39\x3e\x1a\x8c\xaf\xd0\x68\x53\xfb\x3d\x71\x29\x8d\x1b\x69\x8c\x35\x3e\xfb\x08\x6d\x22\x65\x94\xfe\x3d\x97\x00\x3f\x06\x7e\x58\x33\x3e\x18\x9f\x12\x02\xe7\x18\x36\x3e\x54\xac\x7a\xfc\x33\x1c\x36\x3e\x4a\x60\x08\x84\xa6\x07\x3f\x3e\x21\x54\x94\xe4\xbf\x34\x3c\x3e\x0b\x30\x41\x0e\xf0\xb1\x38\x3e\x63\x1b\xd6\x84\x42\x43\x3f\x3e\x36\x74\x39\x5e\x09\x63\x3a\x3e\xde\x19\xb9\x56\x86\x42\x34\x3e\xa6\xd9\xb2\x01\x92\xca\x36\x3e\x1c\x93\x2a\x3a\x82\x38\x27\x3e\x30\x92\x17\x0e\x88\x11\x3c\x3e\xfe\x52\x6d\x8d\xdc\x3d\x31\x3e\x17\xe9\x22\x89\xd5\xee\x33\x3e\x50\xdd\x6b\x84\x92\x59\x29\x3e\x8b\x27\x2e\x5f\x4d\xdb\x0d\x3e\xc4\x35\x06\x2a\xf1\xa5\xf1\x3d\x34\x3c\x2c\x88\xf0\x42\x46\x3e\x5e\x47\xf6\xa7\x9b\xee\x2a\x3e\xe4\x60\x4a\x83\x7f\x4b\x26\x3e\x2e\x79\x43\xe2\x42\x0d\x29\x3e\x01\x4f\x13\x08\x20\x27\x4c\x3e\x5b\xcf\xd6\x16\x2e\x78\x4a\x3e\x48\x66\xda\x79\x5c\x50\x44\x3e\x21\xcd\x4d\xea\xd4\xa9\x4c\x3e\xbc\xd5\x7c\x62\x3d\x7d\x29\x3e\x13\xaa\xbc\xf9\x5c\xb1\x20\x3e\xdd\x76\xcf\x63\x20\x5b\x31\x3e\x48\x27\xaa\xf3\xe6\x83\x29\x3e\x94\xe9\xff\xf4\x64\x4c\x3f\x3e\x0f\x5a\xe8\x7c\xba\xbe\x46\x3e\xb8\xa6\x4e\xfd\x69\x9c\x3b\x3e\xab\xa4\x5f\x83\xa5\x6a\x2b\x3e\xd1\xed\x0f\x79\xc3\xcc\x43\x3e\xe0\x4f\x40\xc4\x4c\xc0\x29\x3e\x9d\xd8\x75\x7a\x4b\x73\x40\x3e\x12\x16\xe0\xc4\x04\x44\x1b\x3e\x94\x48\xce\xc2\x65\xc5\x40\x3e\xcd\x35\xd9\x41\x14\xc7\x33\x3e\x4e\x3b\x6b\x55\x92\xa4\x72\x3d\x43\xdc\x41\x03\x09\xfa\x20\x3e\xf4\xd9\xe3\x09\x70\x8f\x2e\x3e\x45\x8a\x04\x8b\xf6\x1b\x4b\x3e\x56\xa9\xfa\xdf\x52\xee\x3e\x3e\xbd\x65\xe4\x00\x09\x6b\x45\x3e\x66\x76\x77\xf5\x9e\x92\x4d\x3e\x60\xe2\x37\x86\xa2\x6e\x48\x3e\xf0\xa2\x0c\xf1\xaf\x65\x46\x3e\x74\xec\x48\xaf\xfd\x11\x2f\x3e\xc7\xd1\xa4\x86\x1b\xbe\x4c\x3e\x65\x76\xa8\xfe\x5b\xb0\x25\x3e\x1d\x4a\x1a\x0a\xc2\xce\x41\x3e\x9f\x9b\x40\x0a\x5f\xcd\x41\x3e\x70\x50\x26\xc8\x56\x36\x45\x3e\x60\x22\x28\x35\xd8\x7e\x37\x3e\xd2\xb9\x40\x30\xbc\x17\x24\x3e\xf2\xef\x79\x7b\xef\x8e\x40\x3e\xe9\x57\xdc\x39\x6f\xc7\x4d\x3e\x57\xf4\x0c\xa7\x93\x04\x4c\x3e\x0c\xa6\xa5\xce\xd6\x83\x4a\x3e\xba\x57\xc5\x0d\x70\xd6\x30\x3e\x0a\xbd\xe8\x12\x6c\xc9\x44\x3e\x15\x23\xe3\x93\x19\x2c\x3d\x3e\x42\x82\x5f\x13\x21\xc7\x22\x3e\x7d\x74\xda\x4d\x3e\x9a\x27\x3e\x2b\xa7\x41\x69\x9f\xf8\xfc\x3d\x31\x08\xf1\x02\xa7\x49\x21\x3e\xdb\x75\x81\x7c\x4b\xad\x4e\x3e\x0a\xe7\x63\xfe\x30\x69\x4e\x3e\x2f\xee\xd9\xbe\x06\xe1\x41\x3e\x92\x1c\xf1\x82\x2b\x68\x2d\x3e\x7c\xa4\xdb\x88\xf1\x07\x3a\x3e\xf6\x72\xc1\x2d\x34\xf9\x40\x3e\x25\x3e\x62\xde\x3f\xef\x03\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x20\xe0\x1f\xe0\x1f\xe0\xff\x3f\xf0\x07\xfc\x01\x7f\xc0\xff\x3f\x12\xfa\x01\xaa\x1c\xa1\xff\x3f\x20\xf8\x81\x1f\xf8\x81\xff\x3f\xb5\xdb\xa0\xac\x10\x63\xff\x3f\x71\x42\x4a\x9e\x65\x44\xff\x3f\xb5\x0a\x23\x44\xf6\x25\xff\x3f\x08\x1f\x7c\xf0\xc1\x07\xff\x3f\x02\x8e\x45\xf8\xc7\xe9\xfe\x3f\xc0\xec\x01\xb3\x07\xcc\xfe\x3f\xeb\x01\xba\x7a\x80\xae\xfe\x3f\x67\xb7\xf0\xab\x31\x91\xfe\x3f\xe4\x50\x97\xa5\x1a\x74\xfe\x3f\x74\xe5\x01\xc9\x3a\x57\xfe\x3f\x73\x1a\xdc\x79\x91\x3a\xfe\x3f\x1e\x1e\x1e\x1e\x1e\x1e\xfe\x3f\x1e\xe0\x01\x1e\xe0\x01\xfe\x3f\x8a\x86\xf8\xe3\xd6\xe5\xfd\x3f\xca\x1d\xa0\xdc\x01\xca\xfd\x3f\xdb\x81\xb9\x76\x60\xae\xfd\x3f\x8a\x7f\x1e\x23\xf2\x92\xfd\x3f\x34\x2c\xb8\x54\xb6\x77\xfd\x3f\xb2\x72\x75\x80\xac\x5c\xfd\x3f\x1d\xd4\x41\x1d\xd4\x41\xfd\x3f\x1a\x5b\xfc\xa3\x2c\x27\xfd\x3f\x74\xc0\x6e\x8f\xb5\x0c\xfd\x3f\xc6\xbf\x44\x5c\x6e\xf2\xfc\x3f\x0b\x9b\x03\x89\x56\xd8\xfc\x3f\xe7\xcb\x01\x96\x6d\xbe\xfc\x3f\x91\xe1\x5e\x05\xb3\xa4\xfc\x3f\x42\x8a\xfb\x5a\x26\x8b\xfc\x3f\x1c\xc7\x71\x1c\xc7\x71\xfc\x3f\x86\x49\x0d\xd1\x94\x58\xfc\x3f\xf0\xf8\xc3\x01\x8f\x3f\xfc\x3f\x1c\xa0\x2e\x39\xb5\x26\xfc\x3f\xe0\xc0\x81\x03\x07\x0e\xfc\x3f\x8b\x8d\x86\xee\x83\xf5\xfb\x3f\xf7\x06\x94\x89\x2b\xdd\xfb\x3f\x7b\x3e\x88\x65\xfd\xc4\xfb\x3f\xd0\xba\xc1\x14\xf9\xac\xfb\x3f\x23\xff\x18\x2b\x1e\x95\xfb\x3f\x8b\x33\xda\x3d\x6c\x7d\xfb\x3f\x05\xee\xbe\xe3\xe2\x65\xfb\x3f\x4f\x1b\xe8\xb4\x81\x4e\xfb\x3f\xce\x06\xd8\x4a\x48\x37\xfb\x3f\xd9\x80\x6c\x40\x36\x20\xfb\x3f\xa4\x22\xd9\x31\x4b\x09\xfb\x3f\x28\xaf\xa1\xbc\x86\xf2\xfa\x3f\x5e\x90\x94\x7f\xe8\xdb\xfa\x3f\x1b\x70\xc5\x1a\x70\xc5\xfa\x3f\xfd\xeb\x87\x2f\x1d\xaf\xfa\x3f\xbe\x63\x6a\x60\xef\x98\xfa\x3f\x59\xe1\x30\x51\xe6\x82\xfa\x3f\x6d\x1a\xd0\xa6\x01\x6d\xfa\x3f\x4a\x8a\x68\x07\x41\x57\xfa\x3f\x1a\xa4\x41\x1a\xa4\x41\xfa\x3f\xa0\x1c\xc5\x87\x2a\x2c\xfa\x3f\x02\x4b\x7a\xf9\xd3\x16\xfa\x3f\x1a\xa0\x01\x1a\xa0\x01\xfa\x3f\xd9\x33\x10\x95\x8e\xec\xf9\x3f\x2d\x68\x6b\x17\x9f\xd7\xf9\x3f\x02\xa1\xe4\x4e\xd1\xc2\xf9\x3f\xda\x10\x55\xea\x24\xae\xf9\x3f\x9a\x99\x99\x99\x99\x99\xf9\x3f\xff\xc0\x8e\x0d\x2f\x85\xf9\x3f\x72\xb8\x0c\xf8\xe4\x70\xf9\x3f\xae\x77\xe3\x0b\xbb\x5c\xf9\x3f\xe0\xe9\xd6\xfc\xb0\x48\xf9\x3f\xe6\x2c\x9b\x7f\xc6\x34\xf9\x3f\x29\xe2\xd0\x49\xfb\x20\xf9\x3f\xd5\x90\x01\x12\x4f\x0d\xf9\x3f\xfa\x18\x9c\x8f\xc1\xf9\xf8\x3f\x3f\x37\xf1\x7a\x52\xe6\xf8\x3f\xd3\x18\x30\x8d\x01\xd3\xf8\x3f\x3a\xff\x62\x80\xce\xbf\xf8\x3f\xaa\xf3\x6b\x0f\xb9\xac\xf8\x3f\x9c\x89\x01\xf6\xc0\x99\xf8\x3f\x4a\xb0\xab\xf0\xe5\x86\xf8\x3f\xb9\x92\xc0\xbc\x27\x74\xf8\x3f\x18\x86\x61\x18\x86\x61\xf8\x3f\x14\x06\x78\xc2\x00\x4f\xf8\x3f\xdd\xbe\xb2\x7a\x97\x3c\xf8\x3f\xa0\xa4\x82\x01\x4a\x2a\xf8\x3f\x18\x18\x18\x18\x18\x18\xf8\x3f\x06\x18\x60\x80\x01\x06\xf8\x3f\x40\x7f\x01\xfd\x05\xf4\xf7\x3f\x1d\x4f\x5a\x51\x25\xe2\xf7\x3f\xf4\x05\x7d\x41\x5f\xd0\xf7\x3f\x7c\x01\x2e\x92\xb3\xbe\xf7\x3f\xc3\xec\xe0\x08\x22\xad\xf7\x3f\x8b\x39\xb6\x6b\xaa\x9b\xf7\x3f\xc8\xa4\x78\x81\x4c\x8a\xf7\x3f\x0d\xc6\x9a\x11\x08\x79\xf7\x3f\xb1\xa9\x34\xe4\xdc\x67\xf7\x3f\x6d\x75\x01\xc2\xca\x56\xf7\x3f\x46\x17\x5d\x74\xd1\x45\xf7\x3f\x8d\xfe\x41\xc5\xf0\x34\xf7\x3f\xbc\xde\x46\x7f\x28\x24\xf7\x3f\x09\x7c\x9c\x6d\x78\x13\xf7\x3f\x70\x81\x0b\x5c\xe0\x02\xf7\x3f\x17\x60\xf2\x16\x60\xf2\xf6\x3f\xc7\x37\x43\x6b\xf7\xe1\xf6\x3f\x61\xc8\x81\x26\xa6\xd1\xf6\x3f\x17\x6c\xc1\x16\x6c\xc1\xf6\x3f\x3d\x1a\xa3\x0a\x49\xb1\xf6\x3f\x90\x72\x53\xd1\x3c\xa1\xf6\x3f\xc0\xd0\x88\x3a\x47\x91\xf6\x3f\x17\x68\x81\x16\x68\x81\xf6\x3f\x1a\x67\x01\x36\x9f\x71\xf6\x3f\xf9\x22\x51\x6a\xec\x61\xf6\x3f\xa3\x4a\x3b\x85\x4f\x52\xf6\x3f\x64\x21\x0b\x59\xc8\x42\xf6\x3f\xde\xc0\x8a\xb8\x56\x33\xf6\x3f\x40\x62\x01\x77\xfa\x23\xf6\x3f\x94\xae\x31\x68\xb3\x14\xf6\x3f\x06\x16\x58\x60\x81\x05\xf6\x3f\xfc\x2d\x29\x34\x64\xf6\xf5\x3f\xe7\x15\xd0\xb8\x5b\xe7\xf5\x3f\xa5\xe2\xec\xc3\x67\xd8\xf5\x3f\x57\x10\x93\x2b\x88\xc9\xf5\x3f\x91\xfa\x47\xc6\xbc\xba\xf5\x3f\xc0\x5a\x01\x6b\x05\xac\xf5\x3f\xaa\xcc\x23\xf1\x61\x9d\xf5\x3f\xed\x58\x81\x30\xd2\x8e\xf5\x3f\x60\x05\x58\x01\x56\x80\xf5\x3f\x3a\x6b\x50\x3c\xed\x71\xf5\x3f\xe2\x52\x7c\xba\x97\x63\xf5\x3f\x55\x55\x55\x55\x55\x55\xf5\x3f\xfe\x82\xbb\xe6\x25\x47\xf5\x3f\xeb\x0f\xf4\x48\x09\x39\xf5\x3f\x4b\x05\xa8\x56\xff\x2a\xf5\x3f\x15\xf8\xe2\xea\x07\x1d\xf5\x3f\xc5\xc4\x11\xe1\x22\x0f\xf5\x3f\x15\x50\x01\x15\x50\x01\xf5\x3f\x9b\x4c\xdd\x62\x8f\xf3\xf4\x3f\x39\x05\x2f\xa7\xe0\xe5\xf4\x3f\x4c\x2c\xdc\xbe\x43\xd8\xf4\x3f\x6e\xaf\x25\x87\xb8\xca\xf4\x3f\xe1\x8f\xa6\xdd\x3e\xbd\xf4\x3f\x5b\xbf\x52\xa0\xd6\xaf\xf4\x3f\x4a\x01\x76\xad\x7f\xa2\xf4\x3f\x67\xd0\xb2\xe3\x39\x95\xf4\x3f\x80\x48\x01\x22\x05\x88\xf4\x3f\x7b\x14\xae\x47\xe1\x7a\xf4\x3f\x66\x60\x59\x34\xce\x6d\xf4\x3f\x9a\xcf\xf5\xc7\xcb\x60\xf4\x3f\xca\x76\xc7\xe2\xd9\x53\xf4\x3f\xfb\xd9\x62\x65\xf8\x46\xf4\x3f\x4d\xee\xab\x30\x27\x3a\xf4\x3f\x87\x1f\xd5\x25\x66\x2d\xf4\x3f\x51\x59\x5e\x26\xb5\x20\xf4\x3f\x14\x14\x14\x14\x14\x14\xf4\x3f\x66\x65\x0e\xd1\x82\x07\xf4\x3f\xfb\x13\xb0\x3f\x01\xfb\xf3\x3f\x07\xaf\xa5\x42\x8f\xee\xf3\x3f\x02\xa9\xe4\xbc\x2c\xe2\xf3\x3f\xc6\x75\xaa\x91\xd9\xd5\xf3\x3f\xe7\xab\x7b\xa4\x95\xc9\xf3\x3f\x55\x29\x23\xd9\x60\xbd\xf3\x3f\x14\x3b\xb1\x13\x3b\xb1\xf3\x3f\x22\xc8\x7a\x38\x24\xa5\xf3\x3f\x63\x7f\x18\x2c\x1c\x99\xf3\x3f\x8e\x08\x66\xd3\x22\x8d\xf3\x3f\x14\x38\x81\x13\x38\x81\xf3\x3f\xee\x45\xc9\xd1\x5b\x75\xf3\x3f\x48\x07\xde\xf3\x8d\x69\xf3\x3f\xf8\x2a\x9f\x5f\xce\x5d\xf3\x3f\xc1\x78\x2b\xfb\x1c\x52\xf3\x3f\x46\x13\xe0\xac\x79\x46\xf3\x3f\xb2\xbc\x57\x5b\xe4\x3a\xf3\x3f\xfa\x1d\x6a\xed\x5c\x2f\xf3\x3f\xbf\x10\x2b\x4a\xe3\x23\xf3\x3f\xb6\xeb\xe9\x58\x77\x18\xf3\x3f\x90\xd1\x30\x01\x19\x0d\xf3\x3f\x60\x02\xc4\x2a\xc8\x01\xf3\x3f\x68\x2f\xa1\xbd\x84\xf6\xf2\x3f\x4b\xd1\xfe\xa1\x4e\xeb\xf2\x3f\x97\x80\x4b\xc0\x25\xe0\xf2\x3f\xa0\x50\x2d\x01\x0a\xd5\xf2\x3f\xa0\x2c\x81\x4d\xfb\xc9\xf2\x3f\x11\x37\x5a\x8e\xf9\xbe\xf2\x3f\x40\x2b\x01\xad\x04\xb4\xf2\x3f\x05\xc1\xf3\x92\x1c\xa9\xf2\x3f\x9e\x12\xe4\x29\x41\x9e\xf2\x3f\xa5\x04\xb8\x5b\x72\x93\xf2\x3f\x13\xb0\x88\x12\xb0\x88\xf2\x3f\x4d\xce\xa1\x38\xfa\x7d\xf2\x3f\x35\x27\x81\xb8\x50\x73\xf2\x3f\x27\x01\xd6\x7c\xb3\x68\xf2\x3f\xf1\x92\x80\x70\x22\x5e\xf2\x3f\xb2\x77\x91\x7e\x9d\x53\xf2\x3f\x92\x24\x49\x92\x24\x49\xf2\x3f\x5b\x60\x17\x97\xb7\x3e\xf2\x3f\xdf\xbc\x9a\x78\x56\x34\xf2\x3f\x2a\x12\xa0\x22\x01\x2a\xf2\x3f\x78\xfb\x21\x81\xb7\x1f\xf2\x3f\xe6\x55\x48\x80\x79\x15\xf2\x3f\xd9\xc0\x67\x0c\x47\x0b\xf2\x3f\x12\x20\x01\x12\x20\x01\xf2\x3f\x70\x1f\xc1\x7d\x04\xf7\xf1\x3f\x4c\xb8\x7f\x3c\xf4\xec\xf1\x3f\x74\xb8\x3f\x3b\xef\xe2\xf1\x3f\xbd\x4a\x2e\x67\xf5\xd8\xf1\x3f\x1d\x81\xa2\xad\x06\xcf\xf1\x3f\x59\xe0\x1c\xfc\x22\xc5\xf1\x3f\x29\xed\x46\x40\x4a\xbb\xf1\x3f\xe3\xba\xf2\x67\x7c\xb1\xf1\x3f\x96\x7b\x1a\x61\xb9\xa7\xf1\x3f\x9e\x11\xe0\x19\x01\x9e\xf1\x3f\x9c\xa2\x8c\x80\x53\x94\xf1\x3f\xdb\x2b\x90\x83\xb0\x8a\xf1\x3f\x12\x18\x81\x11\x18\x81\xf1\x3f\x84\xd6\x1b\x19\x8a\x77\xf1\x3f\x79\x73\x42\x89\x06\x6e\xf1\x3f\x01\x32\xfc\x50\x8d\x64\xf1\x3f\x0d\x27\x75\x5f\x1e\x5b\xf1\x3f\xc9\xd5\xfd\xa3\xb9\x51\xf1\x3f\x3b\xcd\x0a\x0e\x5f\x48\xf1\x3f\x24\x47\x34\x8d\x0e\x3f\xf1\x3f\x11\xc8\x35\x11\xc8\x35\xf1\x3f\xac\xc0\xed\x89\x8b\x2c\xf1\x3f\x33\x30\x5d\xe7\x58\x23\xf1\x3f\x26\x48\xa7\x19\x30\x1a\xf1\x3f\x11\x11\x11\x11\x11\x11\xf1\x3f\x80\x10\x01\xbe\xfb\x07\xf1\x3f\x11\xf0\xfe\x10\xf0\xfe\xf0\x3f\xa2\x25\xb3\xfa\xed\xf5\xf0\x3f\x90\x9c\xe6\x6b\xf5\xec\xf0\x3f\x11\x60\x82\x55\x06\xe4\xf0\x3f\x96\x46\x8f\xa8\x20\xdb\xf0\x3f\x3a\x9e\x35\x56\x44\xd2\xf0\x3f\x3b\xda\xbc\x4f\x71\xc9\xf0\x3f\x71\x41\x8b\x86\xa7\xc0\xf0\x3f\xc8\x9d\x25\xec\xe6\xb7\xf0\x3f\xb5\xec\x2e\x72\x2f\xaf\xf0\x3f\xa7\x10\x68\x0a\x81\xa6\xf0\x3f\x60\x83\xaf\xa6\xdb\x9d\xf0\x3f\x54\x09\x01\x39\x3f\x95\xf0\x3f\xe2\x65\x75\xb3\xab\x8c\xf0\x3f\x84\x10\x42\x08\x21\x84\xf0\x3f\xe2\xea\xb8\x29\x9f\x7b\xf0\x3f\xc6\xf7\x47\x0a\x26\x73\xf0\x3f\xfb\x12\x79\x9c\xb5\x6a\xf0\x3f\xfc\xa9\xf1\xd2\x4d\x62\xf0\x3f\x86\x75\x72\xa0\xee\x59\xf0\x3f\x04\x34\xd7\xf7\x97\x51\xf0\x3f\xc5\x64\x16\xcc\x49\x49\xf0\x3f\x10\x04\x41\x10\x04\x41\xf0\x3f\xfc\x47\x82\xb7\xc6\x38\xf0\x3f\x1a\x5e\x1f\xb5\x91\x30\xf0\x3f\xe9\x29\x77\xfc\x64\x28\xf0\x3f\x08\x04\x02\x81\x40\x20\xf0\x3f\x37\x7a\x51\x36\x24\x18\xf0\x3f\x10\x10\x10\x10\x10\x10\xf0\x3f\x80\x00\x01\x02\x04\x08\xf0\x3f\x00\x00\x00\x00\x00\x00\xf0\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x6f\x67\x31\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\x3f\x43\xff\xff\xff\xff\xff\xff\x3f\xc3\x53\x79\x73\x74\x72\x61\x79\x20\x65\x72\x72\x6f\x72\x20\x25\x73\x3a\x20\x25\x64\x20\x25\x73\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x67\x65\x74\x20\x74\x72\x61\x79\x20\x6d\x65\x6e\x75\x20\x70\x6f\x73\x69\x74\x69\x6f\x6e\x00\x00\x67\x65\x74\x20\x6d\x65\x6e\x75\x20\x69\x74\x65\x6d\x20\x69\x64\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x79\x00\x73\x00\x74\x00\x72\x00\x61\x00\x79\x00\x43\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x6f\x61\x64\x20\x69\x63\x6f\x6e\x20\x69\x6d\x61\x67\x65\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x7e\xb7\x57\x00\x00\x00\x00\x02\x00\x00\x00\x65\x00\x00\x00\xac\x7f\x01\x00\xac\x6f\x01\x00\x00\x00\x00\x00\x04\x7e\xb7\x57\x00\x00\x00\x00\x0c\x00\x00\x00\x14\x00\x00\x00\x14\x80\x01\x00\x14\x70\x01\x00\x00\x00\x00\x00\x04\x7e\xb7\x57\x00\x00\x00\x00\x0d\x00\x00\x00\x14\x03\x00\x00\x28\x80\x01\x00\x28\x70\x01\x00\x00\x00\x00\x00\x04\x7e\xb7\x57\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x02\x01\x80\x01\x00\x00\x00\xe0\x02\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x45\x54\x57\x30\x10\x00\x00\x01\x86\x0e\x04\x88\x2b\x05\x8a\xbb\x05\x05\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x2f\x00\x00\x49\x6e\x76\x6f\x6b\x65\x4d\x61\x69\x6e\x56\x69\x61\x43\x52\x54\x00\x22\x4d\x61\x69\x6e\x20\x49\x6e\x76\x6f\x6b\x65\x64\x2e\x22\x00\x02\x46\x69\x6c\x65\x4e\x61\x6d\x65\x00\x01\x05\x05\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x2e\x00\x00\x45\x78\x69\x74\x4d\x61\x69\x6e\x56\x69\x61\x43\x52\x54\x00\x22\x4d\x61\x69\x6e\x20\x52\x65\x74\x75\x72\x6e\x65\x64\x2e\x22\x00\x02\x46\x69\x6c\x65\x4e\x61\x6d\x65\x00\x01\x02\x2b\x00\x4d\x69\x63\x72\x6f\x73\x6f\x66\x74\x2e\x43\x52\x54\x50\x72\x6f\x76\x69\x64\x65\x72\x00\x13\x00\x01\x1a\x73\x50\x4f\xcf\x89\x82\x47\xb3\xe0\xdc\xe8\xc9\x04\x76\xba\x01\x52\x53\x44\x53\x29\x19\x09\x80\x7d\xc7\xfc\x48\xb3\x58\x4d\x35\x41\xc1\xcb\xab\x01\x00\x00\x00\x44\x3a\x5c\x7e\x47\x49\x54\x5c\x66\x6f\x72\x67\x6f\x64\x73\x61\x6b\x65\x73\x6c\x75\x63\x6b\x63\x6f\x6c\x6f\x72\x73\x5c\x73\x79\x73\x74\x72\x61\x79\x2d\x6d\x61\x73\x74\x65\x72\x5c\x73\x79\x73\x74\x72\x61\x79\x5c\x78\x36\x34\x5c\x52\x65\x6c\x65\x61\x73\x65\x5c\x73\x79\x73\x74\x72\x61\x79\x2e\x70\x64\x62\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x00\x00\xa2\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x47\x43\x54\x4c\x00\x10\x00\x00\xdb\x01\x00\x00\x2e\x74\x65\x78\x74\x00\x00\x00\xe0\x11\x00\x00\x27\xe7\x00\x00\x2e\x74\x65\x78\x74\x24\x6d\x6e\x00\x00\x00\x00\x10\xf9\x00\x00\x12\x00\x00\x00\x2e\x74\x65\x78\x74\x24\x6d\x6e\x24\x30\x30\x00\x30\xf9\x00\x00\x70\x02\x00\x00\x2e\x74\x65\x78\x74\x24\x78\x00\x00\x00\x01\x00\xd8\x02\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x35\x00\x00\x00\x00\xd8\x02\x01\x00\x10\x00\x00\x00\x2e\x30\x30\x63\x66\x67\x00\x00\xe8\x02\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x43\x41\x00\x00\x00\x00\xf0\x02\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x43\x5a\x00\x00\x00\x00\xf8\x02\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x49\x41\x00\x00\x00\x00\x00\x03\x01\x00\x18\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x49\x43\x00\x00\x00\x00\x18\x03\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x49\x5a\x00\x00\x00\x00\x20\x03\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x50\x41\x00\x00\x00\x00\x28\x03\x01\x00\x10\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x50\x58\x00\x00\x00\x00\x38\x03\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x50\x58\x41\x00\x00\x00\x40\x03\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x50\x5a\x00\x00\x00\x00\x48\x03\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x54\x41\x00\x00\x00\x00\x50\x03\x01\x00\x08\x00\x00\x00\x2e\x43\x52\x54\x24\x58\x54\x5a\x00\x00\x00\x00\x60\x03\x01\x00\x94\x7b\x00\x00\x2e\x72\x64\x61\x74\x61\x00\x00\xf8\x7e\x01\x00\x10\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x45\x54\x57\x30\x00\x00\x00\x00\x08\x7f\x01\x00\x77\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x45\x54\x57\x31\x00\x00\x00\x00\x7f\x7f\x01\x00\x2c\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x45\x54\x57\x32\x00\x00\x00\x00\xab\x7f\x01\x00\x01\x00\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x45\x54\x57\x39\x00\x00\x00\x00\xac\x7f\x01\x00\x90\x03\x00\x00\x2e\x72\x64\x61\x74\x61\x24\x7a\x7a\x7a\x64\x62\x67\x00\x00\x00\x40\x83\x01\x00\x08\x00\x00\x00\x2e\x72\x74\x63\x24\x49\x41\x41\x00\x00\x00\x00\x48\x83\x01\x00\x08\x00\x00\x00\x2e\x72\x74\x63\x24\x49\x5a\x5a\x00\x00\x00\x00\x50\x83\x01\x00\x08\x00\x00\x00\x2e\x72\x74\x63\x24\x54\x41\x41\x00\x00\x00\x00\x58\x83\x01\x00\x08\x00\x00\x00\x2e\x72\x74\x63\x24\x54\x5a\x5a\x00\x00\x00\x00\x60\x83\x01\x00\x74\x0c\x00\x00\x2e\x78\x64\x61\x74\x61\x00\x00\xe0\x8f\x01\x00\xa1\x00\x00\x00\x2e\x65\x64\x61\x74\x61\x00\x00\x84\x90\x01\x00\x50\x00\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x32\x00\x00\x00\x00\xd4\x90\x01\x00\x14\x00\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x33\x00\x00\x00\x00\xe8\x90\x01\x00\xd8\x02\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x34\x00\x00\x00\x00\xc0\x93\x01\x00\x7e\x06\x00\x00\x2e\x69\x64\x61\x74\x61\x24\x36\x00\x00\x00\x00\x00\xa0\x01\x00\x90\x09\x00\x00\x2e\x64\x61\x74\x61\x00\x00\x00\x90\xa9\x01\x00\x98\x14\x00\x00\x2e\x62\x73\x73\x00\x00\x00\x00\x00\xc0\x01\x00\xcc\x0f\x00\x00\x2e\x70\x64\x61\x74\x61\x00\x00\x00\xd0\x01\x00\x7c\x00\x00\x00\x2e\x67\x66\x69\x64\x73\x24\x78\x00\x00\x00\x00\x7c\xd0\x01\x00\x1c\x00\x00\x00\x2e\x67\x66\x69\x64\x73\x24\x79\x00\x00\x00\x00\x00\xe0\x01\x00\x58\x00\x00\x00\x2e\x72\x73\x72\x63\x24\x30\x31\x00\x00\x00\x00\x60\xe0\x01\x00\x80\x01\x00\x00\x2e\x72\x73\x72\x63\x24\x30\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x06\x02\x00\x06\x72\x02\x30\x01\x07\x02\x00\x07\x01\x13\x00\x21\x08\x02\x00\x08\x34\x12\x00\x90\x12\x00\x00\xc5\x12\x00\x00\x68\x83\x01\x00\x21\x00\x00\x00\x90\x12\x00\x00\xc5\x12\x00\x00\x68\x83\x01\x00\x01\x04\x01\x00\x04\x42\x00\x00\x01\x04\x01\x00\x04\xe2\x00\x00\x01\x06\x02\x00\x06\xb2\x02\x30\x01\x0d\x04\x00\x0d\x34\x12\x00\x0d\xf2\x06\x70\x01\x04\x01\x00\x04\x82\x00\x00\x21\x05\x02\x00\x05\x34\x08\x00\xf0\x15\x00\x00\x1e\x16\x00\x00\xb8\x83\x01\x00\x21\x00\x00\x00\xf0\x15\x00\x00\x1e\x16\x00\x00\xb8\x83\x01\x00\x01\x0a\x02\x00\x0a\x01\x1d\x00\x21\x10\x08\x00\x10\xe4\x1c\x00\x0c\x74\x21\x00\x08\x64\x20\x00\x04\x54\x1f\x00\xe0\x16\x00\x00\xea\x16\x00\x00\xe4\x83\x01\x00\x21\x08\x02\x00\x08\x34\x1e\x00\xea\x16\x00\x00\x78\x17\x00\x00\xec\x83\x01\x00\x21\x00\x00\x00\xea\x16\x00\x00\x78\x17\x00\x00\xec\x83\x01\x00\x21\x00\x00\x00\xe0\x16\x00\x00\xea\x16\x00\x00\xe4\x83\x01\x00\x01\x1b\x04\x00\x1b\x52\x17\x70\x16\x60\x15\x30\x00\x00\x00\x00\x01\x00\x00\x00\x11\x15\x08\x00\x15\x74\x09\x00\x15\x64\x07\x00\x15\x34\x06\x00\x15\x32\x11\xe0\x58\x29\x00\x00\x01\x00\x00\x00\xdf\x19\x00\x00\x6c\x1a\x00\x00\x30\xf9\x00\x00\x00\x00\x00\x00\x11\x0f\x06\x00\x0f\x64\x08\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\x06\x1b\x00\x00\x24\x1b\x00\x00\x47\xf9\x00\x00\x00\x00\x00\x00\x09\x1a\x06\x00\x1a\x34\x0f\x00\x1a\x72\x16\xe0\x14\x70\x13\x60\x58\x29\x00\x00\x01\x00\x00\x00\x76\x1b\x00\x00\x46\x1c\x00\x00\x63\xf9\x00\x00\x46\x1c\x00\x00\x01\x06\x02\x00\x06\x52\x02\x50\x01\x09\x01\x00\x09\x62\x00\x00\x01\x08\x04\x00\x08\x72\x04\x70\x03\x60\x02\x30\x09\x04\x01\x00\x04\x22\x00\x00\x58\x29\x00\x00\x01\x00\x00\x00\xe7\x20\x00\x00\x75\x21\x00\x00\x99\xf9\x00\x00\x75\x21\x00\x00\x01\x02\x01\x00\x02\x50\x00\x00\x01\x0d\x04\x00\x0d\x34\x0a\x00\x0d\x72\x06\x50\x01\x0d\x04\x00\x0d\x34\x09\x00\x0d\x32\x06\x50\x01\x15\x05\x00\x15\x34\xba\x00\x15\x01\xb8\x00\x06\x50\x00\x00\x01\x0d\x04\x00\x0d\x34\x07\x00\x0d\x32\x06\x50\x01\x00\x00\x00\x19\x26\x05\x00\x15\x34\x55\x00\x15\x01\x52\x00\x06\x50\x00\x00\xe0\xf0\x00\x00\x80\x02\x00\x00\x01\x1d\x0c\x00\x1d\x74\x0f\x00\x1d\x64\x0e\x00\x1d\x54\x0d\x00\x1d\x34\x0c\x00\x1d\x72\x19\xf0\x17\xe0\x15\xc0\x01\x1c\x0c\x00\x1c\x64\x10\x00\x1c\x54\x0f\x00\x1c\x34\x0e\x00\x1c\x72\x18\xf0\x16\xe0\x14\xd0\x12\xc0\x10\x70\x00\x00\x00\x00\x01\x00\x00\x00\x01\x19\x0a\x00\x19\x74\x09\x00\x19\x64\x08\x00\x19\x54\x07\x00\x19\x34\x06\x00\x19\x32\x15\xe0\x00\x00\x00\x00\x01\x07\x02\x00\x07\x01\x9b\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x09\x02\x00\x09\xb2\x02\x50\x01\x18\x0a\x00\x18\x64\x0a\x00\x18\x54\x09\x00\x18\x34\x08\x00\x18\x32\x14\xf0\x12\xe0\x10\x70\x01\x0f\x06\x00\x0f\x54\x07\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x01\x13\x08\x00\x13\x54\x0a\x00\x13\x34\x09\x00\x13\x32\x0f\xe0\x0d\x70\x0c\x60\x01\x18\x0a\x00\x18\x64\x0d\x00\x18\x54\x0c\x00\x18\x34\x0b\x00\x18\x52\x14\xf0\x12\xe0\x10\x70\x01\x0a\x04\x00\x0a\x34\x0d\x00\x0a\x92\x06\x70\x01\x06\x02\x00\x06\x32\x02\x30\x19\x1e\x06\x00\x0f\x64\x0e\x00\x0f\x34\x0d\x00\x0f\x92\x0b\x70\xe0\xf0\x00\x00\x40\x00\x00\x00\x19\x24\x07\x00\x12\x64\xa2\x00\x12\x34\xa1\x00\x12\x01\x9e\x00\x0b\x70\x00\x00\xe0\xf0\x00\x00\xe0\x04\x00\x00\x01\x1e\x0a\x00\x1e\x74\x09\x00\x1e\x64\x08\x00\x1e\x54\x07\x00\x1e\x34\x06\x00\x1e\x32\x1a\xe0\x01\x05\x02\x00\x05\x34\x01\x00\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\x2a\x38\x00\x00\x34\x38\x00\x00\xb1\xf9\x00\x00\x00\x00\x00\x00\x01\x06\x02\x00\x06\x32\x02\x50\x19\x19\x0a\x00\x19\xe4\x09\x00\x19\x74\x08\x00\x19\x64\x07\x00\x19\x34\x06\x00\x19\x32\x15\xf0\x58\x29\x00\x00\x02\x00\x00\x00\x13\x52\x00\x00\x71\x52\x00\x00\xcc\xf9\x00\x00\xb0\x52\x00\x00\xf7\x51\x00\x00\xb6\x52\x00\x00\xe7\xf9\x00\x00\x00\x00\x00\x00\x01\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x01\x18\x0a\x00\x18\x64\x0c\x00\x18\x54\x0b\x00\x18\x34\x0a\x00\x18\x52\x14\xf0\x12\xe0\x10\x70\x01\x12\x02\x00\x12\x72\x0b\x50\x01\x0b\x01\x00\x0b\x62\x00\x00\x01\x1d\x0c\x00\x1d\x74\x0b\x00\x1d\x64\x0a\x00\x1d\x54\x09\x00\x1d\x34\x08\x00\x1d\x32\x19\xf0\x17\xe0\x15\xc0\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\x0d\x56\x00\x00\x17\x56\x00\x00\x82\xfa\x00\x00\x00\x00\x00\x00\x11\x1c\x0a\x00\x1c\x64\x0f\x00\x1c\x34\x0e\x00\x1c\x72\x18\xf0\x16\xe0\x14\xd0\x12\xc0\x10\x70\x58\x29\x00\x00\x01\x00\x00\x00\x56\x56\x00\x00\xaa\x57\x00\x00\x00\xfa\x00\x00\x00\x00\x00\x00\x09\x06\x02\x00\x06\x32\x02\x30\x58\x29\x00\x00\x01\x00\x00\x00\x24\x5c\x00\x00\x31\x5c\x00\x00\x01\x00\x00\x00\x31\x5c\x00\x00\x01\x1f\x0c\x00\x1f\x74\x11\x00\x1f\x64\x10\x00\x1f\x34\x0e\x00\x1f\x72\x18\xf0\x16\xe0\x14\xd0\x12\xc0\x10\x50\x19\x2e\x09\x00\x1d\x64\xc4\x00\x1d\x34\xc3\x00\x1d\x01\xbe\x00\x0e\xe0\x0c\x70\x0b\x50\x00\x00\xe0\xf0\x00\x00\xe0\x05\x00\x00\x01\x19\x0a\x00\x19\x74\x0b\x00\x19\x64\x0a\x00\x19\x54\x09\x00\x19\x34\x08\x00\x19\x52\x15\xe0\x01\x05\x02\x00\x05\x74\x01\x00\x01\x19\x0a\x00\x19\x74\x0f\x00\x19\x64\x0e\x00\x19\x54\x0d\x00\x19\x34\x0c\x00\x19\x92\x15\xe0\x01\x0a\x04\x00\x0a\x34\x07\x00\x0a\x32\x06\x70\x01\x1c\x0c\x00\x1c\x64\x0c\x00\x1c\x54\x0b\x00\x1c\x34\x0a\x00\x1c\x32\x18\xf0\x16\xe0\x14\xd0\x12\xc0\x10\x70\x11\x0a\x04\x00\x0a\x34\x08\x00\x0a\x52\x06\x70\x58\x29\x00\x00\x01\x00\x00\x00\x92\x6a\x00\x00\x11\x6b\x00\x00\x1d\xfa\x00\x00\x00\x00\x00\x00\x01\x0f\x06\x00\x0f\x64\x07\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x11\x14\x08\x00\x14\x64\x0e\x00\x14\x34\x0c\x00\x14\x72\x10\xf0\x0e\xe0\x0c\x70\x58\x29\x00\x00\x02\x00\x00\x00\x62\x6c\x00\x00\xa8\x6c\x00\x00\x36\xfa\x00\x00\x00\x00\x00\x00\x25\x6c\x00\x00\xb6\x6c\x00\x00\x50\xfa\x00\x00\x00\x00\x00\x00\x11\x06\x02\x00\x06\x32\x02\x30\x58\x29\x00\x00\x01\x00\x00\x00\x1a\x6f\x00\x00\x31\x6f\x00\x00\x69\xfa\x00\x00\x00\x00\x00\x00\x01\x1c\x0b\x00\x1c\x74\x17\x00\x1c\x64\x16\x00\x1c\x54\x15\x00\x1c\x34\x14\x00\x1c\x01\x12\x00\x15\xe0\x00\x00\x01\x15\x08\x00\x15\x74\x08\x00\x15\x64\x07\x00\x15\x34\x06\x00\x15\x32\x11\xe0\x01\x12\x06\x00\x12\x64\x13\x00\x12\x34\x11\x00\x12\xd2\x0b\x50\x01\x06\x02\x00\x06\x52\x02\x30\x01\x04\x01\x00\x04\x62\x00\x00\x01\x15\x06\x00\x15\x64\x10\x00\x15\x34\x0e\x00\x15\xb2\x11\x70\x01\x0f\x02\x00\x06\x32\x02\x50\x01\x09\x02\x00\x09\x92\x02\x50\x01\x09\x02\x00\x09\x72\x02\x50\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\xf1\x78\x00\x00\x01\x79\x00\x00\x82\xfa\x00\x00\x00\x00\x00\x00\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\xa9\x78\x00\x00\xbf\x78\x00\x00\x82\xfa\x00\x00\x00\x00\x00\x00\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\x49\x78\x00\x00\x79\x78\x00\x00\x82\xfa\x00\x00\x00\x00\x00\x00\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\x31\x79\x00\x00\x3f\x79\x00\x00\x82\xfa\x00\x00\x00\x00\x00\x00\x01\x1c\x0c\x00\x1c\x64\x14\x00\x1c\x54\x13\x00\x1c\x34\x12\x00\x1c\xb2\x18\xf0\x16\xe0\x14\xd0\x12\xc0\x10\x70\x19\x1c\x03\x00\x0e\x01\x18\x00\x02\x50\x00\x00\xe0\xf0\x00\x00\xb0\x00\x00\x00\x01\x19\x0a\x00\x19\x74\x0f\x00\x19\x64\x0e\x00\x19\x54\x0d\x00\x19\x34\x0c\x00\x19\x92\x15\xf0\x01\x14\x08\x00\x14\x64\x0e\x00\x14\x54\x0d\x00\x14\x34\x0c\x00\x14\x92\x10\x70\x01\x1d\x0c\x00\x1d\x74\x15\x00\x1d\x64\x14\x00\x1d\x54\x13\x00\x1d\x34\x12\x00\x1d\xd2\x19\xf0\x17\xe0\x15\xc0\x01\x19\x0a\x00\x19\x74\x0d\x00\x19\x64\x0c\x00\x19\x54\x0b\x00\x19\x34\x0a\x00\x19\x72\x15\xe0\x01\x15\x08\x00\x15\x64\x0e\x00\x15\x54\x0d\x00\x15\x34\x0c\x00\x15\x92\x11\xe0\x01\x09\x02\x00\x09\x32\x05\x30\x11\x06\x02\x00\x06\x32\x02\x70\x58\x29\x00\x00\x01\x00\x00\x00\xf1\x8b\x00\x00\x07\x8c\x00\x00\x9c\xfa\x00\x00\x00\x00\x00\x00\x11\x0a\x04\x00\x0a\x34\x07\x00\x0a\x32\x06\x70\x58\x29\x00\x00\x01\x00\x00\x00\x32\x94\x00\x00\x90\x94\x00\x00\xb5\xfa\x00\x00\x00\x00\x00\x00\x19\x25\x0a\x00\x16\x54\x11\x00\x16\x34\x10\x00\x16\x72\x12\xf0\x10\xe0\x0e\xc0\x0c\x70\x0b\x60\xe0\xf0\x00\x00\x38\x00\x00\x00\x19\x2b\x07\x00\x1a\x74\xf4\x00\x1a\x34\xf3\x00\x1a\x01\xf0\x00\x0b\x50\x00\x00\xe0\xf0\x00\x00\x70\x07\x00\x00\x01\x0f\x06\x00\x0f\x34\x0c\x00\x0f\x72\x08\x70\x07\x60\x06\x50\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\xed\x8c\x00\x00\xf6\x8c\x00\x00\x82\xfa\x00\x00\x00\x00\x00\x00\x11\x06\x02\x00\x06\x32\x02\x30\x58\x29\x00\x00\x01\x00\x00\x00\x8a\x9a\x00\x00\xa0\x9a\x00\x00\xce\xfa\x00\x00\x00\x00\x00\x00\x01\x07\x01\x00\x07\x42\x00\x00\x11\x10\x07\x00\x10\x82\x0c\xf0\x0a\xd0\x08\xc0\x06\x70\x05\x60\x04\x30\x00\x00\x58\x29\x00\x00\x01\x00\x00\x00\x5b\x9c\x00\x00\x55\x9d\x00\x00\xe4\xfa\x00\x00\x00\x00\x00\x00\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\xca\x9a\x00\x00\xe0\x9a\x00\x00\x82\xfa\x00\x00\x00\x00\x00\x00\x01\x0a\x04\x00\x0a\x34\x06\x00\x0a\x32\x06\x70\x19\x28\x08\x00\x1a\xe4\x15\x00\x1a\x74\x14\x00\x1a\x64\x13\x00\x1a\xf2\x10\x50\xe0\xf0\x00\x00\x70\x00\x00\x00\x01\x15\x09\x00\x15\x74\x05\x00\x15\x64\x04\x00\x15\x54\x03\x00\x15\x34\x02\x00\x15\xe0\x00\x00\x11\x0f\x04\x00\x0f\x34\x07\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\x66\xa1\x00\x00\x70\xa1\x00\x00\x08\xfb\x00\x00\x00\x00\x00\x00\x01\x08\x01\x00\x08\x62\x00\x00\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\xa5\xa1\x00\x00\x00\xa2\x00\x00\x37\xfb\x00\x00\x00\x00\x00\x00\x11\x1b\x0a\x00\x1b\x64\x0c\x00\x1b\x34\x0b\x00\x1b\x32\x17\xf0\x15\xe0\x13\xd0\x11\xc0\x0f\x70\x58\x29\x00\x00\x01\x00\x00\x00\xc6\xa8\x00\x00\xf6\xa8\x00\x00\x20\xfb\x00\x00\x00\x00\x00\x00\x01\x17\x0a\x00\x17\x34\x17\x00\x17\xb2\x10\xf0\x0e\xe0\x0c\xd0\x0a\xc0\x08\x70\x07\x60\x06\x50\x19\x28\x0a\x00\x1a\x34\x18\x00\x1a\xf2\x10\xf0\x0e\xe0\x0c\xd0\x0a\xc0\x08\x70\x07\x60\x06\x50\xe0\xf0\x00\x00\x70\x00\x00\x00\x19\x2d\x09\x00\x1b\x54\x90\x02\x1b\x34\x8e\x02\x1b\x01\x8a\x02\x0e\xe0\x0c\x70\x0b\x60\x00\x00\xe0\xf0\x00\x00\x40\x14\x00\x00\x19\x31\x0b\x00\x1f\x54\x96\x02\x1f\x34\x94\x02\x1f\x01\x8e\x02\x12\xf0\x10\xe0\x0e\xc0\x0c\x70\x0b\x60\x00\x00\xe0\xf0\x00\x00\x60\x14\x00\x00\x01\x14\x08\x00\x14\x64\x08\x00\x14\x54\x07\x00\x14\x34\x06\x00\x14\x32\x10\x70\x01\x14\x06\x00\x14\x64\x07\x00\x14\x34\x06\x00\x14\x32\x10\x70\x11\x15\x08\x00\x15\x74\x0a\x00\x15\x64\x09\x00\x15\x34\x08\x00\x15\x52\x11\xf0\x58\x29\x00\x00\x01\x00\x00\x00\x48\xad\x00\x00\x95\xad\x00\x00\x69\xfa\x00\x00\x00\x00\x00\x00\x01\x0f\x06\x00\x0f\x64\x11\x00\x0f\x34\x10\x00\x0f\xd2\x0b\x70\x19\x2d\x0d\x55\x1f\x74\x14\x00\x1b\x64\x13\x00\x17\x34\x12\x00\x13\x53\x0e\xb2\x0a\xf0\x08\xe0\x06\xd0\x04\xc0\x02\x50\x00\x00\xe0\xf0\x00\x00\x58\x00\x00\x00\x01\x0a\x02\x00\x0a\x32\x06\x30\x11\x0a\x04\x00\x0a\x34\x06\x00\x0a\x32\x06\x70\x58\x29\x00\x00\x01\x00\x00\x00\xd3\xb6\x00\x00\xe9\xb6\x00\x00\x9c\xfa\x00\x00\x00\x00\x00\x00\x19\x2d\x0a\x00\x1c\x01\xfb\x00\x0d\xf0\x0b\xe0\x09\xd0\x07\xc0\x05\x70\x04\x60\x03\x30\x02\x50\xe0\xf0\x00\x00\xc0\x07\x00\x00\x01\x59\x0e\x00\x59\xf4\x43\x00\x51\xe4\x44\x00\x49\xc4\x46\x00\x41\x54\x47\x00\x36\x34\x48\x00\x0e\x01\x49\x00\x07\x70\x06\x60\x21\x08\x02\x00\x08\xd4\x45\x00\x40\xb8\x00\x00\xa9\xb9\x00\x00\xe4\x8d\x01\x00\x21\x00\x00\x00\x40\xb8\x00\x00\xa9\xb9\x00\x00\xe4\x8d\x01\x00\x01\x17\x06\x00\x17\x64\x09\x00\x17\x34\x08\x00\x17\x32\x13\x70\x01\x0e\x02\x00\x0e\x32\x0a\x30\x01\x18\x06\x00\x18\x54\x07\x00\x18\x34\x06\x00\x18\x32\x14\x60\x19\x2d\x0d\x35\x1f\x74\x14\x00\x1b\x64\x13\x00\x17\x34\x12\x00\x13\x33\x0e\xb2\x0a\xf0\x08\xe0\x06\xd0\x04\xc0\x02\x50\x00\x00\xe0\xf0\x00\x00\x50\x00\x00\x00\x11\x0f\x04\x00\x0f\x34\x06\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\xd1\xd8\x00\x00\x11\xd9\x00\x00\x37\xfb\x00\x00\x00\x00\x00\x00\x11\x1b\x0a\x00\x1b\x64\x0c\x00\x1b\x34\x0b\x00\x1b\x32\x17\xf0\x15\xe0\x13\xd0\x11\xc0\x0f\x70\x58\x29\x00\x00\x01\x00\x00\x00\x4b\xdb\x00\x00\x7c\xdb\x00\x00\x20\xfb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x0a\x03\x00\x0a\x68\x02\x00\x04\xa2\x00\x00\x09\x19\x0a\x00\x19\x74\x0b\x00\x19\x64\x0a\x00\x19\x34\x09\x00\x19\x32\x15\xf0\x13\xe0\x11\xc0\x58\x29\x00\x00\x01\x00\x00\x00\xbe\xe7\x00\x00\xc7\xe7\x00\x00\x51\xfb\x00\x00\xc7\xe7\x00\x00\x01\x08\x02\x00\x08\x92\x04\x30\x19\x26\x09\x00\x18\x68\x0e\x00\x14\x01\x1e\x00\x09\xe0\x07\x70\x06\x60\x05\x30\x04\x50\x00\x00\xe0\xf0\x00\x00\xd0\x00\x00\x00\x01\x06\x02\x00\x06\x12\x02\x30\x01\x0b\x03\x00\x0b\x68\x05\x00\x07\xc2\x00\x00\x01\x04\x01\x00\x04\x02\x00\x00\x01\x1b\x08\x00\x1b\x74\x09\x00\x1b\x64\x08\x00\x1b\x34\x07\x00\x1b\x32\x14\x50\x09\x0f\x06\x00\x0f\x64\x09\x00\x0f\x34\x08\x00\x0f\x32\x0b\x70\x58\x29\x00\x00\x01\x00\x00\x00\x62\xf0\x00\x00\x69\xf0\x00\x00\x51\xfb\x00\x00\x69\xf0\x00\x00\x01\x02\x01\x00\x02\x30\x00\x00\x09\x0a\x04\x00\x0a\x34\x06\x00\x0a\x32\x06\x70\x58\x29\x00\x00\x01\x00\x00\x00\xbd\xf1\x00\x00\xf0\xf1\x00\x00\x80\xfb\x00\x00\xf0\xf1\x00\x00\x01\x04\x01\x00\x04\x12\x00\x00\x01\x00\x00\x00\x01\x04\x01\x00\x04\x22\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x7e\xb7\x57\x00\x00\x00\x00\x3a\x90\x01\x00\x01\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x08\x90\x01\x00\x1c\x90\x01\x00\x30\x90\x01\x00\xe0\x16\x00\x00\xb0\x14\x00\x00\x90\x18\x00\x00\xf0\x15\x00\x00\xa0\x16\x00\x00\x46\x90\x01\x00\x5e\x90\x01\x00\x69\x90\x01\x00\x6e\x90\x01\x00\x76\x90\x01\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x73\x79\x73\x74\x72\x61\x79\x2e\x64\x6c\x6c\x00\x61\x64\x64\x5f\x6f\x72\x5f\x75\x70\x64\x61\x74\x65\x5f\x6d\x65\x6e\x75\x5f\x69\x74\x65\x6d\x00\x6e\x61\x74\x69\x76\x65\x4c\x6f\x6f\x70\x00\x71\x75\x69\x74\x00\x73\x65\x74\x49\x63\x6f\x6e\x00\x73\x65\x74\x54\x6f\x6f\x6c\x74\x69\x70\x00\x00\x00\x00\xf8\x90\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x93\x01\x00\x10\x00\x01\x00\x10\x93\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x95\x01\x00\x28\x02\x01\x00\x00\x93\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x95\x01\x00\x18\x02\x01\x00\xe8\x90\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x9a\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x9a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\x93\x01\x00\x00\x00\x00\x00\xd0\x93\x01\x00\x00\x00\x00\x00\x0a\x9a\x01\x00\x00\x00\x00\x00\xfc\x99\x01\x00\x00\x00\x00\x00\xec\x99\x01\x00\x00\x00\x00\x00\xd8\x99\x01\x00\x00\x00\x00\x00\xca\x99\x01\x00\x00\x00\x00\x00\xbc\x99\x01\x00\x00\x00\x00\x00\xb0\x99\x01\x00\x00\x00\x00\x00\xa0\x99\x01\x00\x00\x00\x00\x00\x8e\x99\x01\x00\x00\x00\x00\x00\x7e\x99\x01\x00\x00\x00\x00\x00\x72\x99\x01\x00\x00\x00\x00\x00\x5e\x99\x01\x00\x00\x00\x00\x00\x4c\x99\x01\x00\x00\x00\x00\x00\x3a\x99\x01\x00\x00\x00\x00\x00\x28\x99\x01\x00\x00\x00\x00\x00\x16\x99\x01\x00\x00\x00\x00\x00\x9c\x95\x01\x00\x00\x00\x00\x00\xb0\x95\x01\x00\x00\x00\x00\x00\xca\x95\x01\x00\x00\x00\x00\x00\xde\x95\x01\x00\x00\x00\x00\x00\xfa\x95\x01\x00\x00\x00\x00\x00\x18\x96\x01\x00\x00\x00\x00\x00\x2c\x96\x01\x00\x00\x00\x00\x00\x40\x96\x01\x00\x00\x00\x00\x00\x5c\x96\x01\x00\x00\x00\x00\x00\x76\x96\x01\x00\x00\x00\x00\x00\x8c\x96\x01\x00\x00\x00\x00\x00\xa2\x96\x01\x00\x00\x00\x00\x00\xbc\x96\x01\x00\x00\x00\x00\x00\xd2\x96\x01\x00\x00\x00\x00\x00\xe6\x96\x01\x00\x00\x00\x00\x00\xf8\x96\x01\x00\x00\x00\x00\x00\x0e\x97\x01\x00\x00\x00\x00\x00\x1c\x97\x01\x00\x00\x00\x00\x00\x34\x97\x01\x00\x00\x00\x00\x00\x5c\x97\x01\x00\x00\x00\x00\x00\x68\x97\x01\x00\x00\x00\x00\x00\x76\x97\x01\x00\x00\x00\x00\x00\x84\x97\x01\x00\x00\x00\x00\x00\x8e\x97\x01\x00\x00\x00\x00\x00\x9c\x97\x01\x00\x00\x00\x00\x00\xae\x97\x01\x00\x00\x00\x00\x00\xc0\x97\x01\x00\x00\x00\x00\x00\xd0\x97\x01\x00\x00\x00\x00\x00\xe8\x97\x01\x00\x00\x00\x00\x00\x00\x98\x01\x00\x00\x00\x00\x00\x18\x98\x01\x00\x00\x00\x00\x00\x26\x98\x01\x00\x00\x00\x00\x00\x3c\x98\x01\x00\x00\x00\x00\x00\x52\x98\x01\x00\x00\x00\x00\x00\x68\x98\x01\x00\x00\x00\x00\x00\x74\x98\x01\x00\x00\x00\x00\x00\x80\x98\x01\x00\x00\x00\x00\x00\x90\x98\x01\x00\x00\x00\x00\x00\xa0\x98\x01\x00\x00\x00\x00\x00\xae\x98\x01\x00\x00\x00\x00\x00\xb8\x98\x01\x00\x00\x00\x00\x00\xca\x98\x01\x00\x00\x00\x00\x00\xd6\x98\x01\x00\x00\x00\x00\x00\xe2\x98\x01\x00\x00\x00\x00\x00\xfc\x98\x01\x00\x00\x00\x00\x00\xc0\x93\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x95\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x95\x01\x00\x00\x00\x00\x00\x4a\x95\x01\x00\x00\x00\x00\x00\x36\x95\x01\x00\x00\x00\x00\x00\x28\x95\x01\x00\x00\x00\x00\x00\x14\x95\x01\x00\x00\x00\x00\x00\x00\x95\x01\x00\x00\x00\x00\x00\xf2\x94\x01\x00\x00\x00\x00\x00\xe4\x94\x01\x00\x00\x00\x00\x00\xd2\x94\x01\x00\x00\x00\x00\x00\xb4\x94\x01\x00\x00\x00\x00\x00\xa2\x94\x01\x00\x00\x00\x00\x00\x8e\x94\x01\x00\x00\x00\x00\x00\x80\x94\x01\x00\x00\x00\x00\x00\x74\x94\x01\x00\x00\x00\x00\x00\x62\x94\x01\x00\x00\x00\x00\x00\x50\x94\x01\x00\x00\x00\x00\x00\x3c\x94\x01\x00\x00\x00\x00\x00\x2a\x94\x01\x00\x00\x00\x00\x00\x14\x94\x01\x00\x00\x00\x00\x00\x04\x94\x01\x00\x00\x00\x00\x00\xc2\x94\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x02\x47\x65\x74\x4c\x61\x73\x74\x45\x72\x72\x6f\x72\x00\x00\xa0\x01\x46\x6f\x72\x6d\x61\x74\x4d\x65\x73\x73\x61\x67\x65\x57\x00\x00\x6d\x02\x47\x65\x74\x4d\x6f\x64\x75\x6c\x65\x48\x61\x6e\x64\x6c\x65\x57\x00\x00\x4b\x45\x52\x4e\x45\x4c\x33\x32\x2e\x64\x6c\x6c\x00\x00\x35\x01\x47\x65\x74\x43\x75\x72\x73\x6f\x72\x50\x6f\x73\x00\x00\xdb\x02\x53\x65\x74\x46\x6f\x72\x65\x67\x72\x6f\x75\x6e\x64\x57\x69\x6e\x64\x6f\x77\x00\x41\x03\x54\x72\x61\x63\x6b\x50\x6f\x70\x75\x70\x4d\x65\x6e\x75\x00\x00\x6c\x01\x47\x65\x74\x4d\x65\x6e\x75\x49\x74\x65\x6d\x49\x6e\x66\x6f\x57\x00\x00\x75\x02\x50\x6f\x73\x74\x51\x75\x69\x74\x4d\x65\x73\x73\x61\x67\x65\x00\xa1\x00\x44\x65\x66\x57\x69\x6e\x64\x6f\x77\x50\x72\x6f\x63\x57\x00\x00\x27\x02\x4c\x6f\x61\x64\x49\x63\x6f\x6e\x57\x00\x25\x02\x4c\x6f\x61\x64\x43\x75\x72\x73\x6f\x72\x57\x00\x8d\x02\x52\x65\x67\x69\x73\x74\x65\x72\x43\x6c\x61\x73\x73\x45\x78\x57\x00\x00\x71\x00\x43\x72\x65\x61\x74\x65\x57\x69\x6e\x64\x6f\x77\x45\x78\x57\x00\x28\x03\x53\x68\x6f\x77\x57\x69\x6e\x64\x6f\x77\x00\x00\x5f\x03\x55\x70\x64\x61\x74\x65\x57\x69\x6e\x64\x6f\x77\x00\x00\x6e\x00\x43\x72\x65\x61\x74\x65\x50\x6f\x70\x75\x70\x4d\x65\x6e\x75\x00\xe8\x02\x53\x65\x74\x4d\x65\x6e\x75\x49\x6e\x66\x6f\x00\x75\x01\x47\x65\x74\x4d\x65\x73\x73\x61\x67\x65\x57\x00\x47\x03\x54\x72\x61\x6e\x73\x6c\x61\x74\x65\x4d\x65\x73\x73\x61\x67\x65\x00\x00\xb5\x00\x44\x69\x73\x70\x61\x74\x63\x68\x4d\x65\x73\x73\x61\x67\x65\x57\x00\x00\x29\x02\x4c\x6f\x61\x64\x49\x6d\x61\x67\x65\x57\x00\x00\x69\x01\x47\x65\x74\x4d\x65\x6e\x75\x49\x74\x65\x6d\x43\x6f\x75\x6e\x74\x00\x00\xeb\x02\x53\x65\x74\x4d\x65\x6e\x75\x49\x74\x65\x6d\x49\x6e\x66\x6f\x57\x00\x00\xee\x01\x49\x6e\x73\x65\x72\x74\x4d\x65\x6e\x75\x49\x74\x65\x6d\x57\x00\x55\x53\x45\x52\x33\x32\x2e\x64\x6c\x6c\x00\x00\x43\x01\x53\x68\x65\x6c\x6c\x5f\x4e\x6f\x74\x69\x66\x79\x49\x63\x6f\x6e\x57\x00\x53\x48\x45\x4c\x4c\x33\x32\x2e\x64\x6c\x6c\x00\xae\x04\x52\x74\x6c\x43\x61\x70\x74\x75\x72\x65\x43\x6f\x6e\x74\x65\x78\x74\x00\xb5\x04\x52\x74\x6c\x4c\x6f\x6f\x6b\x75\x70\x46\x75\x6e\x63\x74\x69\x6f\x6e\x45\x6e\x74\x72\x79\x00\x00\xbc\x04\x52\x74\x6c\x56\x69\x72\x74\x75\x61\x6c\x55\x6e\x77\x69\x6e\x64\x00\x00\x92\x05\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x46\x69\x6c\x74\x65\x72\x00\x00\x52\x05\x53\x65\x74\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x46\x69\x6c\x74\x65\x72\x00\x0f\x02\x47\x65\x74\x43\x75\x72\x72\x65\x6e\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x70\x05\x54\x65\x72\x6d\x69\x6e\x61\x74\x65\x50\x72\x6f\x63\x65\x73\x73\x00\x00\x70\x03\x49\x73\x50\x72\x6f\x63\x65\x73\x73\x6f\x72\x46\x65\x61\x74\x75\x72\x65\x50\x72\x65\x73\x65\x6e\x74\x00\x30\x04\x51\x75\x65\x72\x79\x50\x65\x72\x66\x6f\x72\x6d\x61\x6e\x63\x65\x43\x6f\x75\x6e\x74\x65\x72\x00\x10\x02\x47\x65\x74\x43\x75\x72\x72\x65\x6e\x74\x50\x72\x6f\x63\x65\x73\x73\x49\x64\x00\x14\x02\x47\x65\x74\x43\x75\x72\x72\x65\x6e\x74\x54\x68\x72\x65\x61\x64\x49\x64\x00\x00\xdd\x02\x47\x65\x74\x53\x79\x73\x74\x65\x6d\x54\x69\x6d\x65\x41\x73\x46\x69\x6c\x65\x54\x69\x6d\x65\x00\x54\x03\x49\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x53\x4c\x69\x73\x74\x48\x65\x61\x64\x00\x6a\x03\x49\x73\x44\x65\x62\x75\x67\x67\x65\x72\x50\x72\x65\x73\x65\x6e\x74\x00\xc5\x02\x47\x65\x74\x53\x74\x61\x72\x74\x75\x70\x49\x6e\x66\x6f\x57\x00\x69\x02\x47\x65\x74\x4d\x6f\x64\x75\x6c\x65\x46\x69\x6c\x65\x4e\x61\x6d\x65\x57\x00\x00\xbb\x04\x52\x74\x6c\x55\x6e\x77\x69\x6e\x64\x45\x78\x00\x58\x03\x49\x6e\x74\x65\x72\x6c\x6f\x63\x6b\x65\x64\x46\x6c\x75\x73\x68\x53\x4c\x69\x73\x74\x00\x51\x03\x49\x6e\x69\x74\x69\x61\x6c\x69\x7a\x65\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x41\x6e\x64\x53\x70\x69\x6e\x43\x6f\x75\x6e\x74\x00\x82\x05\x54\x6c\x73\x41\x6c\x6c\x6f\x63\x00\x00\x84\x05\x54\x6c\x73\x47\x65\x74\x56\x61\x6c\x75\x65\x00\x85\x05\x54\x6c\x73\x53\x65\x74\x56\x61\x6c\x75\x65\x00\x83\x05\x54\x6c\x73\x46\x72\x65\x65\x00\xa4\x01\x46\x72\x65\x65\x4c\x69\x62\x72\x61\x72\x79\x00\xa4\x02\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00\x00\xaa\x03\x4c\x6f\x61\x64\x4c\x69\x62\x72\x61\x72\x79\x45\x78\x57\x00\x00\x19\x05\x53\x65\x74\x4c\x61\x73\x74\x45\x72\x72\x6f\x72\x00\x00\x29\x01\x45\x6e\x74\x65\x72\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x00\x00\xa5\x03\x4c\x65\x61\x76\x65\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x00\x00\x06\x01\x44\x65\x6c\x65\x74\x65\x43\x72\x69\x74\x69\x63\x61\x6c\x53\x65\x63\x74\x69\x6f\x6e\x00\x57\x01\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x6c\x02\x47\x65\x74\x4d\x6f\x64\x75\x6c\x65\x48\x61\x6e\x64\x6c\x65\x45\x78\x57\x00\x00\xd4\x03\x4d\x75\x6c\x74\x69\x42\x79\x74\x65\x54\x6f\x57\x69\x64\x65\x43\x68\x61\x72\x00\xdd\x05\x57\x69\x64\x65\x43\x68\x61\x72\x54\x6f\x4d\x75\x6c\x74\x69\x42\x79\x74\x65\x00\x3c\x03\x48\x65\x61\x70\x46\x72\x65\x65\x00\x00\x38\x03\x48\x65\x61\x70\x41\x6c\x6c\x6f\x63\x00\x99\x03\x4c\x43\x4d\x61\x70\x53\x74\x72\x69\x6e\x67\x57\x00\x00\xc7\x02\x47\x65\x74\x53\x74\x64\x48\x61\x6e\x64\x6c\x65\x00\x00\x45\x02\x47\x65\x74\x46\x69\x6c\x65\x54\x79\x70\x65\x00\xaa\x01\x47\x65\x74\x41\x43\x50\x00\x00\x75\x03\x49\x73\x56\x61\x6c\x69\x64\x43\x6f\x64\x65\x50\x61\x67\x65\x00\x8d\x02\x47\x65\x74\x4f\x45\x4d\x43\x50\x00\x00\xb9\x01\x47\x65\x74\x43\x50\x49\x6e\x66\x6f\x00\x2e\x02\x47\x65\x74\x45\x6e\x76\x69\x72\x6f\x6e\x6d\x65\x6e\x74\x53\x74\x72\x69\x6e\x67\x73\x57\x00\x00\xa3\x01\x46\x72\x65\x65\x45\x6e\x76\x69\x72\x6f\x6e\x6d\x65\x6e\x74\x53\x74\x72\x69\x6e\x67\x73\x57\x00\xa9\x02\x47\x65\x74\x50\x72\x6f\x63\x65\x73\x73\x48\x65\x61\x70\x00\x00\xce\x01\x47\x65\x74\x43\x6f\x6d\x6d\x61\x6e\x64\x4c\x69\x6e\x65\x41\x00\xcf\x01\x47\x65\x74\x43\x6f\x6d\x6d\x61\x6e\x64\x4c\x69\x6e\x65\x57\x00\xcc\x02\x47\x65\x74\x53\x74\x72\x69\x6e\x67\x54\x79\x70\x65\x57\x00\x00\x98\x01\x46\x6c\x75\x73\x68\x46\x69\x6c\x65\x42\x75\x66\x66\x65\x72\x73\x00\x00\xf1\x05\x57\x72\x69\x74\x65\x46\x69\x6c\x65\x00\xe2\x01\x47\x65\x74\x43\x6f\x6e\x73\x6f\x6c\x65\x43\x50\x00\x00\xf4\x01\x47\x65\x74\x43\x6f\x6e\x73\x6f\x6c\x65\x4d\x6f\x64\x65\x00\x00\x30\x05\x53\x65\x74\x53\x74\x64\x48\x61\x6e\x64\x6c\x65\x00\x00\x41\x03\x48\x65\x61\x70\x53\x69\x7a\x65\x00\x00\x3f\x03\x48\x65\x61\x70\x52\x65\x41\x6c\x6c\x6f\x63\x00\x7f\x00\x43\x6c\x6f\x73\x65\x48\x61\x6e\x64\x6c\x65\x00\x0c\x05\x53\x65\x74\x46\x69\x6c\x65\x50\x6f\x69\x6e\x74\x65\x72\x45\x78\x00\x00\xf0\x05\x57\x72\x69\x74\x65\x43\x6f\x6e\x73\x6f\x6c\x65\x57\x00\xc2\x00\x43\x72\x65\x61\x74\x65\x46\x69\x6c\x65\x57\x00\x44\x04\x52\x61\x69\x73\x65\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x00\x00\x1a\x03\x53\x79\x73\x74\x65\x6d\x46\x75\x6e\x63\x74\x69\x6f\x6e\x30\x33\x36\x00\x41\x44\x56\x41\x50\x49\x33\x32\x2e\x64\x6c\x6c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x32\xa2\xdf\x2d\x99\x2b\x00\x00\xcd\x5d\x20\xd2\x66\xd4\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x2f\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7f\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x90\xec\x5e\x22\xc0\xb2\x44\xa5\xdd\xfd\x71\x6a\x22\x2a\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x26\x00\x80\x01\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x20\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x20\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x0c\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x0a\x0a\x0a\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x20\x01\x80\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\xa3\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\xa3\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\xa3\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\xa3\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\xa3\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x23\x01\x80\x01\x00\x00\x00\xb0\x24\x01\x80\x01\x00\x00\x00\xd0\x18\x01\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x01\x80\x01\x00\x00\x00\x70\xa3\x01\x80\x01\x00\x00\x00\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x00\x00\x00\x00\x00\x00\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\xa3\x01\x80\x01\x00\x00\x00\x01\x02\x04\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x03\x00\x00\x60\x82\x79\x82\x21\x00\x00\x00\x00\x00\x00\x00\xa6\xdf\x00\x00\x00\x00\x00\x00\xa1\xa5\x00\x00\x00\x00\x00\x00\x81\x9f\xe0\xfc\x00\x00\x00\x00\x40\x7e\x80\xfc\x00\x00\x00\x00\xa8\x03\x00\x00\xc1\xa3\xda\xa3\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xfe\x00\x00\x00\x00\x00\x00\x40\xfe\x00\x00\x00\x00\x00\x00\xb5\x03\x00\x00\xc1\xa3\xda\xa3\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xfe\x00\x00\x00\x00\x00\x00\x41\xfe\x00\x00\x00\x00\x00\x00\xb6\x03\x00\x00\xcf\xa2\xe4\xa2\x1a\x00\xe5\xa2\xe8\xa2\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xfe\x00\x00\x00\x00\x00\x00\x40\x7e\xa1\xfe\x00\x00\x00\x00\x51\x05\x00\x00\x51\xda\x5e\xda\x20\x00\x5f\xda\x6a\xda\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xd3\xd8\xde\xe0\xf9\x00\x00\x31\x7e\x81\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x00\x00\x00\x00\x00\x00\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x00\x00\x00\x00\x00\x00\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\xa9\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x04\xba\x01\x80\x01\x00\x00\x00\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x5c\xa9\x01\x80\x01\x00\x00\x00\x08\xba\x01\x80\x01\x00\x00\x00\x08\xba\x01\x80\x01\x00\x00\x00\x08\xba\x01\x80\x01\x00\x00\x00\x08\xba\x01\x80\x01\x00\x00\x00\x08\xba\x01\x80\x01\x00\x00\x00\x08\xba\x01\x80\x01\x00\x00\x00\x08\xba\x01\x80\x01\x00\x00\x00\x2e\x00\x00\x00\x2e\x00\x00\x00\xfe\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x7a\x10\x00\x00\x88\x88\x01\x00\x7c\x10\x00\x00\x3e\x11\x00\x00\x64\x85\x01\x00\x40\x11\x00\x00\xdb\x11\x00\x00\x60\x83\x01\x00\xf0\x11\x00\x00\x8b\x12\x00\x00\x60\x83\x01\x00\x90\x12\x00\x00\xc5\x12\x00\x00\x68\x83\x01\x00\xc5\x12\x00\x00\x24\x13\x00\x00\x70\x83\x01\x00\x24\x13\x00\x00\x30\x13\x00\x00\x84\x83\x01\x00\x30\x13\x00\x00\x9c\x13\x00\x00\x94\x83\x01\x00\xa0\x13\x00\x00\x2c\x14\x00\x00\x9c\x83\x01\x00\x30\x14\x00\x00\xab\x14\x00\x00\xa4\x83\x01\x00\xb0\x14\x00\x00\xe7\x15\x00\x00\xac\x83\x01\x00\xf0\x15\x00\x00\x1e\x16\x00\x00\xb8\x83\x01\x00\x1e\x16\x00\x00\x70\x16\x00\x00\xc0\x83\x01\x00\x70\x16\x00\x00\x98\x16\x00\x00\xd4\x83\x01\x00\xa0\x16\x00\x00\xdd\x16\x00\x00\x94\x83\x01\x00\xe0\x16\x00\x00\xea\x16\x00\x00\xe4\x83\x01\x00\xea\x16\x00\x00\x78\x17\x00\x00\xec\x83\x01\x00\x78\x17\x00\x00\x3a\x18\x00\x00\x0c\x84\x01\x00\x3a\x18\x00\x00\x5e\x18\x00\x00\x20\x84\x01\x00\x5e\x18\x00\x00\x81\x18\x00\x00\x30\x84\x01\x00\xc0\x18\x00\x00\x13\x19\x00\x00\x40\x84\x01\x00\x30\x19\x00\x00\x51\x19\x00\x00\x50\x84\x01\x00\x54\x19\x00\x00\xa4\x19\x00\x00\x94\x83\x01\x00\xa4\x19\x00\x00\xcf\x1a\x00\x00\x54\x84\x01\x00\xd0\x1a\x00\x00\x52\x1b\x00\x00\x80\x84\x01\x00\x54\x1b\x00\x00\x5c\x1c\x00\x00\xa8\x84\x01\x00\x5c\x1c\x00\x00\xb0\x1c\x00\x00\x10\x8d\x01\x00\xb0\x1c\x00\x00\xed\x1c\x00\x00\x88\x88\x01\x00\xf0\x1c\x00\x00\x24\x1d\x00\x00\x3c\x86\x01\x00\x24\x1d\x00\x00\xf5\x1d\x00\x00\xd8\x84\x01\x00\xf8\x1d\x00\x00\x69\x1e\x00\x00\xe0\x84\x01\x00\x6c\x1e\x00\x00\xa5\x1e\x00\x00\x94\x83\x01\x00\xa8\x1e\x00\x00\xc8\x1e\x00\x00\x94\x83\x01\x00\xc8\x1e\x00\x00\xdd\x1e\x00\x00\x94\x83\x01\x00\xe0\x1e\x00\x00\x08\x1f\x00\x00\x94\x83\x01\x00\x08\x1f\x00\x00\x1d\x1f\x00\x00\x94\x83\x01\x00\x20\x1f\x00\x00\x81\x1f\x00\x00\x10\x8d\x01\x00\x84\x1f\x00\x00\xb4\x1f\x00\x00\x94\x83\x01\x00\xb4\x1f\x00\x00\xc8\x1f\x00\x00\x94\x83\x01\x00\xc8\x1f\x00\x00\x11\x20\x00\x00\x3c\x86\x01\x00\x14\x20\x00\x00\xdd\x20\x00\x00\x14\x85\x01\x00\xe0\x20\x00\x00\x7c\x21\x00\x00\xec\x84\x01\x00\x7c\x21\x00\x00\xa0\x21\x00\x00\x3c\x86\x01\x00\xa0\x21\x00\x00\xcb\x21\x00\x00\x3c\x86\x01\x00\xcc\x21\x00\x00\x1b\x22\x00\x00\x3c\x86\x01\x00\x1c\x22\x00\x00\x33\x22\x00\x00\x94\x83\x01\x00\x34\x22\x00\x00\xe0\x22\x00\x00\x20\x85\x01\x00\x04\x23\x00\x00\x1f\x23\x00\x00\x94\x83\x01\x00\x30\x23\x00\x00\x75\x24\x00\x00\x2c\x85\x01\x00\x78\x24\x00\x00\xc2\x24\x00\x00\x88\x88\x01\x00\xc4\x24\x00\x00\x0e\x25\x00\x00\x88\x88\x01\x00\x18\x25\x00\x00\xd9\x26\x00\x00\x3c\x85\x01\x00\xf4\x26\x00\x00\x0c\x28\x00\x00\x4c\x85\x01\x00\x0c\x28\x00\x00\x24\x29\x00\x00\x4c\x85\x01\x00\x38\x29\x00\x00\x55\x29\x00\x00\x94\x83\x01\x00\x58\x29\x00\x00\x46\x2b\x00\x00\x80\x85\x01\x00\x48\x2b\x00\x00\x7f\x2b\x00\x00\x94\x83\x01\x00\x80\x2b\x00\x00\x94\x2b\x00\x00\x94\x83\x01\x00\x94\x2b\x00\x00\xa6\x2b\x00\x00\x94\x83\x01\x00\xa8\x2b\x00\x00\xd2\x2b\x00\x00\x3c\x86\x01\x00\xd4\x2b\x00\x00\xe4\x2b\x00\x00\x94\x83\x01\x00\xe4\x2b\x00\x00\x0e\x2c\x00\x00\x3c\x86\x01\x00\x20\x2c\x00\x00\xc0\x2d\x00\x00\xa0\x85\x01\x00\xc0\x2d\x00\x00\x88\x2f\x00\x00\x48\x88\x01\x00\x88\x2f\x00\x00\x09\x30\x00\x00\xa4\x85\x01\x00\x0c\x30\x00\x00\x8e\x30\x00\x00\xa4\x85\x01\x00\x90\x30\x00\x00\xe3\x30\x00\x00\xd4\x8b\x01\x00\xe4\x30\x00\x00\x7a\x31\x00\x00\x04\x88\x01\x00\x7c\x31\x00\x00\xd0\x31\x00\x00\xd4\x8b\x01\x00\xd0\x31\x00\x00\x24\x32\x00\x00\xd4\x8b\x01\x00\x24\x32\x00\x00\x78\x32\x00\x00\xd4\x8b\x01\x00\x78\x32\x00\x00\xdf\x32\x00\x00\x88\x88\x01\x00\xe0\x32\x00\x00\x57\x33\x00\x00\x10\x8d\x01\x00\x58\x33\x00\x00\x8d\x33\x00\x00\x1c\x88\x01\x00\x90\x33\x00\x00\xce\x33\x00\x00\xa0\x8a\x01\x00\xe0\x33\x00\x00\x04\x34\x00\x00\xc0\x85\x01\x00\x10\x34\x00\x00\x28\x34\x00\x00\xc8\x85\x01\x00\x30\x34\x00\x00\x31\x34\x00\x00\xcc\x85\x01\x00\x40\x34\x00\x00\x41\x34\x00\x00\xd0\x85\x01\x00\x44\x34\x00\x00\x63\x34\x00\x00\x94\x83\x01\x00\x64\x34\x00\x00\xb1\x34\x00\x00\x3c\x86\x01\x00\xb4\x34\x00\x00\x59\x35\x00\x00\x88\x88\x01\x00\x5c\x35\x00\x00\x9b\x35\x00\x00\x94\x83\x01\x00\x9c\x35\x00\x00\xbe\x35\x00\x00\x94\x83\x01\x00\xc0\x35\x00\x00\x06\x36\x00\x00\x3c\x86\x01\x00\x08\x36\x00\x00\x3f\x36\x00\x00\x3c\x86\x01\x00\x64\x36\x00\x00\x83\x37\x00\x00\xa4\x85\x01\x00\x98\x37\x00\x00\xf3\x37\x00\x00\x3c\x86\x01\x00\x0c\x38\x00\x00\x49\x38\x00\x00\x98\x86\x01\x00\x4c\x38\x00\x00\xf8\x38\x00\x00\x10\x8d\x01\x00\x28\x39\x00\x00\xc3\x39\x00\x00\x90\x86\x01\x00\xc4\x39\x00\x00\x60\x3a\x00\x00\x90\x86\x01\x00\x60\x3a\x00\x00\xe4\x3a\x00\x00\x78\x86\x01\x00\xe4\x3a\x00\x00\x60\x3b\x00\x00\x3c\x86\x01\x00\x60\x3b\x00\x00\xf0\x3b\x00\x00\xd4\x8b\x01\x00\xf0\x3b\x00\x00\xde\x3c\x00\x00\x5c\x86\x01\x00\xe0\x3c\x00\x00\x4d\x3d\x00\x00\xd4\x8b\x01\x00\x50\x3d\x00\x00\xd3\x3d\x00\x00\x04\x86\x01\x00\xd4\x3d\x00\x00\xe3\x3f\x00\x00\xf4\x85\x01\x00\xe4\x3f\x00\x00\x53\x40\x00\x00\x3c\x86\x01\x00\x54\x40\x00\x00\xe6\x40\x00\x00\x3c\x86\x01\x00\xe8\x40\x00\x00\x63\x42\x00\x00\x94\x83\x01\x00\x64\x42\x00\x00\xdd\x44\x00\x00\x18\x86\x01\x00\xe0\x44\x00\x00\x5f\x45\x00\x00\x88\x88\x01\x00\x60\x45\x00\x00\x7a\x47\x00\x00\x30\x86\x01\x00\x7c\x47\x00\x00\x2e\x48\x00\x00\xd4\x8b\x01\x00\x30\x48\x00\x00\xcf\x49\x00\x00\x3c\x86\x01\x00\xd0\x49\x00\x00\xab\x4a\x00\x00\x88\x88\x01\x00\xac\x4a\x00\x00\x3c\x4b\x00\x00\x88\x88\x01\x00\x3c\x4b\x00\x00\xc8\x4b\x00\x00\x94\x83\x01\x00\xc8\x4b\x00\x00\x9d\x4c\x00\x00\x44\x86\x01\x00\xa0\x4c\x00\x00\x95\x4d\x00\x00\xdc\x85\x01\x00\x98\x4d\x00\x00\x23\x4e\x00\x00\xd4\x85\x01\x00\x24\x4e\x00\x00\x07\x4f\x00\x00\xd4\x8b\x01\x00\x08\x4f\x00\x00\x7e\x4f\x00\x00\xa4\x85\x01\x00\x80\x4f\x00\x00\xcc\x4f\x00\x00\x88\x88\x01\x00\xe0\x4f\x00\x00\x6d\x51\x00\x00\x10\x8d\x01\x00\x7c\x51\x00\x00\xe8\x52\x00\x00\xc4\x86\x01\x00\xe8\x52\x00\x00\x31\x53\x00\x00\x3c\x86\x01\x00\x34\x53\x00\x00\xa0\x53\x00\x00\xd4\x8b\x01\x00\xcc\x53\x00\x00\x38\x54\x00\x00\xd4\x8b\x01\x00\x38\x54\x00\x00\x31\x55\x00\x00\x10\x87\x01\x00\x34\x55\x00\x00\x75\x55\x00\x00\x04\x87\x01\x00\x78\x55\x00\x00\x92\x55\x00\x00\x94\x83\x01\x00\x94\x55\x00\x00\xae\x55\x00\x00\x94\x83\x01\x00\xb0\x55\x00\x00\xe8\x55\x00\x00\x94\x83\x01\x00\xf0\x55\x00\x00\x2b\x56\x00\x00\x54\x87\x01\x00\x2c\x56\x00\x00\xcb\x57\x00\x00\x78\x87\x01\x00\xcc\x57\x00\x00\xa6\x59\x00\x00\x38\x87\x01\x00\xb8\x59\x00\x00\xf2\x59\x00\x00\x30\x87\x01\x00\x34\x5a\x00\x00\x7c\x5a\x00\x00\x28\x87\x01\x00\x90\x5a\x00\x00\xb3\x5a\x00\x00\x94\x83\x01\x00\xb4\x5a\x00\x00\xc4\x5a\x00\x00\x94\x83\x01\x00\xc4\x5a\x00\x00\x15\x5b\x00\x00\x3c\x86\x01\x00\x20\x5b\x00\x00\xae\x5b\x00\x00\x3c\x86\x01\x00\xc8\x5b\x00\x00\xdc\x5b\x00\x00\x94\x83\x01\x00\xdc\x5b\x00\x00\xec\x5b\x00\x00\x94\x83\x01\x00\x00\x5c\x00\x00\x10\x5c\x00\x00\x94\x83\x01\x00\x10\x5c\x00\x00\x37\x5c\x00\x00\xa8\x87\x01\x00\x38\x5c\x00\x00\x75\x5c\x00\x00\x98\x8d\x01\x00\x78\x5c\x00\x00\xd6\x5c\x00\x00\x3c\x86\x01\x00\xd8\x5c\x00\x00\x37\x5d\x00\x00\x3c\x86\x01\x00\x38\x5d\x00\x00\x8d\x5d\x00\x00\x94\x83\x01\x00\x90\x5d\x00\x00\x05\x5e\x00\x00\x3c\x86\x01\x00\x34\x5e\x00\x00\x47\x61\x00\x00\xc8\x87\x01\x00\x48\x61\x00\x00\xa3\x62\x00\x00\xe4\x87\x01\x00\xac\x62\x00\x00\x53\x63\x00\x00\x04\x88\x01\x00\x54\x63\x00\x00\x72\x63\x00\x00\x3c\x89\x01\x00\x74\x63\x00\x00\xba\x63\x00\x00\x94\x83\x01\x00\x04\x64\x00\x00\x52\x64\x00\x00\xd4\x8b\x01\x00\x54\x64\x00\x00\x74\x64\x00\x00\x94\x83\x01\x00\x74\x64\x00\x00\x94\x64\x00\x00\x94\x83\x01\x00\x94\x64\x00\x00\x34\x66\x00\x00\x48\x88\x01\x00\x34\x66\x00\x00\x89\x66\x00\x00\xd4\x8b\x01\x00\x8c\x66\x00\x00\xe1\x66\x00\x00\xd4\x8b\x01\x00\xe4\x66\x00\x00\x39\x67\x00\x00\xd4\x8b\x01\x00\x3c\x67\x00\x00\xa4\x67\x00\x00\x88\x88\x01\x00\xa4\x67\x00\x00\x1c\x68\x00\x00\x10\x8d\x01\x00\x1c\x68\x00\x00\x0b\x69\x00\x00\x24\x88\x01\x00\x0c\x69\x00\x00\x71\x69\x00\x00\x88\x88\x01\x00\x74\x69\x00\x00\xab\x69\x00\x00\x1c\x88\x01\x00\xac\x69\x00\x00\x31\x6a\x00\x00\x3c\x88\x01\x00\x34\x6a\x00\x00\x75\x6a\x00\x00\x3c\x86\x01\x00\x78\x6a\x00\x00\x2a\x6b\x00\x00\x64\x88\x01\x00\x2c\x6b\x00\x00\xa3\x6b\x00\x00\x88\x88\x01\x00\xa4\x6b\x00\x00\xef\x6b\x00\x00\x3c\x86\x01\x00\xfc\x6b\x00\x00\xe0\x6c\x00\x00\x98\x88\x01\x00\xe0\x6c\x00\x00\x20\x6d\x00\x00\x3c\x86\x01\x00\x20\x6d\x00\x00\x0b\x6e\x00\x00\xf4\x88\x01\x00\x0c\x6e\x00\x00\x07\x6f\x00\x00\x10\x89\x01\x00\x08\x6f\x00\x00\x43\x6f\x00\x00\xd4\x88\x01\x00\x44\x6f\x00\x00\x84\x6f\x00\x00\xd4\x8b\x01\x00\x84\x6f\x00\x00\xf8\x6f\x00\x00\x60\x83\x01\x00\xf8\x6f\x00\x00\x45\x70\x00\x00\xd4\x8b\x01\x00\x48\x70\x00\x00\x86\x71\x00\x00\x24\x89\x01\x00\x88\x71\x00\x00\xb3\x71\x00\x00\x94\x83\x01\x00\xc8\x71\x00\x00\xf7\x71\x00\x00\x34\x89\x01\x00\xf8\x71\x00\x00\x40\x73\x00\x00\x24\x88\x01\x00\x48\x73\x00\x00\xcc\x74\x00\x00\x44\x89\x01\x00\xcc\x74\x00\x00\xe0\x74\x00\x00\x3c\x89\x01\x00\xe0\x74\x00\x00\x39\x76\x00\x00\x54\x89\x01\x00\x3c\x76\x00\x00\x2c\x78\x00\x00\x54\x89\x01\x00\x2c\x78\x00\x00\x8b\x78\x00\x00\xb4\x89\x01\x00\x8c\x78\x00\x00\xd1\x78\x00\x00\x90\x89\x01\x00\xd4\x78\x00\x00\x13\x79\x00\x00\x6c\x89\x01\x00\x14\x79\x00\x00\x51\x79\x00\x00\xd8\x89\x01\x00\x54\x79\x00\x00\x21\x7a\x00\x00\x5c\x89\x01\x00\x24\x7a\x00\x00\x44\x7a\x00\x00\x98\x8d\x01\x00\x44\x7a\x00\x00\x39\x7b\x00\x00\x64\x89\x01\x00\x3c\x7b\x00\x00\xa3\x7b\x00\x00\xd4\x8b\x01\x00\xa4\x7b\x00\x00\xe5\x7b\x00\x00\x3c\x86\x01\x00\xe8\x7b\x00\x00\x7c\x7c\x00\x00\xd4\x8b\x01\x00\x7c\x7c\x00\x00\x1b\x7d\x00\x00\x88\x88\x01\x00\x1c\x7d\x00\x00\x55\x7d\x00\x00\x94\x83\x01\x00\x58\x7d\x00\x00\x7a\x7d\x00\x00\x94\x83\x01\x00\x7c\x7d\x00\x00\xad\x7d\x00\x00\x3c\x86\x01\x00\xb0\x7d\x00\x00\xe1\x7d\x00\x00\x3c\x86\x01\x00\x4c\x7e\x00\x00\xa9\x81\x00\x00\x58\x8a\x01\x00\xac\x81\x00\x00\x79\x82\x00\x00\x44\x8a\x01\x00\x7c\x82\x00\x00\x57\x84\x00\x00\x2c\x8a\x01\x00\x58\x84\x00\x00\xa0\x85\x00\x00\x74\x8a\x01\x00\xa0\x85\x00\x00\xd7\x86\x00\x00\x8c\x8a\x01\x00\xd8\x86\x00\x00\x1a\x88\x00\x00\x18\x8a\x01\x00\x1c\x88\x00\x00\x5d\x8a\x00\x00\xfc\x89\x01\x00\x60\x8a\x00\x00\x86\x8a\x00\x00\x94\x83\x01\x00\xb8\x8a\x00\x00\x87\x8b\x00\x00\xd4\x8b\x01\x00\x88\x8b\x00\x00\xc1\x8b\x00\x00\xa0\x8a\x01\x00\xd0\x8b\x00\x00\x17\x8c\x00\x00\xa8\x8a\x01\x00\x18\x8c\x00\x00\x60\x8c\x00\x00\x3c\x86\x01\x00\x7c\x8c\x00\x00\xb3\x8c\x00\x00\x3c\x86\x01\x00\xd0\x8c\x00\x00\x08\x8d\x00\x00\x38\x8b\x01\x00\x08\x8d\x00\x00\x1f\x8f\x00\x00\x88\x88\x01\x00\x20\x8f\x00\x00\x9d\x8f\x00\x00\x60\x83\x01\x00\xa0\x8f\x00\x00\x30\x90\x00\x00\x10\x8d\x01\x00\x30\x90\x00\x00\x12\x92\x00\x00\x0c\x8b\x01\x00\x14\x92\x00\x00\xc9\x93\x00\x00\x28\x8b\x01\x00\xcc\x93\x00\x00\xf3\x93\x00\x00\x94\x83\x01\x00\xf4\x93\x00\x00\xb3\x94\x00\x00\xc8\x8a\x01\x00\xb4\x94\x00\x00\x5b\x97\x00\x00\xec\x8a\x01\x00\x5c\x97\x00\x00\x5f\x98\x00\x00\x74\x8a\x01\x00\x68\x98\x00\x00\xfd\x98\x00\x00\x10\x8d\x01\x00\x00\x99\x00\x00\x1c\x99\x00\x00\x94\x83\x01\x00\x28\x99\x00\x00\x4d\x99\x00\x00\x94\x83\x01\x00\x50\x99\x00\x00\xe4\x99\x00\x00\x10\x8d\x01\x00\xe4\x99\x00\x00\x33\x9a\x00\x00\x88\x88\x01\x00\x3c\x9a\x00\x00\x7c\x9a\x00\x00\xd4\x8b\x01\x00\x7c\x9a\x00\x00\xb0\x9a\x00\x00\x5c\x8b\x01\x00\xb0\x9a\x00\x00\xf5\x9a\x00\x00\xb0\x8b\x01\x00\xf8\x9a\x00\x00\x26\x9b\x00\x00\x7c\x8b\x01\x00\x48\x9b\x00\x00\xe1\x9d\x00\x00\x84\x8b\x01\x00\x0c\x9e\x00\x00\x51\x9e\x00\x00\xd4\x8b\x01\x00\x5c\x9e\x00\x00\x8b\x9e\x00\x00\x94\x83\x01\x00\x8c\x9e\x00\x00\x9b\x9f\x00\x00\xe0\x8b\x01\x00\x9c\x9f\x00\x00\x63\xa0\x00\x00\xfc\x8b\x01\x00\x64\xa0\x00\x00\x96\xa0\x00\x00\x94\x83\x01\x00\x98\xa0\x00\x00\x1b\xa1\x00\x00\xd4\x8b\x01\x00\x1c\xa1\x00\x00\x85\xa1\x00\x00\x14\x8c\x01\x00\x88\xa1\x00\x00\x14\xa2\x00\x00\x40\x8c\x01\x00\x14\xa2\x00\x00\xa5\xa2\x00\x00\x38\x8c\x01\x00\xa8\xa2\x00\x00\xb0\xa4\x00\x00\xac\x8c\x01\x00\xb0\xa4\x00\x00\xb5\xa5\x00\x00\xcc\x8c\x01\x00\xb8\xa5\x00\x00\xd4\xa6\x00\x00\xcc\x8c\x01\x00\xd4\xa6\x00\x00\x46\xa8\x00\x00\xec\x8c\x01\x00\x48\xa8\x00\x00\x34\xa9\x00\x00\x64\x8c\x01\x00\x34\xa9\x00\x00\x15\xac\x00\x00\x94\x8c\x01\x00\x18\xac\x00\x00\xad\xac\x00\x00\x10\x8d\x01\x00\xb0\xac\x00\x00\x00\xad\x00\x00\x24\x8d\x01\x00\x00\xad\x00\x00\xb7\xad\x00\x00\x34\x8d\x01\x00\x00\xae\x00\x00\xba\xae\x00\x00\x10\x89\x01\x00\xbc\xae\x00\x00\x31\xaf\x00\x00\x94\x83\x01\x00\x34\xaf\x00\x00\x73\xaf\x00\x00\x60\x83\x01\x00\x74\xaf\x00\x00\xcf\xb2\x00\x00\x70\x8d\x01\x00\xd0\xb2\x00\x00\x66\xb3\x00\x00\x60\x8d\x01\x00\xf4\xb3\x00\x00\x6a\xb5\x00\x00\x10\x8d\x01\x00\x94\xb5\x00\x00\xca\xb5\x00\x00\x98\x8d\x01\x00\xf4\xb5\x00\x00\x9c\xb6\x00\x00\x94\x83\x01\x00\x9c\xb6\x00\x00\x0c\xb7\x00\x00\xa0\x8d\x01\x00\x0c\xb7\x00\x00\x74\xb7\x00\x00\xd4\x8b\x01\x00\x74\xb7\x00\x00\x33\xb8\x00\x00\x3c\x86\x01\x00\x40\xb8\x00\x00\xa9\xb9\x00\x00\xe4\x8d\x01\x00\xa9\xb9\x00\x00\xdc\xbc\x00\x00\x04\x8e\x01\x00\xdc\xbc\x00\x00\x0e\xbd\x00\x00\x18\x8e\x01\x00\x10\xbd\x00\x00\x7b\xd0\x00\x00\xc4\x8d\x01\x00\x7c\xd0\x00\x00\x03\xd1\x00\x00\x88\x88\x01\x00\x04\xd1\x00\x00\x08\xd2\x00\x00\x28\x8e\x01\x00\x08\xd2\x00\x00\xf0\xd2\x00\x00\x88\x88\x01\x00\xf0\xd2\x00\x00\x4f\xd3\x00\x00\x94\x83\x01\x00\x50\xd3\x00\x00\x5a\xd4\x00\x00\x38\x8e\x01\x00\x5c\xd4\x00\x00\xc8\xd4\x00\x00\x98\x8d\x01\x00\xc8\xd4\x00\x00\x1e\xd5\x00\x00\x88\x88\x01\x00\x20\xd5\x00\x00\x28\xd6\x00\x00\x40\x8e\x01\x00\x28\xd6\x00\x00\xd9\xd7\x00\x00\x50\x8e\x01\x00\xdc\xd7\x00\x00\xf3\xd7\x00\x00\x94\x83\x01\x00\xf4\xd7\x00\x00\x2d\xd8\x00\x00\x94\x83\x01\x00\x30\xd8\x00\x00\xb2\xd8\x00\x00\xd4\x8b\x01\x00\xb4\xd8\x00\x00\x25\xd9\x00\x00\x78\x8e\x01\x00\x28\xd9\x00\x00\xc9\xd9\x00\x00\x38\x8c\x01\x00\xcc\xd9\x00\x00\x86\xda\x00\x00\xd4\x8b\x01\x00\xcc\xda\x00\x00\xbc\xdb\x00\x00\x9c\x8e\x01\x00\xbc\xdb\x00\x00\x55\xdc\x00\x00\x88\x88\x01\x00\x68\xdc\x00\x00\xc1\xdc\x00\x00\xd8\x84\x01\x00\xe4\xdc\x00\x00\x04\xdd\x00\x00\x3c\x86\x01\x00\x04\xdd\x00\x00\x50\xdd\x00\x00\x3c\x86\x01\x00\x50\xdd\x00\x00\xa0\xdd\x00\x00\x3c\x86\x01\x00\x70\xde\x00\x00\x1b\xe4\x00\x00\xd0\x8e\x01\x00\x1c\xe4\x00\x00\x7d\xe4\x00\x00\x3c\x86\x01\x00\x80\xe4\x00\x00\xbb\xe4\x00\x00\xb8\x83\x01\x00\xbc\xe4\x00\x00\xdc\xe4\x00\x00\x94\x83\x01\x00\xdc\xe4\x00\x00\xf3\xe4\x00\x00\x94\x83\x01\x00\xf4\xe4\x00\x00\x05\xe5\x00\x00\x94\x83\x01\x00\x14\xe5\x00\x00\x64\xe5\x00\x00\x3c\x86\x01\x00\x64\xe5\x00\x00\xb6\xe5\x00\x00\x3c\x86\x01\x00\x0c\xe6\x00\x00\xa2\xe8\x00\x00\xdc\x8e\x01\x00\xa4\xe8\x00\x00\x09\xe9\x00\x00\x0c\x8f\x01\x00\x0c\xe9\x00\x00\xc5\xe9\x00\x00\x88\x88\x01\x00\xc8\xe9\x00\x00\xef\xea\x00\x00\x14\x8f\x01\x00\x10\xeb\x00\x00\x80\xeb\x00\x00\x34\x8f\x01\x00\x80\xeb\x00\x00\xa0\xeb\x00\x00\x3c\x89\x01\x00\xa0\xeb\x00\x00\x36\xec\x00\x00\x3c\x8f\x01\x00\x50\xec\x00\x00\x60\xec\x00\x00\x48\x8f\x01\x00\xa0\xec\x00\x00\xc7\xec\x00\x00\xb8\x83\x01\x00\xc8\xec\x00\x00\xce\xef\x00\x00\x50\x8f\x01\x00\xd0\xef\x00\x00\xfe\xef\x00\x00\x94\x83\x01\x00\x00\xf0\x00\x00\x1d\xf0\x00\x00\x3c\x86\x01\x00\x20\xf0\x00\x00\x9c\xf0\x00\x00\x64\x8f\x01\x00\x9c\xf0\x00\x00\xbb\xf0\x00\x00\x3c\x86\x01\x00\xbc\xf0\x00\x00\xcd\xf0\x00\x00\x94\x83\x01\x00\xe0\xf0\x00\x00\xfd\xf0\x00\x00\x94\x83\x01\x00\x00\xf1\x00\x00\x5b\xf1\x00\x00\x8c\x8f\x01\x00\xb0\xf1\x00\x00\xfd\xf1\x00\x00\x94\x8f\x01\x00\x40\xf2\x00\x00\x91\xf2\x00\x00\xb8\x8f\x01\x00\xb0\xf2\x00\x00\xe5\xf6\x00\x00\xc0\x8f\x01\x00\xe8\xf6\x00\x00\x2c\xf8\x00\x00\xc4\x8f\x01\x00\x40\xf8\x00\x00\x07\xf9\x00\x00\xd0\x8f\x01\x00\x20\xf9\x00\x00\x22\xf9\x00\x00\x48\x85\x01\x00\x30\xf9\x00\x00\x47\xf9\x00\x00\xbc\x86\x01\x00\x47\xf9\x00\x00\x63\xf9\x00\x00\xbc\x86\x01\x00\x63\xf9\x00\x00\x99\xf9\x00\x00\xd0\x84\x01\x00\x99\xf9\x00\x00\xb1\xf9\x00\x00\x0c\x85\x01\x00\xb1\xf9\x00\x00\xcc\xf9\x00\x00\xbc\x86\x01\x00\xcc\xf9\x00\x00\xe7\xf9\x00\x00\xbc\x86\x01\x00\xe7\xf9\x00\x00\x00\xfa\x00\x00\xbc\x86\x01\x00\x00\xfa\x00\x00\x1d\xfa\x00\x00\xbc\x86\x01\x00\x1d\xfa\x00\x00\x36\xfa\x00\x00\xbc\x86\x01\x00\x36\xfa\x00\x00\x50\xfa\x00\x00\xbc\x86\x01\x00\x50\xfa\x00\x00\x69\xfa\x00\x00\xbc\x86\x01\x00\x69\xfa\x00\x00\x82\xfa\x00\x00\xbc\x86\x01\x00\x82\xfa\x00\x00\x9c\xfa\x00\x00\xbc\x86\x01\x00\x9c\xfa\x00\x00\xb5\xfa\x00\x00\xbc\x86\x01\x00\xb5\xfa\x00\x00\xce\xfa\x00\x00\xbc\x86\x01\x00\xce\xfa\x00\x00\xe4\xfa\x00\x00\xbc\x86\x01\x00\xe4\xfa\x00\x00\x08\xfb\x00\x00\xbc\x86\x01\x00\x08\xfb\x00\x00\x20\xfb\x00\x00\xbc\x86\x01\x00\x20\xfb\x00\x00\x37\xfb\x00\x00\xbc\x86\x01\x00\x37\xfb\x00\x00\x51\xfb\x00\x00\xbc\x86\x01\x00\x51\xfb\x00\x00\x7d\xfb\x00\x00\xbc\x86\x01\x00\x80\xfb\x00\x00\xa0\xfb\x00\x00\xbc\x86\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x5b\x00\x00\x90\x5a\x00\x00\xb4\x5a\x00\x00\xb0\x5b\x00\x00\x20\x5b\x00\x00\xb0\x5b\x00\x00\xcc\x93\x00\x00\xb0\x5b\x00\x00\x28\x99\x00\x00\x44\x6f\x00\x00\x08\x6f\x00\x00\x58\x7d\x00\x00\x1c\x7d\x00\x00\x18\x5b\x00\x00\x1c\x99\x00\x00\x00\x99\x00\x00\x7c\x8c\x00\x00\x18\x8c\x00\x00\xb0\x5b\x00\x00\xb0\x5b\x00\x00\x34\x6a\x00\x00\x74\x69\x00\x00\xc4\x5a\x00\x00\x7c\x5a\x00\x00\x64\x36\x00\x00\x98\x37\x00\x00\x24\x7a\x00\x00\xd0\x8b\x00\x00\xdc\xd7\x00\x00\xbc\xe4\x00\x00\x10\xeb\x00\x00\x36\x00\x00\x00\x49\x00\x00\x00\x4c\x00\x00\x00\x0b\x00\x00\x00\x0d\x00\x00\x00\x64\x00\x00\x00\x51\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x18\x00\x00\x00\x18\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00\x30\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x09\x04\x00\x00\x48\x00\x00\x00\x60\xe0\x01\x00\x7d\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\x2d\x38\x27\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x27\x79\x65\x73\x27\x3f\x3e\x0d\x0a\x3c\x61\x73\x73\x65\x6d\x62\x6c\x79\x20\x78\x6d\x6c\x6e\x73\x3d\x27\x75\x72\x6e\x3a\x73\x63\x68\x65\x6d\x61\x73\x2d\x6d\x69\x63\x72\x6f\x73\x6f\x66\x74\x2d\x63\x6f\x6d\x3a\x61\x73\x6d\x2e\x76\x31\x27\x20\x6d\x61\x6e\x69\x66\x65\x73\x74\x56\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\x30\x27\x3e\x0d\x0a\x20\x20\x3c\x74\x72\x75\x73\x74\x49\x6e\x66\x6f\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x75\x72\x6e\x3a\x73\x63\x68\x65\x6d\x61\x73\x2d\x6d\x69\x63\x72\x6f\x73\x6f\x66\x74\x2d\x63\x6f\x6d\x3a\x61\x73\x6d\x2e\x76\x33\x22\x3e\x0d\x0a\x20\x20\x20\x20\x3c\x73\x65\x63\x75\x72\x69\x74\x79\x3e\x0d\x0a\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x71\x75\x65\x73\x74\x65\x64\x50\x72\x69\x76\x69\x6c\x65\x67\x65\x73\x3e\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3c\x72\x65\x71\x75\x65\x73\x74\x65\x64\x45\x78\x65\x63\x75\x74\x69\x6f\x6e\x4c\x65\x76\x65\x6c\x20\x6c\x65\x76\x65\x6c\x3d\x27\x61\x73\x49\x6e\x76\x6f\x6b\x65\x72\x27\x20\x75\x69\x41\x63\x63\x65\x73\x73\x3d\x27\x66\x61\x6c\x73\x65\x27\x20\x2f\x3e\x0d\x0a\x20\x20\x20\x20\x20\x20\x3c\x2f\x72\x65\x71\x75\x65\x73\x74\x65\x64\x50\x72\x69\x76\x69\x6c\x65\x67\x65\x73\x3e\x0d\x0a\x20\x20\x20\x20\x3c\x2f\x73\x65\x63\x75\x72\x69\x74\x79\x3e\x0d\x0a\x20\x20\x3c\x2f\x74\x72\x75\x73\x74\x49\x6e\x66\x6f\x3e\x0d\x0a\x3c\x2f\x61\x73\x73\x65\x6d\x62\x6c\x79\x3e\x0d\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xf0\x00\x00\x00\xd8\xa2\xe0\xa2\x00\xa3\x08\xa3\x10\xa3\x28\xa3\x30\xa3\x38\xa3\x68\xa3\x70\xa3\x78\xa3\xa8\xa3\xb0\xa3\xb8\xa3\xc0\xa3\x20\xaa\x28\xaa\x30\xaa\x38\xaa\x40\xaa\x50\xaa\x58\xaa\x60\xaa\x68\xaa\x70\xaa\x78\xaa\x80\xaa\x88\xaa\x90\xaa\x98\xaa\xa0\xaa\xa8\xaa\xb0\xaa\xb8\xaa\xc0\xaa\xc8\xaa\xd0\xaa\xd8\xaa\xe0\xaa\xe8\xaa\xf0\xaa\xf8\xaa\x00\xab\x08\xab\x10\xab\x18\xab\x20\xab\x28\xab\x30\xab\x38\xab\x40\xab\x48\xab\x50\xab\x58\xab\x60\xab\x68\xab\x70\xab\x78\xab\x80\xab\x88\xab\x90\xab\x98\xab\xa0\xab\xa8\xab\xb0\xab\xb8\xab\xc0\xab\xc8\xab\xd0\xab\xd8\xab\xe0\xab\xe8\xab\xf0\xab\xf8\xab\x00\xac\x08\xac\x10\xac\x18\xac\x20\xac\x28\xac\x30\xac\x38\xac\x40\xac\x48\xac\x50\xac\x58\xac\x60\xac\x68\xac\x70\xac\x78\xac\x80\xac\x88\xac\x90\xac\x98\xac\xa0\xac\xa8\xac\xb0\xac\xb8\xac\xc0\xac\xc8\xac\xd0\xac\xd8\xac\xe0\xac\xe8\xac\xf0\xac\xf8\xac\x00\xad\x08\xad\x10\xad\x18\xad\x20\xad\x28\xad\x30\xad\x38\xad\x40\xad\x00\x00\x00\x10\x01\x00\x18\x01\x00\x00\x60\xa0\x70\xa0\x80\xa0\x88\xa0\x90\xa0\x98\xa0\xa0\xa0\xa8\xa0\xb0\xa0\xb8\xa0\xc8\xa0\xd0\xa0\xd8\xa0\xe0\xa0\xe8\xa0\xf0\xa0\xf8\xa0\x00\xa1\x18\xa1\x28\xa1\x30\xa1\x38\xa1\x40\xa1\x48\xa1\xc0\xa2\xc8\xa2\xd0\xa2\xd8\xa2\xe0\xa2\xe8\xa2\xf0\xa2\xf8\xa2\x00\xa3\x08\xa3\x10\xa3\x18\xa3\x20\xa3\x28\xa3\x30\xa3\x38\xa3\x40\xa3\x48\xa3\x50\xa3\x58\xa3\xd0\xa8\xd8\xa8\xe0\xa8\xe8\xa8\xf0\xa8\xf8\xa8\x00\xa9\x08\xa9\x10\xa9\x18\xa9\x20\xa9\x28\xa9\x30\xa9\x38\xa9\x40\xa9\x48\xa9\x50\xa9\x58\xa9\x60\xa9\x68\xa9\x70\xa9\x78\xa9\x80\xa9\x88\xa9\x90\xa9\x98\xa9\xa0\xa9\xa8\xa9\xb0\xa9\xb8\xa9\xc0\xa9\xc8\xa9\xd0\xa9\xd8\xa9\xe0\xa9\xe8\xa9\xf0\xa9\xf8\xa9\x00\xaa\x08\xaa\x10\xaa\x18\xaa\x20\xaa\x30\xaa\x38\xaa\x40\xaa\x48\xaa\x50\xaa\x58\xaa\x60\xaa\x68\xaa\x70\xaa\x78\xaa\x80\xaa\x88\xaa\x90\xaa\x98\xaa\xa0\xaa\xa8\xaa\xb0\xaa\xb8\xaa\xc0\xaa\xc8\xaa\xd0\xaa\xd8\xaa\xe0\xaa\xe8\xaa\xf0\xaa\xf8\xaa\x00\xab\x08\xab\x10\xab\x18\xab\x20\xab\x28\xab\x30\xab\x38\xab\x40\xab\x48\xab\x50\xab\x58\xab\x60\xab\x68\xab\x70\xab\x78\xab\x80\xab\x88\xab\x50\xaf\x58\xaf\x60\xaf\x68\xaf\x00\x00\x00\x20\x01\x00\x54\x01\x00\x00\xb8\xa5\xc8\xa5\xd8\xa5\xe8\xa5\xf8\xa5\x08\xa6\x18\xa6\x28\xa6\x38\xa6\x48\xa6\x58\xa6\x68\xa6\x78\xa6\x88\xa6\x98\xa6\xa8\xa6\xb8\xa6\xc8\xa6\xd8\xa6\xe8\xa6\xf8\xa6\x08\xa7\x18\xa7\x28\xa7\x38\xa7\x48\xa7\x58\xa7\x68\xa7\x78\xa7\x88\xa7\x98\xa7\xa8\xa7\xb8\xa7\xc8\xa7\xd8\xa7\xe8\xa7\xf8\xa7\x08\xa8\x18\xa8\x28\xa8\x38\xa8\x48\xa8\x58\xa8\x68\xa8\x78\xa8\x88\xa8\x98\xa8\xa8\xa8\xb8\xa8\xc8\xa8\xd8\xa8\xe8\xa8\xf8\xa8\x08\xa9\x18\xa9\x28\xa9\x38\xa9\x48\xa9\x58\xa9\x68\xa9\x78\xa9\x88\xa9\x98\xa9\xa8\xa9\xb8\xa9\xc8\xa9\xd8\xa9\xe8\xa9\xf8\xa9\x08\xaa\x18\xaa\x28\xaa\x38\xaa\x48\xaa\x58\xaa\x68\xaa\x78\xaa\x88\xaa\x98\xaa\xa8\xaa\xb8\xaa\xc8\xaa\xd8\xaa\xe8\xaa\xf8\xaa\x08\xab\x18\xab\x28\xab\x38\xab\x48\xab\x58\xab\x68\xab\x78\xab\x88\xab\x98\xab\xa8\xab\xb8\xab\xc8\xab\xd8\xab\xe8\xab\xf8\xab\x08\xac\x18\xac\x28\xac\x38\xac\x48\xac\x58\xac\x68\xac\x78\xac\x88\xac\x98\xac\xa8\xac\xb8\xac\xc8\xac\xd8\xac\xe8\xac\xf8\xac\x08\xad\x18\xad\x28\xad\x38\xad\x48\xad\x58\xad\x68\xad\x78\xad\x88\xad\x98\xad\xa8\xad\xb8\xad\xc8\xad\xd8\xad\xe8\xad\xf8\xad\x08\xae\x18\xae\x28\xae\x38\xae\x48\xae\x58\xae\x68\xae\x78\xae\x88\xae\x98\xae\xa8\xae\xb8\xae\xc8\xae\xd8\xae\xe8\xae\xf8\xae\x08\xaf\x18\xaf\x28\xaf\x38\xaf\x48\xaf\x58\xaf\x68\xaf\x78\xaf\x88\xaf\x98\xaf\xa8\xaf\xb8\xaf\xc8\xaf\xd8\xaf\xe8\xaf\xf8\xaf\x00\x00\x00\x30\x01\x00\x88\x00\x00\x00\x08\xa0\x18\xa0\x28\xa0\x38\xa0\x48\xa0\x58\xa0\x68\xa0\x78\xa0\x88\xa0\x98\xa0\xa8\xa0\xb8\xa0\xc8\xa0\xd8\xa0\xe8\xa0\xf8\xa0\x08\xa1\x18\xa1\x28\xa1\x38\xa1\x48\xa1\x58\xa1\x68\xa1\x78\xa1\x88\xa1\x98\xa1\xa8\xa1\xb8\xa1\xc8\xa1\xd8\xa1\xe8\xa1\xf8\xa1\x08\xa2\x18\xa2\x28\xa2\x38\xa2\x48\xa2\x58\xa2\x68\xa2\x78\xa2\x88\xa2\x98\xa2\xa8\xa2\xb8\xa2\xc8\xa2\xd8\xa2\xe8\xa2\xf8\xa2\x08\xa3\x18\xa3\x28\xa3\x38\xa3\x48\xa3\x58\xa3\x68\xa3\x78\xa3\x88\xa3\x98\xa3\xa8\xa3\xb8\xa3\xc8\xa3\xd8\xa3\xe8\xa3\x00\x00\x00\x40\x01\x00\xd0\x01\x00\x00\x10\xa0\x20\xa0\x30\xa0\x40\xa0\x50\xa0\x60\xa0\x70\xa0\x80\xa0\x90\xa0\xa0\xa0\xb0\xa0\xc0\xa0\xd0\xa0\xe0\xa0\xf0\xa0\x00\xa1\x10\xa1\x20\xa1\x30\xa1\x40\xa1\x50\xa1\x60\xa1\x70\xa1\x80\xa1\x90\xa1\xa0\xa1\xb0\xa1\xc0\xa1\xd0\xa1\xe0\xa1\xf0\xa1\x00\xa2\x10\xa2\x20\xa2\x30\xa2\x40\xa2\x50\xa2\x60\xa2\x70\xa2\x80\xa2\x90\xa2\xa0\xa2\xb0\xa2\xc0\xa2\xd0\xa2\xe0\xa2\xf0\xa2\x00\xa3\x10\xa3\x20\xa3\x30\xa3\x40\xa3\x50\xa3\x60\xa3\x70\xa3\x80\xa3\x90\xa3\xa0\xa3\xb0\xa3\xc0\xa3\xd0\xa3\xe0\xa3\xf0\xa3\x00\xa4\x10\xa4\x20\xa4\x30\xa4\x40\xa4\x50\xa4\x60\xa4\x70\xa4\x80\xa4\x90\xa4\xa0\xa4\xb0\xa4\xc0\xa4\xd0\xa4\xe0\xa4\xf0\xa4\x00\xa5\x10\xa5\x20\xa5\x30\xa5\x40\xa5\x50\xa5\x60\xa5\x70\xa5\x80\xa5\x90\xa5\xa0\xa5\xb0\xa5\xc0\xa5\xd0\xa5\xe0\xa5\xf0\xa5\x00\xa6\x10\xa6\x20\xa6\x30\xa6\x40\xa6\x50\xa6\x60\xa6\x70\xa6\x80\xa6\x90\xa6\xa0\xa6\xb0\xa6\xc0\xa6\xd0\xa6\xe0\xa6\xf0\xa6\x00\xa7\x10\xa7\x20\xa7\x30\xa7\x40\xa7\x50\xa7\x60\xa7\x70\xa7\x80\xa7\x90\xa7\xa0\xa7\xb0\xa7\xc0\xa7\xd0\xa7\xe0\xa7\xf0\xa7\x00\xa8\x10\xa8\x20\xa8\x30\xa8\x40\xa8\x50\xa8\x60\xa8\x70\xa8\x80\xa8\x90\xa8\xa0\xa8\xb0\xa8\xc0\xa8\xd0\xa8\xe0\xa8\xf0\xa8\x00\xa9\x10\xa9\x20\xa9\x30\xa9\x40\xa9\x50\xa9\x60\xa9\x70\xa9\x80\xa9\x90\xa9\xa0\xa9\xb0\xa9\xc0\xa9\xd0\xa9\xe0\xa9\xf0\xa9\x00\xaa\x10\xaa\x20\xaa\x30\xaa\x40\xaa\x50\xaa\x60\xaa\x70\xaa\x80\xaa\x90\xaa\xa0\xaa\xb0\xaa\xc0\xaa\xd0\xaa\xe0\xaa\xf0\xaa\x00\xab\x10\xab\x20\xab\x30\xab\x40\xab\x50\xab\x60\xab\x70\xab\x80\xab\x90\xab\xa0\xab\xb0\xab\xc0\xab\xd0\xab\xe0\xab\xf0\xab\x00\xac\x10\xac\x20\xac\x30\xac\x40\xac\x50\xac\x60\xac\x70\xac\x80\xac\x90\xac\xa0\xac\xb0\xac\xc0\xac\xd0\xac\xe0\xac\xf0\xac\x00\xad\x10\xad\x20\xad\x30\xad\x40\xad\x50\xad\x60\xad\x70\xad\x80\xad\x90\xad\xa0\xad\xb0\xad\xc0\xad\xd0\xad\xe0\xad\xf0\xad\x00\xae\x10\xae\x20\xae\x30\xae\x40\xae\x00\x70\x01\x00\x10\x00\x00\x00\xb8\xae\xd0\xae\xd8\xae\x00\x00\x00\xa0\x01\x00\x4c\x00\x00\x00\x38\xa0\x78\xa0\x00\xa2\x48\xa2\x68\xa2\x88\xa2\xa8\xa2\xc8\xa2\xf8\xa2\x10\xa3\x18\xa3\x20\xa3\x58\xa3\x60\xa3\x98\xa5\xc0\xa8\xc8\xa8\xd0\xa8\xd8\xa8\xe0\xa8\xe8\xa8\xf0\xa8\xf8\xa8\x00\xa9\x08\xa9\x18\xa9\x20\xa9\x28\xa9\x30\xa9\x38\xa9\x40\xa9\x48\xa9\x50\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - -func systrayamd64DllBytes() ([]byte, error) { - return bindataRead( - _systrayamd64Dll, - "systrayamd64.dll", - ) -} - -func systrayamd64Dll() (*asset, error) { - bytes, err := systrayamd64DllBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "systrayamd64.dll", size: 111104, mode: os.FileMode(438), modTime: time.Unix(1471643140, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if err != nil { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "systray386.dll": systray386Dll, - "systrayamd64.dll": systrayamd64Dll, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} -var _bintree = &bintree{nil, map[string]*bintree{ - "systray386.dll": &bintree{systray386Dll, map[string]*bintree{}}, - "systrayamd64.dll": &bintree{systrayamd64Dll, map[string]*bintree{}}, -}} - -// RestoreAsset restores an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// RestoreAssets restores an asset under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, filepath.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} - diff --git a/vendor/github.com/manucorporat/sse/LICENSE b/vendor/github.com/gin-contrib/sse/LICENSE similarity index 100% rename from vendor/github.com/manucorporat/sse/LICENSE rename to vendor/github.com/gin-contrib/sse/LICENSE diff --git a/vendor/github.com/gin-contrib/sse/sse-decoder.go b/vendor/github.com/gin-contrib/sse/sse-decoder.go new file mode 100644 index 000000000..fd49b9c37 --- /dev/null +++ b/vendor/github.com/gin-contrib/sse/sse-decoder.go @@ -0,0 +1,116 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package sse + +import ( + "bytes" + "io" + "io/ioutil" +) + +type decoder struct { + events []Event +} + +func Decode(r io.Reader) ([]Event, error) { + var dec decoder + return dec.decode(r) +} + +func (d *decoder) dispatchEvent(event Event, data string) { + dataLength := len(data) + if dataLength > 0 { + //If the data buffer's last character is a U+000A LINE FEED (LF) character, then remove the last character from the data buffer. + data = data[:dataLength-1] + dataLength-- + } + if dataLength == 0 && event.Event == "" { + return + } + if event.Event == "" { + event.Event = "message" + } + event.Data = data + d.events = append(d.events, event) +} + +func (d *decoder) decode(r io.Reader) ([]Event, error) { + buf, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + var currentEvent Event + var dataBuffer *bytes.Buffer = new(bytes.Buffer) + // TODO (and unit tests) + // Lines must be separated by either a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, + // a single U+000A LINE FEED (LF) character, + // or a single U+000D CARRIAGE RETURN (CR) character. + lines := bytes.Split(buf, []byte{'\n'}) + for _, line := range lines { + if len(line) == 0 { + // If the line is empty (a blank line). Dispatch the event. + d.dispatchEvent(currentEvent, dataBuffer.String()) + + // reset current event and data buffer + currentEvent = Event{} + dataBuffer.Reset() + continue + } + if line[0] == byte(':') { + // If the line starts with a U+003A COLON character (:), ignore the line. + continue + } + + var field, value []byte + colonIndex := bytes.IndexRune(line, ':') + if colonIndex != -1 { + // If the line contains a U+003A COLON character character (:) + // Collect the characters on the line before the first U+003A COLON character (:), + // and let field be that string. + field = line[:colonIndex] + // Collect the characters on the line after the first U+003A COLON character (:), + // and let value be that string. + value = line[colonIndex+1:] + // If value starts with a single U+0020 SPACE character, remove it from value. + if len(value) > 0 && value[0] == ' ' { + value = value[1:] + } + } else { + // Otherwise, the string is not empty but does not contain a U+003A COLON character character (:) + // Use the whole line as the field name, and the empty string as the field value. + field = line + value = []byte{} + } + // The steps to process the field given a field name and a field value depend on the field name, + // as given in the following list. Field names must be compared literally, + // with no case folding performed. + switch string(field) { + case "event": + // Set the event name buffer to field value. + currentEvent.Event = string(value) + case "id": + // Set the event stream's last event ID to the field value. + currentEvent.Id = string(value) + case "retry": + // If the field value consists of only characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), + // then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer. + // Otherwise, ignore the field. + currentEvent.Id = string(value) + case "data": + // Append the field value to the data buffer, + dataBuffer.Write(value) + // then append a single U+000A LINE FEED (LF) character to the data buffer. + dataBuffer.WriteString("\n") + default: + //Otherwise. The field is ignored. + continue + } + } + // Once the end of the file is reached, the user agent must dispatch the event one final time. + d.dispatchEvent(currentEvent, dataBuffer.String()) + + return d.events, nil +} diff --git a/vendor/github.com/manucorporat/sse/sse-encoder.go b/vendor/github.com/gin-contrib/sse/sse-encoder.go similarity index 78% rename from vendor/github.com/manucorporat/sse/sse-encoder.go rename to vendor/github.com/gin-contrib/sse/sse-encoder.go index 16bab7652..f9c808750 100644 --- a/vendor/github.com/manucorporat/sse/sse-encoder.go +++ b/vendor/github.com/gin-contrib/sse/sse-encoder.go @@ -22,7 +22,14 @@ const ContentType = "text/event-stream" var contentType = []string{ContentType} var noCache = []string{"no-cache"} -var replacer = strings.NewReplacer("\n", "\\n", "\r", "\\r") + +var fieldReplacer = strings.NewReplacer( + "\n", "\\n", + "\r", "\\r") + +var dataReplacer = strings.NewReplacer( + "\n", "\ndata:", + "\r", "\\r") type Event struct { Event string @@ -41,30 +48,30 @@ func Encode(writer io.Writer, event Event) error { func writeId(w stringWriter, id string) { if len(id) > 0 { - w.WriteString("id: ") - writeEscape(w, id) + w.WriteString("id:") + fieldReplacer.WriteString(w, id) w.WriteString("\n") } } func writeEvent(w stringWriter, event string) { if len(event) > 0 { - w.WriteString("event: ") - writeEscape(w, event) + w.WriteString("event:") + fieldReplacer.WriteString(w, event) w.WriteString("\n") } } func writeRetry(w stringWriter, retry uint) { if retry > 0 { - w.WriteString("retry: ") + w.WriteString("retry:") w.WriteString(strconv.FormatUint(uint64(retry), 10)) w.WriteString("\n") } } func writeData(w stringWriter, data interface{}) error { - w.WriteString("data: ") + w.WriteString("data:") switch kindOfData(data) { case reflect.Struct, reflect.Slice, reflect.Map: err := json.NewEncoder(w).Encode(data) @@ -73,21 +80,24 @@ func writeData(w stringWriter, data interface{}) error { } w.WriteString("\n") default: - text := fmt.Sprint(data) - writeEscape(w, text) + dataReplacer.WriteString(w, fmt.Sprint(data)) w.WriteString("\n\n") } return nil } func (r Event) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + return Encode(w, r) +} + +func (r Event) WriteContentType(w http.ResponseWriter) { header := w.Header() header["Content-Type"] = contentType if _, exist := header["Cache-Control"]; !exist { header["Cache-Control"] = noCache } - return Encode(w, r) } func kindOfData(data interface{}) reflect.Kind { @@ -98,9 +108,3 @@ func kindOfData(data interface{}) reflect.Kind { } return valueType } - -func writeEscape(w stringWriter, str string) { - // any-char = %x0000-0009 / %x000B-000C / %x000E-10FFFF - // ; a Unicode character other than U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR) - replacer.WriteString(w, str) -} diff --git a/vendor/github.com/manucorporat/sse/writer.go b/vendor/github.com/gin-contrib/sse/writer.go similarity index 100% rename from vendor/github.com/manucorporat/sse/writer.go rename to vendor/github.com/gin-contrib/sse/writer.go diff --git a/vendor/github.com/gin-gonic/gin/AUTHORS.md b/vendor/github.com/gin-gonic/gin/AUTHORS.md index 2feaf4677..dda19bcf3 100644 --- a/vendor/github.com/gin-gonic/gin/AUTHORS.md +++ b/vendor/github.com/gin-gonic/gin/AUTHORS.md @@ -1,10 +1,12 @@ List of all the awesome people working to make Gin the best Web Framework in Go. +## gin 1.x series authors +**Gin Core Team:** Bo-Yi Wu (@appleboy), 田欧 (@thinkerou), Javier Provecho (@javierprovecho) -##gin 0.x series authors +## gin 0.x series authors -**Maintainer:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho) +**Maintainers:** Manu Martinez-Almeida (@manucorporat), Javier Provecho (@javierprovecho) People and companies, who have contributed, in alphabetical order. @@ -226,4 +228,4 @@ People and companies, who have contributed, in alphabetical order. **@yuyabee** -- Fixed README \ No newline at end of file +- Fixed README diff --git a/vendor/github.com/gin-gonic/gin/BENCHMARKS.md b/vendor/github.com/gin-gonic/gin/BENCHMARKS.md deleted file mode 100644 index 181f75b36..000000000 --- a/vendor/github.com/gin-gonic/gin/BENCHMARKS.md +++ /dev/null @@ -1,298 +0,0 @@ -**Machine:** intel i7 ivy bridge quad-core. 8GB RAM. -**Date:** June 4th, 2015 -[https://github.com/gin-gonic/go-http-routing-benchmark](https://github.com/gin-gonic/go-http-routing-benchmark) - -``` -BenchmarkAce_Param 5000000 372 ns/op 32 B/op 1 allocs/op -BenchmarkBear_Param 1000000 1165 ns/op 424 B/op 5 allocs/op -BenchmarkBeego_Param 1000000 2440 ns/op 720 B/op 10 allocs/op -BenchmarkBone_Param 1000000 1067 ns/op 384 B/op 3 allocs/op -BenchmarkDenco_Param 5000000 240 ns/op 32 B/op 1 allocs/op -BenchmarkEcho_Param 10000000 130 ns/op 0 B/op 0 allocs/op -BenchmarkGin_Param 10000000 133 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_Param 1000000 1826 ns/op 656 B/op 9 allocs/op -BenchmarkGoji_Param 2000000 957 ns/op 336 B/op 2 allocs/op -BenchmarkGoJsonRest_Param 1000000 2021 ns/op 657 B/op 14 allocs/op -BenchmarkGoRestful_Param 200000 8825 ns/op 2496 B/op 31 allocs/op -BenchmarkGorillaMux_Param 500000 3340 ns/op 784 B/op 9 allocs/op -BenchmarkHttpRouter_Param 10000000 152 ns/op 32 B/op 1 allocs/op -BenchmarkHttpTreeMux_Param 2000000 717 ns/op 336 B/op 2 allocs/op -BenchmarkKocha_Param 3000000 423 ns/op 56 B/op 3 allocs/op -BenchmarkMacaron_Param 1000000 3410 ns/op 1104 B/op 11 allocs/op -BenchmarkMartini_Param 200000 7101 ns/op 1152 B/op 12 allocs/op -BenchmarkPat_Param 1000000 2040 ns/op 656 B/op 14 allocs/op -BenchmarkPossum_Param 1000000 2048 ns/op 624 B/op 7 allocs/op -BenchmarkR2router_Param 1000000 1144 ns/op 432 B/op 6 allocs/op -BenchmarkRevel_Param 200000 6725 ns/op 1672 B/op 28 allocs/op -BenchmarkRivet_Param 1000000 1121 ns/op 464 B/op 5 allocs/op -BenchmarkTango_Param 1000000 1479 ns/op 256 B/op 10 allocs/op -BenchmarkTigerTonic_Param 1000000 3393 ns/op 992 B/op 19 allocs/op -BenchmarkTraffic_Param 300000 5525 ns/op 1984 B/op 23 allocs/op -BenchmarkVulcan_Param 2000000 924 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_Param 1000000 1084 ns/op 368 B/op 3 allocs/op -BenchmarkAce_Param5 3000000 614 ns/op 160 B/op 1 allocs/op -BenchmarkBear_Param5 1000000 1617 ns/op 469 B/op 5 allocs/op -BenchmarkBeego_Param5 1000000 3373 ns/op 992 B/op 13 allocs/op -BenchmarkBone_Param5 1000000 1478 ns/op 432 B/op 3 allocs/op -BenchmarkDenco_Param5 3000000 570 ns/op 160 B/op 1 allocs/op -BenchmarkEcho_Param5 5000000 256 ns/op 0 B/op 0 allocs/op -BenchmarkGin_Param5 10000000 222 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_Param5 1000000 2789 ns/op 928 B/op 12 allocs/op -BenchmarkGoji_Param5 1000000 1287 ns/op 336 B/op 2 allocs/op -BenchmarkGoJsonRest_Param5 1000000 3670 ns/op 1105 B/op 17 allocs/op -BenchmarkGoRestful_Param5 200000 10756 ns/op 2672 B/op 31 allocs/op -BenchmarkGorillaMux_Param5 300000 5543 ns/op 912 B/op 9 allocs/op -BenchmarkHttpRouter_Param5 5000000 403 ns/op 160 B/op 1 allocs/op -BenchmarkHttpTreeMux_Param5 1000000 1089 ns/op 336 B/op 2 allocs/op -BenchmarkKocha_Param5 1000000 1682 ns/op 440 B/op 10 allocs/op -BenchmarkMacaron_Param5 300000 4596 ns/op 1376 B/op 14 allocs/op -BenchmarkMartini_Param5 100000 15703 ns/op 1280 B/op 12 allocs/op -BenchmarkPat_Param5 300000 5320 ns/op 1008 B/op 42 allocs/op -BenchmarkPossum_Param5 1000000 2155 ns/op 624 B/op 7 allocs/op -BenchmarkR2router_Param5 1000000 1559 ns/op 432 B/op 6 allocs/op -BenchmarkRevel_Param5 200000 8184 ns/op 2024 B/op 35 allocs/op -BenchmarkRivet_Param5 1000000 1914 ns/op 528 B/op 9 allocs/op -BenchmarkTango_Param5 1000000 3280 ns/op 944 B/op 18 allocs/op -BenchmarkTigerTonic_Param5 200000 11638 ns/op 2519 B/op 53 allocs/op -BenchmarkTraffic_Param5 200000 8941 ns/op 2280 B/op 31 allocs/op -BenchmarkVulcan_Param5 1000000 1279 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_Param5 1000000 1574 ns/op 416 B/op 3 allocs/op -BenchmarkAce_Param20 1000000 1528 ns/op 640 B/op 1 allocs/op -BenchmarkBear_Param20 300000 4906 ns/op 1633 B/op 5 allocs/op -BenchmarkBeego_Param20 200000 10529 ns/op 3868 B/op 17 allocs/op -BenchmarkBone_Param20 300000 7362 ns/op 2539 B/op 5 allocs/op -BenchmarkDenco_Param20 1000000 1884 ns/op 640 B/op 1 allocs/op -BenchmarkEcho_Param20 2000000 689 ns/op 0 B/op 0 allocs/op -BenchmarkGin_Param20 3000000 545 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_Param20 200000 9437 ns/op 3804 B/op 16 allocs/op -BenchmarkGoji_Param20 500000 3987 ns/op 1246 B/op 2 allocs/op -BenchmarkGoJsonRest_Param20 100000 12799 ns/op 4492 B/op 21 allocs/op -BenchmarkGoRestful_Param20 100000 19451 ns/op 5244 B/op 33 allocs/op -BenchmarkGorillaMux_Param20 100000 12456 ns/op 3275 B/op 11 allocs/op -BenchmarkHttpRouter_Param20 1000000 1333 ns/op 640 B/op 1 allocs/op -BenchmarkHttpTreeMux_Param20 300000 6490 ns/op 2187 B/op 4 allocs/op -BenchmarkKocha_Param20 300000 5335 ns/op 1808 B/op 27 allocs/op -BenchmarkMacaron_Param20 200000 11325 ns/op 4252 B/op 18 allocs/op -BenchmarkMartini_Param20 20000 64419 ns/op 3644 B/op 14 allocs/op -BenchmarkPat_Param20 50000 24672 ns/op 4888 B/op 151 allocs/op -BenchmarkPossum_Param20 1000000 2085 ns/op 624 B/op 7 allocs/op -BenchmarkR2router_Param20 300000 6809 ns/op 2283 B/op 8 allocs/op -BenchmarkRevel_Param20 100000 16600 ns/op 5551 B/op 54 allocs/op -BenchmarkRivet_Param20 200000 8428 ns/op 2620 B/op 26 allocs/op -BenchmarkTango_Param20 100000 16302 ns/op 8224 B/op 48 allocs/op -BenchmarkTigerTonic_Param20 30000 46828 ns/op 10538 B/op 178 allocs/op -BenchmarkTraffic_Param20 50000 28871 ns/op 7998 B/op 66 allocs/op -BenchmarkVulcan_Param20 1000000 2267 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_Param20 300000 6828 ns/op 2507 B/op 5 allocs/op -BenchmarkAce_ParamWrite 3000000 502 ns/op 40 B/op 2 allocs/op -BenchmarkBear_ParamWrite 1000000 1303 ns/op 424 B/op 5 allocs/op -BenchmarkBeego_ParamWrite 1000000 2489 ns/op 728 B/op 11 allocs/op -BenchmarkBone_ParamWrite 1000000 1181 ns/op 384 B/op 3 allocs/op -BenchmarkDenco_ParamWrite 5000000 315 ns/op 32 B/op 1 allocs/op -BenchmarkEcho_ParamWrite 10000000 237 ns/op 8 B/op 1 allocs/op -BenchmarkGin_ParamWrite 5000000 336 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_ParamWrite 1000000 2079 ns/op 664 B/op 10 allocs/op -BenchmarkGoji_ParamWrite 1000000 1092 ns/op 336 B/op 2 allocs/op -BenchmarkGoJsonRest_ParamWrite 1000000 3329 ns/op 1136 B/op 19 allocs/op -BenchmarkGoRestful_ParamWrite 200000 9273 ns/op 2504 B/op 32 allocs/op -BenchmarkGorillaMux_ParamWrite 500000 3919 ns/op 792 B/op 10 allocs/op -BenchmarkHttpRouter_ParamWrite 10000000 223 ns/op 32 B/op 1 allocs/op -BenchmarkHttpTreeMux_ParamWrite 2000000 788 ns/op 336 B/op 2 allocs/op -BenchmarkKocha_ParamWrite 3000000 549 ns/op 56 B/op 3 allocs/op -BenchmarkMacaron_ParamWrite 500000 4558 ns/op 1216 B/op 16 allocs/op -BenchmarkMartini_ParamWrite 200000 8850 ns/op 1256 B/op 16 allocs/op -BenchmarkPat_ParamWrite 500000 3679 ns/op 1088 B/op 19 allocs/op -BenchmarkPossum_ParamWrite 1000000 2114 ns/op 624 B/op 7 allocs/op -BenchmarkR2router_ParamWrite 1000000 1320 ns/op 432 B/op 6 allocs/op -BenchmarkRevel_ParamWrite 200000 8048 ns/op 2128 B/op 33 allocs/op -BenchmarkRivet_ParamWrite 1000000 1393 ns/op 472 B/op 6 allocs/op -BenchmarkTango_ParamWrite 2000000 819 ns/op 136 B/op 5 allocs/op -BenchmarkTigerTonic_ParamWrite 300000 5860 ns/op 1440 B/op 25 allocs/op -BenchmarkTraffic_ParamWrite 200000 7429 ns/op 2400 B/op 27 allocs/op -BenchmarkVulcan_ParamWrite 2000000 972 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_ParamWrite 1000000 1226 ns/op 368 B/op 3 allocs/op -BenchmarkAce_GithubStatic 5000000 294 ns/op 0 B/op 0 allocs/op -BenchmarkBear_GithubStatic 3000000 575 ns/op 88 B/op 3 allocs/op -BenchmarkBeego_GithubStatic 1000000 1561 ns/op 368 B/op 7 allocs/op -BenchmarkBone_GithubStatic 200000 12301 ns/op 2880 B/op 60 allocs/op -BenchmarkDenco_GithubStatic 20000000 74.6 ns/op 0 B/op 0 allocs/op -BenchmarkEcho_GithubStatic 10000000 176 ns/op 0 B/op 0 allocs/op -BenchmarkGin_GithubStatic 10000000 159 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_GithubStatic 1000000 1116 ns/op 304 B/op 6 allocs/op -BenchmarkGoji_GithubStatic 5000000 413 ns/op 0 B/op 0 allocs/op -BenchmarkGoRestful_GithubStatic 30000 55200 ns/op 3520 B/op 36 allocs/op -BenchmarkGoJsonRest_GithubStatic 1000000 1504 ns/op 337 B/op 12 allocs/op -BenchmarkGorillaMux_GithubStatic 100000 23620 ns/op 464 B/op 8 allocs/op -BenchmarkHttpRouter_GithubStatic 20000000 78.3 ns/op 0 B/op 0 allocs/op -BenchmarkHttpTreeMux_GithubStatic 20000000 84.9 ns/op 0 B/op 0 allocs/op -BenchmarkKocha_GithubStatic 20000000 111 ns/op 0 B/op 0 allocs/op -BenchmarkMacaron_GithubStatic 1000000 2686 ns/op 752 B/op 8 allocs/op -BenchmarkMartini_GithubStatic 100000 22244 ns/op 832 B/op 11 allocs/op -BenchmarkPat_GithubStatic 100000 13278 ns/op 3648 B/op 76 allocs/op -BenchmarkPossum_GithubStatic 1000000 1429 ns/op 480 B/op 4 allocs/op -BenchmarkR2router_GithubStatic 2000000 726 ns/op 144 B/op 5 allocs/op -BenchmarkRevel_GithubStatic 300000 6271 ns/op 1288 B/op 25 allocs/op -BenchmarkRivet_GithubStatic 3000000 474 ns/op 112 B/op 2 allocs/op -BenchmarkTango_GithubStatic 1000000 1842 ns/op 256 B/op 10 allocs/op -BenchmarkTigerTonic_GithubStatic 5000000 361 ns/op 48 B/op 1 allocs/op -BenchmarkTraffic_GithubStatic 30000 47197 ns/op 18920 B/op 149 allocs/op -BenchmarkVulcan_GithubStatic 1000000 1415 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_GithubStatic 1000000 2522 ns/op 512 B/op 11 allocs/op -BenchmarkAce_GithubParam 3000000 578 ns/op 96 B/op 1 allocs/op -BenchmarkBear_GithubParam 1000000 1592 ns/op 464 B/op 5 allocs/op -BenchmarkBeego_GithubParam 1000000 2891 ns/op 784 B/op 11 allocs/op -BenchmarkBone_GithubParam 300000 6440 ns/op 1456 B/op 16 allocs/op -BenchmarkDenco_GithubParam 3000000 514 ns/op 128 B/op 1 allocs/op -BenchmarkEcho_GithubParam 5000000 292 ns/op 0 B/op 0 allocs/op -BenchmarkGin_GithubParam 10000000 242 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_GithubParam 1000000 2343 ns/op 720 B/op 10 allocs/op -BenchmarkGoji_GithubParam 1000000 1566 ns/op 336 B/op 2 allocs/op -BenchmarkGoJsonRest_GithubParam 1000000 2828 ns/op 721 B/op 15 allocs/op -BenchmarkGoRestful_GithubParam 10000 177711 ns/op 2816 B/op 35 allocs/op -BenchmarkGorillaMux_GithubParam 100000 13591 ns/op 816 B/op 9 allocs/op -BenchmarkHttpRouter_GithubParam 5000000 352 ns/op 96 B/op 1 allocs/op -BenchmarkHttpTreeMux_GithubParam 2000000 973 ns/op 336 B/op 2 allocs/op -BenchmarkKocha_GithubParam 2000000 889 ns/op 128 B/op 5 allocs/op -BenchmarkMacaron_GithubParam 500000 4047 ns/op 1168 B/op 12 allocs/op -BenchmarkMartini_GithubParam 50000 28982 ns/op 1184 B/op 12 allocs/op -BenchmarkPat_GithubParam 200000 8747 ns/op 2480 B/op 56 allocs/op -BenchmarkPossum_GithubParam 1000000 2158 ns/op 624 B/op 7 allocs/op -BenchmarkR2router_GithubParam 1000000 1352 ns/op 432 B/op 6 allocs/op -BenchmarkRevel_GithubParam 200000 7673 ns/op 1784 B/op 30 allocs/op -BenchmarkRivet_GithubParam 1000000 1573 ns/op 480 B/op 6 allocs/op -BenchmarkTango_GithubParam 1000000 2418 ns/op 480 B/op 13 allocs/op -BenchmarkTigerTonic_GithubParam 300000 6048 ns/op 1440 B/op 28 allocs/op -BenchmarkTraffic_GithubParam 100000 20143 ns/op 6024 B/op 55 allocs/op -BenchmarkVulcan_GithubParam 1000000 2224 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_GithubParam 500000 4156 ns/op 1312 B/op 12 allocs/op -BenchmarkAce_GithubAll 10000 109482 ns/op 13792 B/op 167 allocs/op -BenchmarkBear_GithubAll 10000 287490 ns/op 79952 B/op 943 allocs/op -BenchmarkBeego_GithubAll 3000 562184 ns/op 146272 B/op 2092 allocs/op -BenchmarkBone_GithubAll 500 2578716 ns/op 648016 B/op 8119 allocs/op -BenchmarkDenco_GithubAll 20000 94955 ns/op 20224 B/op 167 allocs/op -BenchmarkEcho_GithubAll 30000 58705 ns/op 0 B/op 0 allocs/op -BenchmarkGin_GithubAll 30000 50991 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_GithubAll 5000 449648 ns/op 133280 B/op 1889 allocs/op -BenchmarkGoji_GithubAll 2000 689748 ns/op 56113 B/op 334 allocs/op -BenchmarkGoJsonRest_GithubAll 5000 537769 ns/op 135995 B/op 2940 allocs/op -BenchmarkGoRestful_GithubAll 100 18410628 ns/op 797236 B/op 7725 allocs/op -BenchmarkGorillaMux_GithubAll 200 8036360 ns/op 153137 B/op 1791 allocs/op -BenchmarkHttpRouter_GithubAll 20000 63506 ns/op 13792 B/op 167 allocs/op -BenchmarkHttpTreeMux_GithubAll 10000 165927 ns/op 56112 B/op 334 allocs/op -BenchmarkKocha_GithubAll 10000 171362 ns/op 23304 B/op 843 allocs/op -BenchmarkMacaron_GithubAll 2000 817008 ns/op 224960 B/op 2315 allocs/op -BenchmarkMartini_GithubAll 100 12609209 ns/op 237952 B/op 2686 allocs/op -BenchmarkPat_GithubAll 300 4830398 ns/op 1504101 B/op 32222 allocs/op -BenchmarkPossum_GithubAll 10000 301716 ns/op 97440 B/op 812 allocs/op -BenchmarkR2router_GithubAll 10000 270691 ns/op 77328 B/op 1182 allocs/op -BenchmarkRevel_GithubAll 1000 1491919 ns/op 345553 B/op 5918 allocs/op -BenchmarkRivet_GithubAll 10000 283860 ns/op 84272 B/op 1079 allocs/op -BenchmarkTango_GithubAll 5000 473821 ns/op 87078 B/op 2470 allocs/op -BenchmarkTigerTonic_GithubAll 2000 1120131 ns/op 241088 B/op 6052 allocs/op -BenchmarkTraffic_GithubAll 200 8708979 ns/op 2664762 B/op 22390 allocs/op -BenchmarkVulcan_GithubAll 5000 353392 ns/op 19894 B/op 609 allocs/op -BenchmarkZeus_GithubAll 2000 944234 ns/op 300688 B/op 2648 allocs/op -BenchmarkAce_GPlusStatic 5000000 251 ns/op 0 B/op 0 allocs/op -BenchmarkBear_GPlusStatic 3000000 415 ns/op 72 B/op 3 allocs/op -BenchmarkBeego_GPlusStatic 1000000 1416 ns/op 352 B/op 7 allocs/op -BenchmarkBone_GPlusStatic 10000000 192 ns/op 32 B/op 1 allocs/op -BenchmarkDenco_GPlusStatic 30000000 47.6 ns/op 0 B/op 0 allocs/op -BenchmarkEcho_GPlusStatic 10000000 131 ns/op 0 B/op 0 allocs/op -BenchmarkGin_GPlusStatic 10000000 131 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_GPlusStatic 1000000 1035 ns/op 288 B/op 6 allocs/op -BenchmarkGoji_GPlusStatic 5000000 304 ns/op 0 B/op 0 allocs/op -BenchmarkGoJsonRest_GPlusStatic 1000000 1286 ns/op 337 B/op 12 allocs/op -BenchmarkGoRestful_GPlusStatic 200000 9649 ns/op 2160 B/op 30 allocs/op -BenchmarkGorillaMux_GPlusStatic 1000000 2346 ns/op 464 B/op 8 allocs/op -BenchmarkHttpRouter_GPlusStatic 30000000 42.7 ns/op 0 B/op 0 allocs/op -BenchmarkHttpTreeMux_GPlusStatic 30000000 49.5 ns/op 0 B/op 0 allocs/op -BenchmarkKocha_GPlusStatic 20000000 74.8 ns/op 0 B/op 0 allocs/op -BenchmarkMacaron_GPlusStatic 1000000 2520 ns/op 736 B/op 8 allocs/op -BenchmarkMartini_GPlusStatic 300000 5310 ns/op 832 B/op 11 allocs/op -BenchmarkPat_GPlusStatic 5000000 398 ns/op 96 B/op 2 allocs/op -BenchmarkPossum_GPlusStatic 1000000 1434 ns/op 480 B/op 4 allocs/op -BenchmarkR2router_GPlusStatic 2000000 646 ns/op 144 B/op 5 allocs/op -BenchmarkRevel_GPlusStatic 300000 6172 ns/op 1272 B/op 25 allocs/op -BenchmarkRivet_GPlusStatic 3000000 444 ns/op 112 B/op 2 allocs/op -BenchmarkTango_GPlusStatic 1000000 1400 ns/op 208 B/op 10 allocs/op -BenchmarkTigerTonic_GPlusStatic 10000000 213 ns/op 32 B/op 1 allocs/op -BenchmarkTraffic_GPlusStatic 1000000 3091 ns/op 1208 B/op 16 allocs/op -BenchmarkVulcan_GPlusStatic 2000000 863 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_GPlusStatic 10000000 237 ns/op 16 B/op 1 allocs/op -BenchmarkAce_GPlusParam 3000000 435 ns/op 64 B/op 1 allocs/op -BenchmarkBear_GPlusParam 1000000 1205 ns/op 448 B/op 5 allocs/op -BenchmarkBeego_GPlusParam 1000000 2494 ns/op 720 B/op 10 allocs/op -BenchmarkBone_GPlusParam 1000000 1126 ns/op 384 B/op 3 allocs/op -BenchmarkDenco_GPlusParam 5000000 325 ns/op 64 B/op 1 allocs/op -BenchmarkEcho_GPlusParam 10000000 168 ns/op 0 B/op 0 allocs/op -BenchmarkGin_GPlusParam 10000000 170 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_GPlusParam 1000000 1895 ns/op 656 B/op 9 allocs/op -BenchmarkGoji_GPlusParam 1000000 1071 ns/op 336 B/op 2 allocs/op -BenchmarkGoJsonRest_GPlusParam 1000000 2282 ns/op 657 B/op 14 allocs/op -BenchmarkGoRestful_GPlusParam 100000 19400 ns/op 2560 B/op 33 allocs/op -BenchmarkGorillaMux_GPlusParam 500000 5001 ns/op 784 B/op 9 allocs/op -BenchmarkHttpRouter_GPlusParam 10000000 240 ns/op 64 B/op 1 allocs/op -BenchmarkHttpTreeMux_GPlusParam 2000000 797 ns/op 336 B/op 2 allocs/op -BenchmarkKocha_GPlusParam 3000000 505 ns/op 56 B/op 3 allocs/op -BenchmarkMacaron_GPlusParam 1000000 3668 ns/op 1104 B/op 11 allocs/op -BenchmarkMartini_GPlusParam 200000 10672 ns/op 1152 B/op 12 allocs/op -BenchmarkPat_GPlusParam 1000000 2376 ns/op 704 B/op 14 allocs/op -BenchmarkPossum_GPlusParam 1000000 2090 ns/op 624 B/op 7 allocs/op -BenchmarkR2router_GPlusParam 1000000 1233 ns/op 432 B/op 6 allocs/op -BenchmarkRevel_GPlusParam 200000 6778 ns/op 1704 B/op 28 allocs/op -BenchmarkRivet_GPlusParam 1000000 1279 ns/op 464 B/op 5 allocs/op -BenchmarkTango_GPlusParam 1000000 1981 ns/op 272 B/op 10 allocs/op -BenchmarkTigerTonic_GPlusParam 500000 3893 ns/op 1064 B/op 19 allocs/op -BenchmarkTraffic_GPlusParam 200000 6585 ns/op 2000 B/op 23 allocs/op -BenchmarkVulcan_GPlusParam 1000000 1233 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_GPlusParam 1000000 1350 ns/op 368 B/op 3 allocs/op -BenchmarkAce_GPlus2Params 3000000 512 ns/op 64 B/op 1 allocs/op -BenchmarkBear_GPlus2Params 1000000 1564 ns/op 464 B/op 5 allocs/op -BenchmarkBeego_GPlus2Params 1000000 3043 ns/op 784 B/op 11 allocs/op -BenchmarkBone_GPlus2Params 1000000 3152 ns/op 736 B/op 7 allocs/op -BenchmarkDenco_GPlus2Params 3000000 431 ns/op 64 B/op 1 allocs/op -BenchmarkEcho_GPlus2Params 5000000 247 ns/op 0 B/op 0 allocs/op -BenchmarkGin_GPlus2Params 10000000 219 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_GPlus2Params 1000000 2363 ns/op 720 B/op 10 allocs/op -BenchmarkGoji_GPlus2Params 1000000 1540 ns/op 336 B/op 2 allocs/op -BenchmarkGoJsonRest_GPlus2Params 1000000 2872 ns/op 721 B/op 15 allocs/op -BenchmarkGoRestful_GPlus2Params 100000 23030 ns/op 2720 B/op 35 allocs/op -BenchmarkGorillaMux_GPlus2Params 200000 10516 ns/op 816 B/op 9 allocs/op -BenchmarkHttpRouter_GPlus2Params 5000000 273 ns/op 64 B/op 1 allocs/op -BenchmarkHttpTreeMux_GPlus2Params 2000000 939 ns/op 336 B/op 2 allocs/op -BenchmarkKocha_GPlus2Params 2000000 844 ns/op 128 B/op 5 allocs/op -BenchmarkMacaron_GPlus2Params 500000 3914 ns/op 1168 B/op 12 allocs/op -BenchmarkMartini_GPlus2Params 50000 35759 ns/op 1280 B/op 16 allocs/op -BenchmarkPat_GPlus2Params 200000 7089 ns/op 2304 B/op 41 allocs/op -BenchmarkPossum_GPlus2Params 1000000 2093 ns/op 624 B/op 7 allocs/op -BenchmarkR2router_GPlus2Params 1000000 1320 ns/op 432 B/op 6 allocs/op -BenchmarkRevel_GPlus2Params 200000 7351 ns/op 1800 B/op 30 allocs/op -BenchmarkRivet_GPlus2Params 1000000 1485 ns/op 480 B/op 6 allocs/op -BenchmarkTango_GPlus2Params 1000000 2111 ns/op 448 B/op 12 allocs/op -BenchmarkTigerTonic_GPlus2Params 300000 6271 ns/op 1528 B/op 28 allocs/op -BenchmarkTraffic_GPlus2Params 100000 14886 ns/op 3312 B/op 34 allocs/op -BenchmarkVulcan_GPlus2Params 1000000 1883 ns/op 98 B/op 3 allocs/op -BenchmarkZeus_GPlus2Params 1000000 2686 ns/op 784 B/op 6 allocs/op -BenchmarkAce_GPlusAll 300000 5912 ns/op 640 B/op 11 allocs/op -BenchmarkBear_GPlusAll 100000 16448 ns/op 5072 B/op 61 allocs/op -BenchmarkBeego_GPlusAll 50000 32916 ns/op 8976 B/op 129 allocs/op -BenchmarkBone_GPlusAll 50000 25836 ns/op 6992 B/op 76 allocs/op -BenchmarkDenco_GPlusAll 500000 4462 ns/op 672 B/op 11 allocs/op -BenchmarkEcho_GPlusAll 500000 2806 ns/op 0 B/op 0 allocs/op -BenchmarkGin_GPlusAll 500000 2579 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_GPlusAll 50000 25223 ns/op 8144 B/op 116 allocs/op -BenchmarkGoji_GPlusAll 100000 14237 ns/op 3696 B/op 22 allocs/op -BenchmarkGoJsonRest_GPlusAll 50000 29227 ns/op 8221 B/op 183 allocs/op -BenchmarkGoRestful_GPlusAll 10000 203144 ns/op 36064 B/op 441 allocs/op -BenchmarkGorillaMux_GPlusAll 20000 80906 ns/op 9712 B/op 115 allocs/op -BenchmarkHttpRouter_GPlusAll 500000 3040 ns/op 640 B/op 11 allocs/op -BenchmarkHttpTreeMux_GPlusAll 200000 9627 ns/op 3696 B/op 22 allocs/op -BenchmarkKocha_GPlusAll 200000 8108 ns/op 976 B/op 43 allocs/op -BenchmarkMacaron_GPlusAll 30000 48083 ns/op 13968 B/op 142 allocs/op -BenchmarkMartini_GPlusAll 10000 196978 ns/op 15072 B/op 178 allocs/op -BenchmarkPat_GPlusAll 30000 58865 ns/op 16880 B/op 343 allocs/op -BenchmarkPossum_GPlusAll 100000 19685 ns/op 6240 B/op 52 allocs/op -BenchmarkR2router_GPlusAll 100000 16251 ns/op 5040 B/op 76 allocs/op -BenchmarkRevel_GPlusAll 20000 93489 ns/op 21656 B/op 368 allocs/op -BenchmarkRivet_GPlusAll 100000 16907 ns/op 5408 B/op 64 allocs/op -``` \ No newline at end of file diff --git a/vendor/github.com/gin-gonic/gin/CHANGELOG.md b/vendor/github.com/gin-gonic/gin/CHANGELOG.md deleted file mode 100644 index 5b5b6addf..000000000 --- a/vendor/github.com/gin-gonic/gin/CHANGELOG.md +++ /dev/null @@ -1,150 +0,0 @@ -#CHANGELOG - -###Gin 1.0rc2 (...) - -- [PERFORMANCE] Fast path for writting Content-Type. -- [PERFORMANCE] Much faster 404 routing -- [PERFORMANCE] Allocation optimizations -- [PERFORMANCE] Faster root tree lookup -- [PERFORMANCE] Zero overhead, String() and JSON() rendering. -- [PERFORMANCE] Faster ClientIP parsing -- [PERFORMANCE] Much faster SSE implementation -- [NEW] Benchmarks suite -- [NEW] Bind validation can be disabled and replaced with custom validators. -- [NEW] More flexible HTML render -- [NEW] Multipart and PostForm bindings -- [NEW] Adds method to return all the registered routes -- [NEW] Context.HandlerName() returns the main handler's name -- [NEW] Adds Error.IsType() helper -- [FIX] Binding multipart form -- [FIX] Integration tests -- [FIX] Crash when binding non struct object in Context. -- [FIX] RunTLS() implementation -- [FIX] Logger() unit tests -- [FIX] Adds SetHTMLTemplate() warning -- [FIX] Context.IsAborted() -- [FIX] More unit tests -- [FIX] JSON, XML, HTML renders accept custom content-types -- [FIX] gin.AbortIndex is unexported -- [FIX] Better approach to avoid directory listing in StaticFS() -- [FIX] Context.ClientIP() always returns the IP with trimmed spaces. -- [FIX] Better warning when running in debug mode. -- [FIX] Google App Engine integration. debugPrint does not use os.Stdout -- [FIX] Fixes integer overflow in error type -- [FIX] Error implements the json.Marshaller interface -- [FIX] MIT license in every file - - -###Gin 1.0rc1 (May 22, 2015) - -- [PERFORMANCE] Zero allocation router -- [PERFORMANCE] Faster JSON, XML and text rendering -- [PERFORMANCE] Custom hand optimized HttpRouter for Gin -- [PERFORMANCE] Misc code optimizations. Inlining, tail call optimizations -- [NEW] Built-in support for golang.org/x/net/context -- [NEW] Any(path, handler). Create a route that matches any path -- [NEW] Refactored rendering pipeline (faster and static typeded) -- [NEW] Refactored errors API -- [NEW] IndentedJSON() prints pretty JSON -- [NEW] Added gin.DefaultWriter -- [NEW] UNIX socket support -- [NEW] RouterGroup.BasePath is exposed -- [NEW] JSON validation using go-validate-yourself (very powerful options) -- [NEW] Completed suite of unit tests -- [NEW] HTTP streaming with c.Stream() -- [NEW] StaticFile() creates a router for serving just one file. -- [NEW] StaticFS() has an option to disable directory listing. -- [NEW] StaticFS() for serving static files through virtual filesystems -- [NEW] Server-Sent Events native support -- [NEW] WrapF() and WrapH() helpers for wrapping http.HandlerFunc and http.Handler -- [NEW] Added LoggerWithWriter() middleware -- [NEW] Added RecoveryWithWriter() middleware -- [NEW] Added DefaultPostFormValue() -- [NEW] Added DefaultFormValue() -- [NEW] Added DefaultParamValue() -- [FIX] BasicAuth() when using custom realm -- [FIX] Bug when serving static files in nested routing group -- [FIX] Redirect using built-in http.Redirect() -- [FIX] Logger when printing the requested path -- [FIX] Documentation typos -- [FIX] Context.Engine renamed to Context.engine -- [FIX] Better debugging messages -- [FIX] ErrorLogger -- [FIX] Debug HTTP render -- [FIX] Refactored binding and render modules -- [FIX] Refactored Context initialization -- [FIX] Refactored BasicAuth() -- [FIX] NoMethod/NoRoute handlers -- [FIX] Hijacking http -- [FIX] Better support for Google App Engine (using log instead of fmt) - - -###Gin 0.6 (Mar 9, 2015) - -- [NEW] Support multipart/form-data -- [NEW] NoMethod handler -- [NEW] Validate sub structures -- [NEW] Support for HTTP Realm Auth -- [FIX] Unsigned integers in binding -- [FIX] Improve color logger - - -###Gin 0.5 (Feb 7, 2015) - -- [NEW] Content Negotiation -- [FIX] Solved security bug that allow a client to spoof ip -- [FIX] Fix unexported/ignored fields in binding - - -###Gin 0.4 (Aug 21, 2014) - -- [NEW] Development mode -- [NEW] Unit tests -- [NEW] Add Content.Redirect() -- [FIX] Deferring WriteHeader() -- [FIX] Improved documentation for model binding - - -###Gin 0.3 (Jul 18, 2014) - -- [PERFORMANCE] Normal log and error log are printed in the same call. -- [PERFORMANCE] Improve performance of NoRouter() -- [PERFORMANCE] Improve context's memory locality, reduce CPU cache faults. -- [NEW] Flexible rendering API -- [NEW] Add Context.File() -- [NEW] Add shorcut RunTLS() for http.ListenAndServeTLS -- [FIX] Rename NotFound404() to NoRoute() -- [FIX] Errors in context are purged -- [FIX] Adds HEAD method in Static file serving -- [FIX] Refactors Static() file serving -- [FIX] Using keyed initialization to fix app-engine integration -- [FIX] Can't unmarshal JSON array, #63 -- [FIX] Renaming Context.Req to Context.Request -- [FIX] Check application/x-www-form-urlencoded when parsing form - - -###Gin 0.2b (Jul 08, 2014) -- [PERFORMANCE] Using sync.Pool to allocatio/gc overhead -- [NEW] Travis CI integration -- [NEW] Completely new logger -- [NEW] New API for serving static files. gin.Static() -- [NEW] gin.H() can be serialized into XML -- [NEW] Typed errors. Errors can be typed. Internet/external/custom. -- [NEW] Support for Godeps -- [NEW] Travis/Godocs badges in README -- [NEW] New Bind() and BindWith() methods for parsing request body. -- [NEW] Add Content.Copy() -- [NEW] Add context.LastError() -- [NEW] Add shorcut for OPTIONS HTTP method -- [FIX] Tons of README fixes -- [FIX] Header is written before body -- [FIX] BasicAuth() and changes API a little bit -- [FIX] Recovery() middleware only prints panics -- [FIX] Context.Get() does not panic anymore. Use MustGet() instead. -- [FIX] Multiple http.WriteHeader() in NotFound handlers -- [FIX] Engine.Run() panics if http server can't be setted up -- [FIX] Crash when route path doesn't start with '/' -- [FIX] Do not update header when status code is negative -- [FIX] Setting response headers before calling WriteHeader in context.String() -- [FIX] Add MIT license -- [FIX] Changes behaviour of ErrorLogger() and Logger() diff --git a/vendor/github.com/gin-gonic/gin/README.md b/vendor/github.com/gin-gonic/gin/README.md deleted file mode 100644 index 458cd060e..000000000 --- a/vendor/github.com/gin-gonic/gin/README.md +++ /dev/null @@ -1,601 +0,0 @@ -#Gin Web Framework [![Build Status](https://travis-ci.org/gin-gonic/gin.svg)](https://travis-ci.org/gin-gonic/gin) [![Coverage Status](https://coveralls.io/repos/gin-gonic/gin/badge.svg?branch=master)](https://coveralls.io/r/gin-gonic/gin?branch=master) - - [![GoDoc](https://godoc.org/github.com/gin-gonic/gin?status.svg)](https://godoc.org/github.com/gin-gonic/gin) [![Join the chat at https://gitter.im/gin-gonic/gin](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -Gin is a web framework written in Golang. It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin. - -![Gin console logger](https://gin-gonic.github.io/gin/other/console.png) - -``` -$ cat test.go -``` -```go -package main - -import "github.com/gin-gonic/gin" - -func main() { - r := gin.Default() - r.GET("/ping", func(c *gin.Context) { - c.String(200, "pong") - }) - r.Run(":8080") // listen and serve on 0.0.0.0:8080 -} -``` - -## Benchmarks - -Gin uses a custom version of [HttpRouter](https://github.com/julienschmidt/httprouter) - -[See all benchmarks](/BENCHMARKS.md) - - -``` -BenchmarkAce_GithubAll 10000 109482 ns/op 13792 B/op 167 allocs/op -BenchmarkBear_GithubAll 10000 287490 ns/op 79952 B/op 943 allocs/op -BenchmarkBeego_GithubAll 3000 562184 ns/op 146272 B/op 2092 allocs/op -BenchmarkBone_GithubAll 500 2578716 ns/op 648016 B/op 8119 allocs/op -BenchmarkDenco_GithubAll 20000 94955 ns/op 20224 B/op 167 allocs/op -BenchmarkEcho_GithubAll 30000 58705 ns/op 0 B/op 0 allocs/op -BenchmarkGin_GithubAll 30000 50991 ns/op 0 B/op 0 allocs/op -BenchmarkGocraftWeb_GithubAll 5000 449648 ns/op 133280 B/op 1889 allocs/op -BenchmarkGoji_GithubAll 2000 689748 ns/op 56113 B/op 334 allocs/op -BenchmarkGoJsonRest_GithubAll 5000 537769 ns/op 135995 B/op 2940 allocs/op -BenchmarkGoRestful_GithubAll 100 18410628 ns/op 797236 B/op 7725 allocs/op -BenchmarkGorillaMux_GithubAll 200 8036360 ns/op 153137 B/op 1791 allocs/op -BenchmarkHttpRouter_GithubAll 20000 63506 ns/op 13792 B/op 167 allocs/op -BenchmarkHttpTreeMux_GithubAll 10000 165927 ns/op 56112 B/op 334 allocs/op -BenchmarkKocha_GithubAll 10000 171362 ns/op 23304 B/op 843 allocs/op -BenchmarkMacaron_GithubAll 2000 817008 ns/op 224960 B/op 2315 allocs/op -BenchmarkMartini_GithubAll 100 12609209 ns/op 237952 B/op 2686 allocs/op -BenchmarkPat_GithubAll 300 4830398 ns/op 1504101 B/op 32222 allocs/op -BenchmarkPossum_GithubAll 10000 301716 ns/op 97440 B/op 812 allocs/op -BenchmarkR2router_GithubAll 10000 270691 ns/op 77328 B/op 1182 allocs/op -BenchmarkRevel_GithubAll 1000 1491919 ns/op 345553 B/op 5918 allocs/op -BenchmarkRivet_GithubAll 10000 283860 ns/op 84272 B/op 1079 allocs/op -BenchmarkTango_GithubAll 5000 473821 ns/op 87078 B/op 2470 allocs/op -BenchmarkTigerTonic_GithubAll 2000 1120131 ns/op 241088 B/op 6052 allocs/op -BenchmarkTraffic_GithubAll 200 8708979 ns/op 2664762 B/op 22390 allocs/op -BenchmarkVulcan_GithubAll 5000 353392 ns/op 19894 B/op 609 allocs/op -BenchmarkZeus_GithubAll 2000 944234 ns/op 300688 B/op 2648 allocs/op -``` - - -##Gin v1. stable - -- [x] Zero allocation router. -- [x] Still the fastest http router and framework. From routing to writing. -- [x] Complete suite of unit tests -- [x] Battle tested -- [x] API frozen, new releases will not break your code. - - -## Start using it -1. Download and install it: - -```sh -go get github.com/gin-gonic/gin -``` -2. Import it in your code: - -```go -import "github.com/gin-gonic/gin" -``` - -##API Examples - -#### Using GET, POST, PUT, PATCH, DELETE and OPTIONS - -```go -func main() { - // Creates a gin router with default middlewares: - // logger and recovery (crash-free) middlewares - router := gin.Default() - - router.GET("/someGet", getting) - router.POST("/somePost", posting) - router.PUT("/somePut", putting) - router.DELETE("/someDelete", deleting) - router.PATCH("/somePatch", patching) - router.HEAD("/someHead", head) - router.OPTIONS("/someOptions", options) - - // Listen and server on 0.0.0.0:8080 - router.Run(":8080") -} -``` - -#### Parameters in path - -```go -func main() { - router := gin.Default() - - // This handler will match /user/john but will not match neither /user/ or /user - router.GET("/user/:name", func(c *gin.Context) { - name := c.Param("name") - c.String(http.StatusOK, "Hello %s", name) - }) - - // However, this one will match /user/john/ and also /user/john/send - // If no other routers match /user/john, it will redirect to /user/join/ - router.GET("/user/:name/*action", func(c *gin.Context) { - name := c.Param("name") - action := c.Param("action") - message := name + " is " + action - c.String(http.StatusOK, message) - }) - - router.Run(":8080") -} -``` - -#### Querystring parameters -```go -func main() { - router := gin.Default() - - // Query string parameters are parsed using the existing underlying request object. - // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe - router.GET("/welcome", func(c *gin.Context) { - firstname := c.DefaultQuery("firstname", "Guest") - lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname") - - c.String(http.StatusOK, "Hello %s %s", firstname, lastname) - }) - router.Run(":8080") -} -``` - -### Multipart/Urlencoded Form - -```go -func main() { - router := gin.Default() - - router.POST("/form_post", func(c *gin.Context) { - message := c.PostForm("message") - nick := c.DefaultPostForm("nick", "anonymous") - - c.JSON(200, gin.H{ - "status": "posted", - "message": message, - }) - }) - router.Run(":8080") -} -``` - -### Another example: query + post form - -``` -POST /post?id=1234&page=1 HTTP/1.1 -Content-Type: application/x-www-form-urlencoded - -name=manu&message=this_is_great -``` - -```go -func main() { - router := gin.Default() - - router.POST("/post", func(c *gin.Context) { - id := c.Query("id") - page := c.DefaultQuery("id", "0") - name := c.PostForm("name") - message := c.PostForm("message") - - fmt.Println("id: %s; page: %s; name: %s; message: %s", id, page, name, message) - }) - router.Run(":8080") -} -``` - -``` -id: 1234; page: 0; name: manu; message: this_is_great -``` - - -#### Grouping routes -```go -func main() { - router := gin.Default() - - // Simple group: v1 - v1 := router.Group("/v1") - { - v1.POST("/login", loginEndpoint) - v1.POST("/submit", submitEndpoint) - v1.POST("/read", readEndpoint) - } - - // Simple group: v2 - v2 := router.Group("/v2") - { - v2.POST("/login", loginEndpoint) - v2.POST("/submit", submitEndpoint) - v2.POST("/read", readEndpoint) - } - - router.Run(":8080") -} -``` - - -#### Blank Gin without middlewares by default - -Use - -```go -r := gin.New() -``` -instead of - -```go -r := gin.Default() -``` - - -#### Using middlewares -```go -func main() { - // Creates a router without any middleware by default - r := gin.New() - - // Global middlewares - r.Use(gin.Logger()) - r.Use(gin.Recovery()) - - // Per route middlewares, you can add as many as you desire. - r.GET("/benchmark", MyBenchLogger(), benchEndpoint) - - // Authorization group - // authorized := r.Group("/", AuthRequired()) - // exactly the same than: - authorized := r.Group("/") - // per group middlewares! in this case we use the custom created - // AuthRequired() middleware just in the "authorized" group. - authorized.Use(AuthRequired()) - { - authorized.POST("/login", loginEndpoint) - authorized.POST("/submit", submitEndpoint) - authorized.POST("/read", readEndpoint) - - // nested group - testing := authorized.Group("testing") - testing.GET("/analytics", analyticsEndpoint) - } - - // Listen and server on 0.0.0.0:8080 - r.Run(":8080") -} -``` - -#### Model binding and validation - -To bind a request body into a type, use model binding. We currently support binding of JSON, XML and standard form values (foo=bar&boo=baz). - -Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`. - -When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use BindWith. - -You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, the current request will fail with an error. - -```go -// Binding from JSON -type Login struct { - User string `form:"user" json:"user" binding:"required"` - Password string `form:"password" json:"password" binding:"required"` -} - -func main() { - router := gin.Default() - - // Example for binding JSON ({"user": "manu", "password": "123"}) - router.POST("/loginJSON", func(c *gin.Context) { - var json Login - if c.BindJSON(&json) == nil { - if json.User == "manu" && json.Password == "123" { - c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) - } else { - c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) - } - } - }) - - // Example for binding a HTML form (user=manu&password=123) - router.POST("/loginForm", func(c *gin.Context) { - var form Login - // This will infer what binder to use depending on the content-type header. - if c.Bind(&form) == nil { - if form.User == "manu" && form.Password == "123" { - c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) - } else { - c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) - } - } - }) - - // Listen and server on 0.0.0.0:8080 - router.Run(":8080") -} -``` - - -###Multipart/Urlencoded binding -```go -package main - -import ( - "github.com/gin-gonic/gin" - "github.com/gin-gonic/gin/binding" -) - -type LoginForm struct { - User string `form:"user" binding:"required"` - Password string `form:"password" binding:"required"` -} - -func main() { - router := gin.Default() - router.POST("/login", func(c *gin.Context) { - // you can bind multipart form with explicit binding declaration: - // c.BindWith(&form, binding.Form) - // or you can simply use autobinding with Bind method: - var form LoginForm - // in this case proper binding will be automatically selected - if c.Bind(&form) == nil { - if form.User == "user" && form.Password == "password" { - c.JSON(200, gin.H{"status": "you are logged in"}) - } else { - c.JSON(401, gin.H{"status": "unauthorized"}) - } - } - }) - router.Run(":8080") -} -``` - -Test it with: -```bash -$ curl -v --form user=user --form password=password http://localhost:8080/login -``` - - -#### XML and JSON rendering - -```go -func main() { - r := gin.Default() - - // gin.H is a shortcut for map[string]interface{} - r.GET("/someJSON", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) - }) - - r.GET("/moreJSON", func(c *gin.Context) { - // You also can use a struct - var msg struct { - Name string `json:"user"` - Message string - Number int - } - msg.Name = "Lena" - msg.Message = "hey" - msg.Number = 123 - // Note that msg.Name becomes "user" in the JSON - // Will output : {"user": "Lena", "Message": "hey", "Number": 123} - c.JSON(http.StatusOK, msg) - }) - - r.GET("/someXML", func(c *gin.Context) { - c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) - }) - - // Listen and server on 0.0.0.0:8080 - r.Run(":8080") -} -``` - -####Serving static files - -```go -func main() { - router := gin.Default() - router.Static("/assets", "./assets") - router.StaticFS("/more_static", http.Dir("my_file_system")) - router.StaticFile("/favicon.ico", "./resources/favicon.ico") - - // Listen and server on 0.0.0.0:8080 - router.Run(":8080") -} -``` - -####HTML rendering - -Using LoadHTMLTemplates() - -```go -func main() { - router := gin.Default() - router.LoadHTMLGlob("templates/*") - //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html") - router.GET("/index", func(c *gin.Context) { - c.HTML(http.StatusOK, "index.tmpl", gin.H{ - "title": "Main website", - }) - }) - router.Run(":8080") -} -``` -```html -

- {{ .title }} -

- -``` - -You can also use your own html template render - -```go -import "html/template" - -func main() { - router := gin.Default() - html := template.Must(template.ParseFiles("file1", "file2")) - router.SetHTMLTemplate(html) - router.Run(":8080") -} -``` - - -#### Redirects - -Issuing a HTTP redirect is easy: - -```go -r.GET("/test", func(c *gin.Context) { - c.Redirect(http.StatusMovedPermanently, "http://www.google.com/") -}) -``` -Both internal and external locations are supported. - - -#### Custom Middlewares - -```go -func Logger() gin.HandlerFunc { - return func(c *gin.Context) { - t := time.Now() - - // Set example variable - c.Set("example", "12345") - - // before request - - c.Next() - - // after request - latency := time.Since(t) - log.Print(latency) - - // access the status we are sending - status := c.Writer.Status() - log.Println(status) - } -} - -func main() { - r := gin.New() - r.Use(Logger()) - - r.GET("/test", func(c *gin.Context) { - example := c.MustGet("example").(string) - - // it would print: "12345" - log.Println(example) - }) - - // Listen and server on 0.0.0.0:8080 - r.Run(":8080") -} -``` - -#### Using BasicAuth() middleware -```go -// simulate some private data -var secrets = gin.H{ - "foo": gin.H{"email": "foo@bar.com", "phone": "123433"}, - "austin": gin.H{"email": "austin@example.com", "phone": "666"}, - "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"}, -} - -func main() { - r := gin.Default() - - // Group using gin.BasicAuth() middleware - // gin.Accounts is a shortcut for map[string]string - authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{ - "foo": "bar", - "austin": "1234", - "lena": "hello2", - "manu": "4321", - })) - - // /admin/secrets endpoint - // hit "localhost:8080/admin/secrets - authorized.GET("/secrets", func(c *gin.Context) { - // get user, it was setted by the BasicAuth middleware - user := c.MustGet(gin.AuthUserKey).(string) - if secret, ok := secrets[user]; ok { - c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret}) - } else { - c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("}) - } - }) - - // Listen and server on 0.0.0.0:8080 - r.Run(":8080") -} -``` - - -#### Goroutines inside a middleware -When starting inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy. - -```go -func main() { - r := gin.Default() - - r.GET("/long_async", func(c *gin.Context) { - // create copy to be used inside the goroutine - c_cp := c.Copy() - go func() { - // simulate a long task with time.Sleep(). 5 seconds - time.Sleep(5 * time.Second) - - // note than you are using the copied context "c_cp", IMPORTANT - log.Println("Done! in path " + c_cp.Request.URL.Path) - }() - }) - - - r.GET("/long_sync", func(c *gin.Context) { - // simulate a long task with time.Sleep(). 5 seconds - time.Sleep(5 * time.Second) - - // since we are NOT using a goroutine, we do not have to copy the context - log.Println("Done! in path " + c.Request.URL.Path) - }) - - // Listen and server on 0.0.0.0:8080 - r.Run(":8080") -} -``` - -#### Custom HTTP configuration - -Use `http.ListenAndServe()` directly, like this: - -```go -func main() { - router := gin.Default() - http.ListenAndServe(":8080", router) -} -``` -or - -```go -func main() { - router := gin.Default() - - s := &http.Server{ - Addr: ":8080", - Handler: router, - ReadTimeout: 10 * time.Second, - WriteTimeout: 10 * time.Second, - MaxHeaderBytes: 1 << 20, - } - s.ListenAndServe() -} -``` diff --git a/vendor/github.com/gin-gonic/gin/auth.go b/vendor/github.com/gin-gonic/gin/auth.go index ab4e35d76..9ed81b5dc 100644 --- a/vendor/github.com/gin-gonic/gin/auth.go +++ b/vendor/github.com/gin-gonic/gin/auth.go @@ -7,27 +7,30 @@ package gin import ( "crypto/subtle" "encoding/base64" + "net/http" "strconv" ) +// AuthUserKey is the cookie name for user credential in basic auth. const AuthUserKey = "user" -type ( - Accounts map[string]string - authPair struct { - Value string - User string - } - authPairs []authPair -) +// Accounts defines a key/value for user/pass list of authorized logins. +type Accounts map[string]string + +type authPair struct { + value string + user string +} + +type authPairs []authPair func (a authPairs) searchCredential(authValue string) (string, bool) { - if len(authValue) == 0 { + if authValue == "" { return "", false } for _, pair := range a { - if pair.Value == authValue { - return pair.User, true + if pair.value == authValue { + return pair.user, true } } return "", false @@ -45,16 +48,17 @@ func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc { pairs := processAccounts(accounts) return func(c *Context) { // Search user in the slice of allowed credentials - user, found := pairs.searchCredential(c.Request.Header.Get("Authorization")) + user, found := pairs.searchCredential(c.requestHeader("Authorization")) if !found { // Credentials doesn't match, we return 401 and abort handlers chain. c.Header("WWW-Authenticate", realm) - c.AbortWithStatus(401) - } else { - // The user credentials was found, set user's id to key AuthUserKey in this context, the userId can be read later using - // c.MustGet(gin.AuthUserKey) - c.Set(AuthUserKey, user) + c.AbortWithStatus(http.StatusUnauthorized) + return } + + // The user credentials was found, set user's id to key AuthUserKey in this context, the user's id can be read later using + // c.MustGet(gin.AuthUserKey). + c.Set(AuthUserKey, user) } } @@ -65,18 +69,14 @@ func BasicAuth(accounts Accounts) HandlerFunc { } func processAccounts(accounts Accounts) authPairs { - if len(accounts) == 0 { - panic("Empty list of authorized credentials") - } + assert1(len(accounts) > 0, "Empty list of authorized credentials") pairs := make(authPairs, 0, len(accounts)) for user, password := range accounts { - if len(user) == 0 { - panic("User can not be empty") - } + assert1(user != "", "User can not be empty") value := authorizationHeader(user, password) pairs = append(pairs, authPair{ - Value: value, - User: user, + value: value, + user: user, }) } return pairs @@ -91,6 +91,6 @@ func secureCompare(given, actual string) bool { if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 { return subtle.ConstantTimeCompare([]byte(given), []byte(actual)) == 1 } - /* Securely compare actual to itself to keep constant time, but always return false */ + // Securely compare actual to itself to keep constant time, but always return false. return subtle.ConstantTimeCompare([]byte(actual), []byte(actual)) == 1 && false } diff --git a/vendor/github.com/gin-gonic/gin/binding/binding.go b/vendor/github.com/gin-gonic/gin/binding/binding.go index 9cf701dfb..3a2aad9cc 100644 --- a/vendor/github.com/gin-gonic/gin/binding/binding.go +++ b/vendor/github.com/gin-gonic/gin/binding/binding.go @@ -6,6 +6,7 @@ package binding import "net/http" +// Content-Type MIME of the most common data formats. const ( MIMEJSON = "application/json" MIMEHTML = "text/html" @@ -14,13 +15,30 @@ const ( MIMEPlain = "text/plain" MIMEPOSTForm = "application/x-www-form-urlencoded" MIMEMultipartPOSTForm = "multipart/form-data" + MIMEPROTOBUF = "application/x-protobuf" + MIMEMSGPACK = "application/x-msgpack" + MIMEMSGPACK2 = "application/msgpack" ) +// Binding describes the interface which needs to be implemented for binding the +// data present in the request such as JSON request body, query parameters or +// the form POST. type Binding interface { Name() string Bind(*http.Request, interface{}) error } +// BindingBody adds BindBody method to Binding. BindBody is similar with Bind, +// but it reads the body from supplied bytes instead of req.Body. +type BindingBody interface { + Binding + BindBody([]byte, interface{}) error +} + +// StructValidator is the minimal interface which needs to be implemented in +// order for it to be used as the validator engine for ensuring the correctness +// of the reqest. Gin provides a default implementation for this using +// https://github.com/go-playground/validator/tree/v8.18.2. type StructValidator interface { // ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right. // If the received type is not a struct, any validation should be skipped and nil must be returned. @@ -28,30 +46,48 @@ type StructValidator interface { // If the struct is not valid or the validation itself fails, a descriptive error should be returned. // Otherwise nil must be returned. ValidateStruct(interface{}) error + + // Engine returns the underlying validator engine which powers the + // StructValidator implementation. + Engine() interface{} } +// Validator is the default validator which implements the StructValidator +// interface. It uses https://github.com/go-playground/validator/tree/v8.18.2 +// under the hood. var Validator StructValidator = &defaultValidator{} +// These implement the Binding interface and can be used to bind the data +// present in the request to struct instances. var ( JSON = jsonBinding{} XML = xmlBinding{} Form = formBinding{} + Query = queryBinding{} FormPost = formPostBinding{} FormMultipart = formMultipartBinding{} + ProtoBuf = protobufBinding{} + MsgPack = msgpackBinding{} ) +// Default returns the appropriate Binding instance based on the HTTP method +// and the content type. func Default(method, contentType string) Binding { if method == "GET" { return Form - } else { - switch contentType { - case MIMEJSON: - return JSON - case MIMEXML, MIMEXML2: - return XML - default: //case MIMEPOSTForm, MIMEMultipartPOSTForm: - return Form - } + } + + switch contentType { + case MIMEJSON: + return JSON + case MIMEXML, MIMEXML2: + return XML + case MIMEPROTOBUF: + return ProtoBuf + case MIMEMSGPACK, MIMEMSGPACK2: + return MsgPack + default: //case MIMEPOSTForm, MIMEMultipartPOSTForm: + return Form } } diff --git a/vendor/github.com/gin-gonic/gin/binding/default_validator.go b/vendor/github.com/gin-gonic/gin/binding/default_validator.go index 7f12152b0..e7a302de6 100644 --- a/vendor/github.com/gin-gonic/gin/binding/default_validator.go +++ b/vendor/github.com/gin-gonic/gin/binding/default_validator.go @@ -1,10 +1,14 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + package binding import ( "reflect" "sync" - "gopkg.in/bluesuncorp/validator.v5" + "gopkg.in/go-playground/validator.v8" ) type defaultValidator struct { @@ -14,27 +18,34 @@ type defaultValidator struct { var _ StructValidator = &defaultValidator{} +// ValidateStruct receives any kind of type, but only performed struct or pointer to struct type. func (v *defaultValidator) ValidateStruct(obj interface{}) error { - if kindOfData(obj) == reflect.Struct { + value := reflect.ValueOf(obj) + valueType := value.Kind() + if valueType == reflect.Ptr { + valueType = value.Elem().Kind() + } + if valueType == reflect.Struct { v.lazyinit() if err := v.validate.Struct(obj); err != nil { - return error(err) + return err } } return nil } +// Engine returns the underlying validator engine which powers the default +// Validator instance. This is useful if you want to register custom validations +// or struct level validations. See validator GoDoc for more info - +// https://godoc.org/gopkg.in/go-playground/validator.v8 +func (v *defaultValidator) Engine() interface{} { + v.lazyinit() + return v.validate +} + func (v *defaultValidator) lazyinit() { v.once.Do(func() { - v.validate = validator.New("binding", validator.BakedInValidators) + config := &validator.Config{TagName: "binding"} + v.validate = validator.New(config) }) } - -func kindOfData(data interface{}) reflect.Kind { - value := reflect.ValueOf(data) - valueType := value.Kind() - if valueType == reflect.Ptr { - valueType = value.Elem().Kind() - } - return valueType -} diff --git a/vendor/github.com/gin-gonic/gin/binding/form.go b/vendor/github.com/gin-gonic/gin/binding/form.go index 2e26c0aca..0be59660b 100644 --- a/vendor/github.com/gin-gonic/gin/binding/form.go +++ b/vendor/github.com/gin-gonic/gin/binding/form.go @@ -6,30 +6,32 @@ package binding import "net/http" +const defaultMemory = 32 * 1024 * 1024 + type formBinding struct{} type formPostBinding struct{} type formMultipartBinding struct{} -func (_ formBinding) Name() string { +func (formBinding) Name() string { return "form" } -func (_ formBinding) Bind(req *http.Request, obj interface{}) error { +func (formBinding) Bind(req *http.Request, obj interface{}) error { if err := req.ParseForm(); err != nil { return err } - req.ParseMultipartForm(32 << 10) // 32 MB + req.ParseMultipartForm(defaultMemory) if err := mapForm(obj, req.Form); err != nil { return err } return validate(obj) } -func (_ formPostBinding) Name() string { +func (formPostBinding) Name() string { return "form-urlencoded" } -func (_ formPostBinding) Bind(req *http.Request, obj interface{}) error { +func (formPostBinding) Bind(req *http.Request, obj interface{}) error { if err := req.ParseForm(); err != nil { return err } @@ -39,12 +41,12 @@ func (_ formPostBinding) Bind(req *http.Request, obj interface{}) error { return validate(obj) } -func (_ formMultipartBinding) Name() string { +func (formMultipartBinding) Name() string { return "multipart/form-data" } -func (_ formMultipartBinding) Bind(req *http.Request, obj interface{}) error { - if err := req.ParseMultipartForm(32 << 10); err != nil { +func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error { + if err := req.ParseMultipartForm(defaultMemory); err != nil { return err } if err := mapForm(obj, req.MultipartForm.Value); err != nil { diff --git a/vendor/github.com/gin-gonic/gin/binding/form_mapping.go b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go index 07c837512..3f6b9bfa1 100644 --- a/vendor/github.com/gin-gonic/gin/binding/form_mapping.go +++ b/vendor/github.com/gin-gonic/gin/binding/form_mapping.go @@ -8,6 +8,8 @@ import ( "errors" "reflect" "strconv" + "strings" + "time" ) func mapForm(ptr interface{}, form map[string][]string) error { @@ -22,12 +24,28 @@ func mapForm(ptr interface{}, form map[string][]string) error { structFieldKind := structField.Kind() inputFieldName := typeField.Tag.Get("form") + inputFieldNameList := strings.Split(inputFieldName, ",") + inputFieldName = inputFieldNameList[0] + var defaultValue string + if len(inputFieldNameList) > 1 { + defaultList := strings.SplitN(inputFieldNameList[1], "=", 2) + if defaultList[0] == "default" { + defaultValue = defaultList[1] + } + } if inputFieldName == "" { inputFieldName = typeField.Name - // if "form" tag is nil, we inspect if the field is a struct. + // if "form" tag is nil, we inspect if the field is a struct or struct pointer. // this would not make sense for JSON parsing but it does for a form // since data is flatten + if structFieldKind == reflect.Ptr { + if !structField.Elem().IsValid() { + structField.Set(reflect.New(structField.Type().Elem())) + } + structField = structField.Elem() + structFieldKind = structField.Kind() + } if structFieldKind == reflect.Struct { err := mapForm(structField.Addr().Interface(), form) if err != nil { @@ -37,8 +55,13 @@ func mapForm(ptr interface{}, form map[string][]string) error { } } inputValue, exists := form[inputFieldName] + if !exists { - continue + if defaultValue == "" { + continue + } + inputValue = make([]string, 1) + inputValue[0] = defaultValue } numElems := len(inputValue) @@ -52,6 +75,12 @@ func mapForm(ptr interface{}, form map[string][]string) error { } val.Field(i).Set(slice) } else { + if _, isTime := structField.Interface().(time.Time); isTime { + if err := setTimeField(inputValue[0], typeField, structField); err != nil { + return err + } + continue + } if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil { return err } @@ -90,6 +119,12 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V return setFloatField(val, 64, structField) case reflect.String: structField.SetString(val) + case reflect.Ptr: + if !structField.Elem().IsValid() { + structField.Set(reflect.New(structField.Type().Elem())) + } + structFieldElem := structField.Elem() + return setWithProperType(structFieldElem.Kind(), val, structFieldElem) default: return errors.New("Unknown type") } @@ -126,7 +161,7 @@ func setBoolField(val string, field reflect.Value) error { if err == nil { field.SetBool(boolVal) } - return nil + return err } func setFloatField(val string, bitSize int, field reflect.Value) error { @@ -140,11 +175,35 @@ func setFloatField(val string, bitSize int, field reflect.Value) error { return err } -// Don't pass in pointers to bind to. Can lead to bugs. See: -// https://github.com/codegangsta/martini-contrib/issues/40 -// https://github.com/codegangsta/martini-contrib/pull/34#issuecomment-29683659 -func ensureNotPointer(obj interface{}) { - if reflect.TypeOf(obj).Kind() == reflect.Ptr { - panic("Pointers are not accepted as binding models") +func setTimeField(val string, structField reflect.StructField, value reflect.Value) error { + timeFormat := structField.Tag.Get("time_format") + if timeFormat == "" { + return errors.New("Blank time format") + } + + if val == "" { + value.Set(reflect.ValueOf(time.Time{})) + return nil } + + l := time.Local + if isUTC, _ := strconv.ParseBool(structField.Tag.Get("time_utc")); isUTC { + l = time.UTC + } + + if locTag := structField.Tag.Get("time_location"); locTag != "" { + loc, err := time.LoadLocation(locTag) + if err != nil { + return err + } + l = loc + } + + t, err := time.ParseInLocation(timeFormat, val, l) + if err != nil { + return err + } + + value.Set(reflect.ValueOf(t)) + return nil } diff --git a/vendor/github.com/gin-gonic/gin/binding/json.go b/vendor/github.com/gin-gonic/gin/binding/json.go index 25c5a06c7..fea17bb2f 100644 --- a/vendor/github.com/gin-gonic/gin/binding/json.go +++ b/vendor/github.com/gin-gonic/gin/binding/json.go @@ -5,19 +5,37 @@ package binding import ( - "encoding/json" - + "bytes" + "io" "net/http" + + "github.com/gin-gonic/gin/json" ) +// EnableDecoderUseNumber is used to call the UseNumber method on the JSON +// Decoder instance. UseNumber causes the Decoder to unmarshal a number into an +// interface{} as a Number instead of as a float64. +var EnableDecoderUseNumber = false + type jsonBinding struct{} -func (_ jsonBinding) Name() string { +func (jsonBinding) Name() string { return "json" } -func (_ jsonBinding) Bind(req *http.Request, obj interface{}) error { - decoder := json.NewDecoder(req.Body) +func (jsonBinding) Bind(req *http.Request, obj interface{}) error { + return decodeJSON(req.Body, obj) +} + +func (jsonBinding) BindBody(body []byte, obj interface{}) error { + return decodeJSON(bytes.NewReader(body), obj) +} + +func decodeJSON(r io.Reader, obj interface{}) error { + decoder := json.NewDecoder(r) + if EnableDecoderUseNumber { + decoder.UseNumber() + } if err := decoder.Decode(obj); err != nil { return err } diff --git a/vendor/github.com/gin-gonic/gin/binding/msgpack.go b/vendor/github.com/gin-gonic/gin/binding/msgpack.go new file mode 100644 index 000000000..b7f731977 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/msgpack.go @@ -0,0 +1,35 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "bytes" + "io" + "net/http" + + "github.com/ugorji/go/codec" +) + +type msgpackBinding struct{} + +func (msgpackBinding) Name() string { + return "msgpack" +} + +func (msgpackBinding) Bind(req *http.Request, obj interface{}) error { + return decodeMsgPack(req.Body, obj) +} + +func (msgpackBinding) BindBody(body []byte, obj interface{}) error { + return decodeMsgPack(bytes.NewReader(body), obj) +} + +func decodeMsgPack(r io.Reader, obj interface{}) error { + cdc := new(codec.MsgpackHandle) + if err := codec.NewDecoder(r, cdc).Decode(&obj); err != nil { + return err + } + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/protobuf.go b/vendor/github.com/gin-gonic/gin/binding/protobuf.go new file mode 100644 index 000000000..540e9c1f7 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/protobuf.go @@ -0,0 +1,36 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import ( + "io/ioutil" + "net/http" + + "github.com/golang/protobuf/proto" +) + +type protobufBinding struct{} + +func (protobufBinding) Name() string { + return "protobuf" +} + +func (b protobufBinding) Bind(req *http.Request, obj interface{}) error { + buf, err := ioutil.ReadAll(req.Body) + if err != nil { + return err + } + return b.BindBody(buf, obj) +} + +func (protobufBinding) BindBody(body []byte, obj interface{}) error { + if err := proto.Unmarshal(body, obj.(proto.Message)); err != nil { + return err + } + // Here it's same to return validate(obj), but util now we cann't add + // `binding:""` to the struct which automatically generate by gen-proto + return nil + // return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/query.go b/vendor/github.com/gin-gonic/gin/binding/query.go new file mode 100644 index 000000000..219743f2a --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/binding/query.go @@ -0,0 +1,21 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package binding + +import "net/http" + +type queryBinding struct{} + +func (queryBinding) Name() string { + return "query" +} + +func (queryBinding) Bind(req *http.Request, obj interface{}) error { + values := req.URL.Query() + if err := mapForm(obj, values); err != nil { + return err + } + return validate(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/binding/xml.go b/vendor/github.com/gin-gonic/gin/binding/xml.go index cac4be895..4e9011496 100644 --- a/vendor/github.com/gin-gonic/gin/binding/xml.go +++ b/vendor/github.com/gin-gonic/gin/binding/xml.go @@ -5,18 +5,27 @@ package binding import ( + "bytes" "encoding/xml" + "io" "net/http" ) type xmlBinding struct{} -func (_ xmlBinding) Name() string { +func (xmlBinding) Name() string { return "xml" } -func (_ xmlBinding) Bind(req *http.Request, obj interface{}) error { - decoder := xml.NewDecoder(req.Body) +func (xmlBinding) Bind(req *http.Request, obj interface{}) error { + return decodeXML(req.Body, obj) +} + +func (xmlBinding) BindBody(body []byte, obj interface{}) error { + return decodeXML(bytes.NewReader(body), obj) +} +func decodeXML(r io.Reader, obj interface{}) error { + decoder := xml.NewDecoder(r) if err := decoder.Decode(obj); err != nil { return err } diff --git a/vendor/github.com/gin-gonic/gin/context.go b/vendor/github.com/gin-gonic/gin/context.go index 20a20e330..724ded790 100644 --- a/vendor/github.com/gin-gonic/gin/context.go +++ b/vendor/github.com/gin-gonic/gin/context.go @@ -7,18 +7,22 @@ package gin import ( "errors" "io" + "io/ioutil" "math" + "mime/multipart" + "net" "net/http" + "net/url" + "os" "strings" "time" + "github.com/gin-contrib/sse" "github.com/gin-gonic/gin/binding" "github.com/gin-gonic/gin/render" - "github.com/manucorporat/sse" - "golang.org/x/net/context" ) -// Content-Type MIME of the most common data formats +// Content-Type MIME of the most common data formats. const ( MIMEJSON = binding.MIMEJSON MIMEHTML = binding.MIMEHTML @@ -27,6 +31,7 @@ const ( MIMEPlain = binding.MIMEPlain MIMEPOSTForm = binding.MIMEPOSTForm MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm + BodyBytesKey = "_gin-gonic/gin/bodybyteskey" ) const abortIndex int8 = math.MaxInt8 / 2 @@ -42,14 +47,18 @@ type Context struct { handlers HandlersChain index int8 - engine *Engine - Keys map[string]interface{} - Errors errorMsgs + engine *Engine + + // Keys is a key/value pair exclusively for the context of each request. + Keys map[string]interface{} + + // Errors is a list of errors attached to all the handlers/middlewares who used this context. + Errors errorMsgs + + // Accepted defines a list of manually accepted formats for content negotiation. Accepted []string } -var _ context.Context = &Context{} - /************************************/ /********** CONTEXT CREATION ********/ /************************************/ @@ -65,9 +74,9 @@ func (c *Context) reset() { } // Copy returns a copy of the current context that can be safely used outside the request's scope. -// This have to be used then the context has to be passed to a goroutine. +// This has to be used when the context has to be passed to a goroutine. func (c *Context) Copy() *Context { - var cp Context = *c + var cp = *c cp.writermem.ResponseWriter = nil cp.Writer = &cp.writermem cp.index = abortIndex @@ -75,49 +84,62 @@ func (c *Context) Copy() *Context { return &cp } -// HandlerName returns the main handle's name. For example if the handler is "handleGetUsers()", this -// function will return "main.handleGetUsers" +// HandlerName returns the main handler's name. For example if the handler is "handleGetUsers()", +// this function will return "main.handleGetUsers". func (c *Context) HandlerName() string { return nameOfFunction(c.handlers.Last()) } +// Handler returns the main handler. +func (c *Context) Handler() HandlerFunc { + return c.handlers.Last() +} + /************************************/ /*********** FLOW CONTROL ***********/ /************************************/ -// Next should be used only in the middlewares. +// Next should be used only inside middleware. // It executes the pending handlers in the chain inside the calling handler. -// See example in github. +// See example in GitHub. func (c *Context) Next() { c.index++ - s := int8(len(c.handlers)) - for ; c.index < s; c.index++ { + for s := int8(len(c.handlers)); c.index < s; c.index++ { c.handlers[c.index](c) } } -// IsAborted returns true if the currect context was aborted. +// IsAborted returns true if the current context was aborted. func (c *Context) IsAborted() bool { return c.index >= abortIndex } -// Abort stops the system to continue calling the pending handlers in the chain. -// Let's say you have an authorization middleware that validates if the request is authorized -// if the authorization fails (the password does not match). This method (Abort()) should be called -// in order to stop the execution of the actual handler. +// Abort prevents pending handlers from being called. Note that this will not stop the current handler. +// Let's say you have an authorization middleware that validates that the current request is authorized. +// If the authorization fails (ex: the password does not match), call Abort to ensure the remaining handlers +// for this request are not called. func (c *Context) Abort() { c.index = abortIndex } // AbortWithStatus calls `Abort()` and writes the headers with the specified status code. -// For example, a failed attempt to authentificate a request could use: context.AbortWithStatus(401). +// For example, a failed attempt to authenticate a request could use: context.AbortWithStatus(401). func (c *Context) AbortWithStatus(code int) { - c.Writer.WriteHeader(code) + c.Status(code) + c.Writer.WriteHeaderNow() c.Abort() } -// AbortWithError calls `AbortWithStatus()` and `Error()` internally. This method stops the chain, writes the status code and -// pushes the specified error to `c.Errors`. +// AbortWithStatusJSON calls `Abort()` and then `JSON` internally. +// This method stops the chain, writes the status code and return a JSON body. +// It also sets the Content-Type as "application/json". +func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) { + c.Abort() + c.JSON(code, jsonObj) +} + +// AbortWithError calls `AbortWithStatus()` and `Error()` internally. +// This method stops the chain, writes the status code and pushes the specified error to `c.Errors`. // See Context.Error() for more details. func (c *Context) AbortWithError(code int, err error) *Error { c.AbortWithStatus(code) @@ -128,21 +150,24 @@ func (c *Context) AbortWithError(code int, err error) *Error { /********* ERROR MANAGEMENT *********/ /************************************/ -// Attaches an error to the current context. The error is pushed to a list of errors. +// Error attaches an error to the current context. The error is pushed to a list of errors. // It's a good idea to call Error for each error that occurred during the resolution of a request. -// A middleware can be used to collect all the errors -// and push them to a database together, print a log, or append it in the HTTP response. +// A middleware can be used to collect all the errors and push them to a database together, +// print a log, or append it in the HTTP response. +// Error will panic if err is nil. func (c *Context) Error(err error) *Error { - var parsedError *Error - switch err.(type) { - case *Error: - parsedError = err.(*Error) - default: + if err == nil { + panic("err is nil") + } + + parsedError, ok := err.(*Error) + if !ok { parsedError = &Error{ Err: err, Type: ErrorTypePrivate, } } + c.Errors = append(c.Errors, parsedError) return parsedError } @@ -151,7 +176,7 @@ func (c *Context) Error(err error) *Error { /******** METADATA MANAGEMENT********/ /************************************/ -// Set is used to store a new key/value pair exclusivelly for this context. +// Set is used to store a new key/value pair exclusively for this context. // It also lazy initializes c.Keys if it was not used previously. func (c *Context) Set(key string, value interface{}) { if c.Keys == nil { @@ -163,13 +188,11 @@ func (c *Context) Set(key string, value interface{}) { // Get returns the value for the given key, ie: (value, true). // If the value does not exists it returns (nil, false) func (c *Context) Get(key string) (value interface{}, exists bool) { - if c.Keys != nil { - value, exists = c.Keys[key] - } + value, exists = c.Keys[key] return } -// Returns the value for the given key if it exists, otherwise it panics. +// MustGet returns the value for the given key if it exists, otherwise it panics. func (c *Context) MustGet(key string) interface{} { if value, exists := c.Get(key); exists { return value @@ -177,121 +200,412 @@ func (c *Context) MustGet(key string) interface{} { panic("Key \"" + key + "\" does not exist") } -/************************************/ -/************ INPUT DATA ************/ -/************************************/ +// GetString returns the value associated with the key as a string. +func (c *Context) GetString(key string) (s string) { + if val, ok := c.Get(key); ok && val != nil { + s, _ = val.(string) + } + return +} + +// GetBool returns the value associated with the key as a boolean. +func (c *Context) GetBool(key string) (b bool) { + if val, ok := c.Get(key); ok && val != nil { + b, _ = val.(bool) + } + return +} + +// GetInt returns the value associated with the key as an integer. +func (c *Context) GetInt(key string) (i int) { + if val, ok := c.Get(key); ok && val != nil { + i, _ = val.(int) + } + return +} + +// GetInt64 returns the value associated with the key as an integer. +func (c *Context) GetInt64(key string) (i64 int64) { + if val, ok := c.Get(key); ok && val != nil { + i64, _ = val.(int64) + } + return +} + +// GetFloat64 returns the value associated with the key as a float64. +func (c *Context) GetFloat64(key string) (f64 float64) { + if val, ok := c.Get(key); ok && val != nil { + f64, _ = val.(float64) + } + return +} + +// GetTime returns the value associated with the key as time. +func (c *Context) GetTime(key string) (t time.Time) { + if val, ok := c.Get(key); ok && val != nil { + t, _ = val.(time.Time) + } + return +} + +// GetDuration returns the value associated with the key as a duration. +func (c *Context) GetDuration(key string) (d time.Duration) { + if val, ok := c.Get(key); ok && val != nil { + d, _ = val.(time.Duration) + } + return +} + +// GetStringSlice returns the value associated with the key as a slice of strings. +func (c *Context) GetStringSlice(key string) (ss []string) { + if val, ok := c.Get(key); ok && val != nil { + ss, _ = val.([]string) + } + return +} + +// GetStringMap returns the value associated with the key as a map of interfaces. +func (c *Context) GetStringMap(key string) (sm map[string]interface{}) { + if val, ok := c.Get(key); ok && val != nil { + sm, _ = val.(map[string]interface{}) + } + return +} -// Query is a shortcut for c.Request.URL.Query().Get(key) -// It is used to return the url query values. -// ?id=1234&name=Manu -// c.Query("id") == "1234" -// c.Query("name") == "Manu" -// c.Query("wtf") == "" -func (c *Context) Query(key string) (va string) { - va, _ = c.query(key) +// GetStringMapString returns the value associated with the key as a map of strings. +func (c *Context) GetStringMapString(key string) (sms map[string]string) { + if val, ok := c.Get(key); ok && val != nil { + sms, _ = val.(map[string]string) + } return } -// PostForm is a shortcut for c.Request.PostFormValue(key) -func (c *Context) PostForm(key string) (va string) { - va, _ = c.postForm(key) +// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings. +func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string) { + if val, ok := c.Get(key); ok && val != nil { + smss, _ = val.(map[string][]string) + } return } -// Param is a shortcut for c.Params.ByName(key) +/************************************/ +/************ INPUT DATA ************/ +/************************************/ + +// Param returns the value of the URL param. +// It is a shortcut for c.Params.ByName(key) +// router.GET("/user/:id", func(c *gin.Context) { +// // a GET request to /user/john +// id := c.Param("id") // id == "john" +// }) func (c *Context) Param(key string) string { return c.Params.ByName(key) } -func (c *Context) DefaultPostForm(key, defaultValue string) string { - if va, ok := c.postForm(key); ok { - return va +// Query returns the keyed url query value if it exists, +// otherwise it returns an empty string `("")`. +// It is shortcut for `c.Request.URL.Query().Get(key)` +// GET /path?id=1234&name=Manu&value= +// c.Query("id") == "1234" +// c.Query("name") == "Manu" +// c.Query("value") == "" +// c.Query("wtf") == "" +func (c *Context) Query(key string) string { + value, _ := c.GetQuery(key) + return value +} + +// DefaultQuery returns the keyed url query value if it exists, +// otherwise it returns the specified defaultValue string. +// See: Query() and GetQuery() for further information. +// GET /?name=Manu&lastname= +// c.DefaultQuery("name", "unknown") == "Manu" +// c.DefaultQuery("id", "none") == "none" +// c.DefaultQuery("lastname", "none") == "" +func (c *Context) DefaultQuery(key, defaultValue string) string { + if value, ok := c.GetQuery(key); ok { + return value } return defaultValue } -// DefaultQuery returns the keyed url query value if it exists, othewise it returns the -// specified defaultValue. -// ``` -// /?name=Manu -// c.DefaultQuery("name", "unknown") == "Manu" -// c.DefaultQuery("id", "none") == "none" -// ``` -func (c *Context) DefaultQuery(key, defaultValue string) string { - if va, ok := c.query(key); ok { - return va +// GetQuery is like Query(), it returns the keyed url query value +// if it exists `(value, true)` (even when the value is an empty string), +// otherwise it returns `("", false)`. +// It is shortcut for `c.Request.URL.Query().Get(key)` +// GET /?name=Manu&lastname= +// ("Manu", true) == c.GetQuery("name") +// ("", false) == c.GetQuery("id") +// ("", true) == c.GetQuery("lastname") +func (c *Context) GetQuery(key string) (string, bool) { + if values, ok := c.GetQueryArray(key); ok { + return values[0], ok + } + return "", false +} + +// QueryArray returns a slice of strings for a given query key. +// The length of the slice depends on the number of params with the given key. +func (c *Context) QueryArray(key string) []string { + values, _ := c.GetQueryArray(key) + return values +} + +// GetQueryArray returns a slice of strings for a given query key, plus +// a boolean value whether at least one value exists for the given key. +func (c *Context) GetQueryArray(key string) ([]string, bool) { + if values, ok := c.Request.URL.Query()[key]; ok && len(values) > 0 { + return values, true + } + return []string{}, false +} + +// QueryMap returns a map for a given query key. +func (c *Context) QueryMap(key string) map[string]string { + dicts, _ := c.GetQueryMap(key) + return dicts +} + +// GetQueryMap returns a map for a given query key, plus a boolean value +// whether at least one value exists for the given key. +func (c *Context) GetQueryMap(key string) (map[string]string, bool) { + return c.get(c.Request.URL.Query(), key) +} + +// PostForm returns the specified key from a POST urlencoded form or multipart form +// when it exists, otherwise it returns an empty string `("")`. +func (c *Context) PostForm(key string) string { + value, _ := c.GetPostForm(key) + return value +} + +// DefaultPostForm returns the specified key from a POST urlencoded form or multipart form +// when it exists, otherwise it returns the specified defaultValue string. +// See: PostForm() and GetPostForm() for further information. +func (c *Context) DefaultPostForm(key, defaultValue string) string { + if value, ok := c.GetPostForm(key); ok { + return value } return defaultValue } -func (c *Context) query(key string) (string, bool) { - req := c.Request - if values, ok := req.URL.Query()[key]; ok && len(values) > 0 { - return values[0], true +// GetPostForm is like PostForm(key). It returns the specified key from a POST urlencoded +// form or multipart form when it exists `(value, true)` (even when the value is an empty string), +// otherwise it returns ("", false). +// For example, during a PATCH request to update the user's email: +// email=mail@example.com --> ("mail@example.com", true) := GetPostForm("email") // set email to "mail@example.com" +// email= --> ("", true) := GetPostForm("email") // set email to "" +// --> ("", false) := GetPostForm("email") // do nothing with email +func (c *Context) GetPostForm(key string) (string, bool) { + if values, ok := c.GetPostFormArray(key); ok { + return values[0], ok } return "", false } -func (c *Context) postForm(key string) (string, bool) { +// PostFormArray returns a slice of strings for a given form key. +// The length of the slice depends on the number of params with the given key. +func (c *Context) PostFormArray(key string) []string { + values, _ := c.GetPostFormArray(key) + return values +} + +// GetPostFormArray returns a slice of strings for a given form key, plus +// a boolean value whether at least one value exists for the given key. +func (c *Context) GetPostFormArray(key string) ([]string, bool) { req := c.Request - req.ParseMultipartForm(32 << 20) // 32 MB + req.ParseForm() + req.ParseMultipartForm(c.engine.MaxMultipartMemory) if values := req.PostForm[key]; len(values) > 0 { - return values[0], true + return values, true } if req.MultipartForm != nil && req.MultipartForm.File != nil { if values := req.MultipartForm.Value[key]; len(values) > 0 { - return values[0], true + return values, true } } - return "", false + return []string{}, false +} + +// PostFormMap returns a map for a given form key. +func (c *Context) PostFormMap(key string) map[string]string { + dicts, _ := c.GetPostFormMap(key) + return dicts +} + +// GetPostFormMap returns a map for a given form key, plus a boolean value +// whether at least one value exists for the given key. +func (c *Context) GetPostFormMap(key string) (map[string]string, bool) { + req := c.Request + req.ParseForm() + req.ParseMultipartForm(c.engine.MaxMultipartMemory) + dicts, exist := c.get(req.PostForm, key) + + if !exist && req.MultipartForm != nil && req.MultipartForm.File != nil { + dicts, exist = c.get(req.MultipartForm.Value, key) + } + + return dicts, exist +} + +// get is an internal method and returns a map which satisfy conditions. +func (c *Context) get(m map[string][]string, key string) (map[string]string, bool) { + dicts := make(map[string]string) + exist := false + for k, v := range m { + if i := strings.IndexByte(k, '['); i >= 1 && k[0:i] == key { + if j := strings.IndexByte(k[i+1:], ']'); j >= 1 { + exist = true + dicts[k[i+1:][:j]] = v[0] + } + } + } + return dicts, exist +} + +// FormFile returns the first file for the provided form key. +func (c *Context) FormFile(name string) (*multipart.FileHeader, error) { + _, fh, err := c.Request.FormFile(name) + return fh, err +} + +// MultipartForm is the parsed multipart form, including file uploads. +func (c *Context) MultipartForm() (*multipart.Form, error) { + err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory) + return c.Request.MultipartForm, err +} + +// SaveUploadedFile uploads the form file to specific dst. +func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error { + src, err := file.Open() + if err != nil { + return err + } + defer src.Close() + + out, err := os.Create(dst) + if err != nil { + return err + } + defer out.Close() + + io.Copy(out, src) + return nil } // Bind checks the Content-Type to select a binding engine automatically, // Depending the "Content-Type" header different bindings are used: -// "application/json" --> JSON binding -// "application/xml" --> XML binding -// otherwise --> returns an error -// If Parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input. +// "application/json" --> JSON binding +// "application/xml" --> XML binding +// otherwise --> returns an error. +// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input. // It decodes the json payload into the struct specified as a pointer. -// Like ParseBody() but this method also writes a 400 error if the json is not valid. +// It writes a 400 error and sets Content-Type header "text/plain" in the response if input is not valid. func (c *Context) Bind(obj interface{}) error { b := binding.Default(c.Request.Method, c.ContentType()) - return c.BindWith(obj, b) + return c.MustBindWith(obj, b) } -// BindJSON is a shortcut for c.BindWith(obj, binding.JSON) +// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON). func (c *Context) BindJSON(obj interface{}) error { - return c.BindWith(obj, binding.JSON) + return c.MustBindWith(obj, binding.JSON) } -// BindWith binds the passed struct pointer using the specified binding engine. +// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query). +func (c *Context) BindQuery(obj interface{}) error { + return c.MustBindWith(obj, binding.Query) +} + +// MustBindWith binds the passed struct pointer using the specified binding engine. +// It will abort the request with HTTP 400 if any error ocurrs. // See the binding package. -func (c *Context) BindWith(obj interface{}, b binding.Binding) error { - if err := b.Bind(c.Request, obj); err != nil { - c.AbortWithError(400, err).SetType(ErrorTypeBind) - return err +func (c *Context) MustBindWith(obj interface{}, b binding.Binding) (err error) { + if err = c.ShouldBindWith(obj, b); err != nil { + c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) } - return nil + + return +} + +// ShouldBind checks the Content-Type to select a binding engine automatically, +// Depending the "Content-Type" header different bindings are used: +// "application/json" --> JSON binding +// "application/xml" --> XML binding +// otherwise --> returns an error +// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input. +// It decodes the json payload into the struct specified as a pointer. +// Like c.Bind() but this method does not set the response status code to 400 and abort if the json is not valid. +func (c *Context) ShouldBind(obj interface{}) error { + b := binding.Default(c.Request.Method, c.ContentType()) + return c.ShouldBindWith(obj, b) +} + +// ShouldBindJSON is a shortcut for c.ShouldBindWith(obj, binding.JSON). +func (c *Context) ShouldBindJSON(obj interface{}) error { + return c.ShouldBindWith(obj, binding.JSON) +} + +// ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query). +func (c *Context) ShouldBindQuery(obj interface{}) error { + return c.ShouldBindWith(obj, binding.Query) +} + +// ShouldBindWith binds the passed struct pointer using the specified binding engine. +// See the binding package. +func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error { + return b.Bind(c.Request, obj) +} + +// ShouldBindBodyWith is similar with ShouldBindWith, but it stores the request +// body into the context, and reuse when it is called again. +// +// NOTE: This method reads the body before binding. So you should use +// ShouldBindWith for better performance if you need to call only once. +func (c *Context) ShouldBindBodyWith( + obj interface{}, bb binding.BindingBody, +) (err error) { + var body []byte + if cb, ok := c.Get(BodyBytesKey); ok { + if cbb, ok := cb.([]byte); ok { + body = cbb + } + } + if body == nil { + body, err = ioutil.ReadAll(c.Request.Body) + if err != nil { + return err + } + c.Set(BodyBytesKey, body) + } + return bb.BindBody(body, obj) } // ClientIP implements a best effort algorithm to return the real client IP, it parses // X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy. +// Use X-Forwarded-For before X-Real-Ip as nginx uses X-Real-Ip with the proxy's IP. func (c *Context) ClientIP() string { if c.engine.ForwardedByClientIP { - clientIP := strings.TrimSpace(c.requestHeader("X-Real-Ip")) - if len(clientIP) > 0 { - return clientIP + clientIP := c.requestHeader("X-Forwarded-For") + clientIP = strings.TrimSpace(strings.Split(clientIP, ",")[0]) + if clientIP == "" { + clientIP = strings.TrimSpace(c.requestHeader("X-Real-Ip")) } - clientIP = c.requestHeader("X-Forwarded-For") - if index := strings.IndexByte(clientIP, ','); index >= 0 { - clientIP = clientIP[0:index] - } - clientIP = strings.TrimSpace(clientIP) - if len(clientIP) > 0 { + if clientIP != "" { return clientIP } } - return strings.TrimSpace(c.Request.RemoteAddr) + + if c.engine.AppEngine { + if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" { + return addr + } + } + + if ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr)); err == nil { + return ip + } + + return "" } // ContentType returns the Content-Type header of the request. @@ -299,38 +613,106 @@ func (c *Context) ContentType() string { return filterFlags(c.requestHeader("Content-Type")) } -func (c *Context) requestHeader(key string) string { - if values, _ := c.Request.Header[key]; len(values) > 0 { - return values[0] +// IsWebsocket returns true if the request headers indicate that a websocket +// handshake is being initiated by the client. +func (c *Context) IsWebsocket() bool { + if strings.Contains(strings.ToLower(c.requestHeader("Connection")), "upgrade") && + strings.ToLower(c.requestHeader("Upgrade")) == "websocket" { + return true } - return "" + return false +} + +func (c *Context) requestHeader(key string) string { + return c.Request.Header.Get(key) } /************************************/ /******** RESPONSE RENDERING ********/ /************************************/ -// Header is a intelligent shortcut for c.Writer.Header().Set(key, value) +// bodyAllowedForStatus is a copy of http.bodyAllowedForStatus non-exported function. +func bodyAllowedForStatus(status int) bool { + switch { + case status >= 100 && status <= 199: + return false + case status == http.StatusNoContent: + return false + case status == http.StatusNotModified: + return false + } + return true +} + +// Status sets the HTTP response code. +func (c *Context) Status(code int) { + c.writermem.WriteHeader(code) +} + +// Header is a intelligent shortcut for c.Writer.Header().Set(key, value). // It writes a header in the response. // If value == "", this method removes the header `c.Writer.Header().Del(key)` func (c *Context) Header(key, value string) { - if len(value) == 0 { + if value == "" { c.Writer.Header().Del(key) } else { c.Writer.Header().Set(key, value) } } -func (c *Context) Render(code int, r render.Render) { - c.writermem.WriteHeader(code) - if err := r.Render(c.Writer); err != nil { - c.renderError(err) +// GetHeader returns value from request headers. +func (c *Context) GetHeader(key string) string { + return c.requestHeader(key) +} + +// GetRawData return stream data. +func (c *Context) GetRawData() ([]byte, error) { + return ioutil.ReadAll(c.Request.Body) +} + +// SetCookie adds a Set-Cookie header to the ResponseWriter's headers. +// The provided cookie must have a valid Name. Invalid cookies may be +// silently dropped. +func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) { + if path == "" { + path = "/" } + http.SetCookie(c.Writer, &http.Cookie{ + Name: name, + Value: url.QueryEscape(value), + MaxAge: maxAge, + Path: path, + Domain: domain, + Secure: secure, + HttpOnly: httpOnly, + }) } -func (c *Context) renderError(err error) { - debugPrintError(err) - c.AbortWithError(500, err).SetType(ErrorTypeRender) +// Cookie returns the named cookie provided in the request or +// ErrNoCookie if not found. And return the named cookie is unescaped. +// If multiple cookies match the given name, only one cookie will +// be returned. +func (c *Context) Cookie(name string) (string, error) { + cookie, err := c.Request.Cookie(name) + if err != nil { + return "", err + } + val, _ := url.QueryUnescape(cookie.Value) + return val, nil +} + +func (c *Context) Render(code int, r render.Render) { + c.Status(code) + + if !bodyAllowedForStatus(code) { + r.WriteContentType(c.Writer) + c.Writer.WriteHeaderNow() + return + } + + if err := r.Render(c.Writer); err != nil { + panic(err) + } } // HTML renders the HTTP template specified by its file name. @@ -343,19 +725,41 @@ func (c *Context) HTML(code int, name string, obj interface{}) { // IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body. // It also sets the Content-Type as "application/json". -// WARNING: we recommend to use this only for development propuses since printing pretty JSON is +// WARNING: we recommend to use this only for development purposes since printing pretty JSON is // more CPU and bandwidth consuming. Use Context.JSON() instead. func (c *Context) IndentedJSON(code int, obj interface{}) { c.Render(code, render.IndentedJSON{Data: obj}) } +// SecureJSON serializes the given struct as Secure JSON into the response body. +// Default prepends "while(1)," to response body if the given struct is array values. +// It also sets the Content-Type as "application/json". +func (c *Context) SecureJSON(code int, obj interface{}) { + c.Render(code, render.SecureJSON{Prefix: c.engine.secureJsonPrefix, Data: obj}) +} + +// JSONP serializes the given struct as JSON into the response body. +// It add padding to response body to request data from a server residing in a different domain than the client. +// It also sets the Content-Type as "application/javascript". +func (c *Context) JSONP(code int, obj interface{}) { + callback := c.DefaultQuery("callback", "") + if callback == "" { + c.Render(code, render.JSON{Data: obj}) + } else { + c.Render(code, render.JsonpJSON{Callback: callback, Data: obj}) + } +} + // JSON serializes the given struct as JSON into the response body. // It also sets the Content-Type as "application/json". func (c *Context) JSON(code int, obj interface{}) { - c.writermem.WriteHeader(code) - if err := render.WriteJSON(c.Writer, obj); err != nil { - c.renderError(err) - } + c.Render(code, render.JSON{Data: obj}) +} + +// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string. +// It also sets the Content-Type as "application/json". +func (c *Context) AsciiJSON(code int, obj interface{}) { + c.Render(code, render.AsciiJSON{Data: obj}) } // XML serializes the given struct as XML into the response body. @@ -364,10 +768,14 @@ func (c *Context) XML(code int, obj interface{}) { c.Render(code, render.XML{Data: obj}) } +// YAML serializes the given struct as YAML into the response body. +func (c *Context) YAML(code int, obj interface{}) { + c.Render(code, render.YAML{Data: obj}) +} + // String writes the given string into the response body. func (c *Context) String(code int, format string, values ...interface{}) { - c.writermem.WriteHeader(code) - render.WriteString(c.Writer, format, values) + c.Render(code, render.String{Format: format, Data: values}) } // Redirect returns a HTTP redirect to the specific location. @@ -387,6 +795,16 @@ func (c *Context) Data(code int, contentType string, data []byte) { }) } +// DataFromReader writes the specified reader into the body stream and updates the HTTP code. +func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) { + c.Render(code, render.Reader{ + Headers: extraHeaders, + ContentType: contentType, + ContentLength: contentLength, + Reader: reader, + }) +} + // File writes the specified file into the body stream in a efficient way. func (c *Context) File(filepath string) { http.ServeFile(c.Writer, c.Request, filepath) @@ -408,9 +826,9 @@ func (c *Context) Stream(step func(w io.Writer) bool) { case <-clientGone: return default: - keepopen := step(w) + keepOpen := step(w) w.Flush() - if !keepopen { + if !keepOpen { return } } @@ -450,9 +868,8 @@ func (c *Context) Negotiate(code int, config Negotiate) { } func (c *Context) NegotiateFormat(offered ...string) string { - if len(offered) == 0 { - panic("you must provide at least one offer") - } + assert1(len(offered) > 0, "you must provide at least one offer") + if c.Accepted == nil { c.Accepted = parseAccept(c.requestHeader("Accept")) } @@ -477,18 +894,33 @@ func (c *Context) SetAccepted(formats ...string) { /***** GOLANG.ORG/X/NET/CONTEXT *****/ /************************************/ +// Deadline returns the time when work done on behalf of this context +// should be canceled. Deadline returns ok==false when no deadline is +// set. Successive calls to Deadline return the same results. func (c *Context) Deadline() (deadline time.Time, ok bool) { return } +// Done returns a channel that's closed when work done on behalf of this +// context should be canceled. Done may return nil if this context can +// never be canceled. Successive calls to Done return the same value. func (c *Context) Done() <-chan struct{} { return nil } +// Err returns a non-nil error value after Done is closed, +// successive calls to Err return the same error. +// If Done is not yet closed, Err returns nil. +// If Done is closed, Err returns a non-nil error explaining why: +// Canceled if the context was canceled +// or DeadlineExceeded if the context's deadline passed. func (c *Context) Err() error { return nil } +// Value returns the value associated with this context for key, or nil +// if no value is associated with key. Successive calls to Value with +// the same key returns the same result. func (c *Context) Value(key interface{}) interface{} { if key == 0 { return c.Request diff --git a/vendor/github.com/gin-gonic/gin/context_appengine.go b/vendor/github.com/gin-gonic/gin/context_appengine.go new file mode 100644 index 000000000..38c189a0b --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/context_appengine.go @@ -0,0 +1,11 @@ +// +build appengine + +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +func init() { + defaultAppEngine = true +} diff --git a/vendor/github.com/gin-gonic/gin/debug.go b/vendor/github.com/gin-gonic/gin/debug.go index bff86e100..f11156b3e 100644 --- a/vendor/github.com/gin-gonic/gin/debug.go +++ b/vendor/github.com/gin-gonic/gin/debug.go @@ -4,14 +4,18 @@ package gin -import "log" +import ( + "bytes" + "html/template" + "log" +) func init() { log.SetFlags(0) } // IsDebugging returns true if the framework is running in debug mode. -// Use SetMode(gin.Release) to switch to disable the debug mode. +// Use SetMode(gin.ReleaseMode) to disable debug mode. func IsDebugging() bool { return ginMode == debugCode } @@ -20,7 +24,19 @@ func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) { if IsDebugging() { nuHandlers := len(handlers) handlerName := nameOfFunction(handlers.Last()) - debugPrint("%-5s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers) + debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers) + } +} + +func debugPrintLoadTemplate(tmpl *template.Template) { + if IsDebugging() { + var buf bytes.Buffer + for _, tmpl := range tmpl.Templates() { + buf.WriteString("\t- ") + buf.WriteString(tmpl.Name()) + buf.WriteString("\n") + } + debugPrint("Loaded HTML Templates (%d): \n%s\n", len(tmpl.Templates()), buf.String()) } } @@ -30,6 +46,15 @@ func debugPrint(format string, values ...interface{}) { } } +func debugPrintWARNINGDefault() { + debugPrint(`[WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon. + +`) + debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. + +`) +} + func debugPrintWARNINGNew() { debugPrint(`[WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release diff --git a/vendor/github.com/gin-gonic/gin/deprecated.go b/vendor/github.com/gin-gonic/gin/deprecated.go index b2e874f01..ab4474296 100644 --- a/vendor/github.com/gin-gonic/gin/deprecated.go +++ b/vendor/github.com/gin-gonic/gin/deprecated.go @@ -3,3 +3,19 @@ // license that can be found in the LICENSE file. package gin + +import ( + "log" + + "github.com/gin-gonic/gin/binding" +) + +// BindWith binds the passed struct pointer using the specified binding engine. +// See the binding package. +func (c *Context) BindWith(obj interface{}, b binding.Binding) error { + log.Println(`BindWith(\"interface{}, binding.Binding\") error is going to + be deprecated, please check issue #662 and either use MustBindWith() if you + want HTTP 400 to be automatically returned if any error occur, or use + ShouldBindWith() if you need to manage the error.`) + return c.MustBindWith(obj, b) +} diff --git a/vendor/github.com/gin-gonic/gin/doc.go b/vendor/github.com/gin-gonic/gin/doc.go new file mode 100644 index 000000000..01ac4a907 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/doc.go @@ -0,0 +1,6 @@ +/* +Package gin implements a HTTP web framework called gin. + +See https://gin-gonic.github.io/gin/ for more information about gin. +*/ +package gin // import "github.com/gin-gonic/gin" diff --git a/vendor/github.com/gin-gonic/gin/errors.go b/vendor/github.com/gin-gonic/gin/errors.go index e829c886b..dbfccd856 100644 --- a/vendor/github.com/gin-gonic/gin/errors.go +++ b/vendor/github.com/gin-gonic/gin/errors.go @@ -6,9 +6,10 @@ package gin import ( "bytes" - "encoding/json" "fmt" "reflect" + + "github.com/gin-gonic/gin/json" ) type ErrorType uint64 @@ -23,15 +24,13 @@ const ( ErrorTypeNu = 2 ) -type ( - Error struct { - Err error - Type ErrorType - Meta interface{} - } +type Error struct { + Err error + Type ErrorType + Meta interface{} +} - errorMsgs []*Error -) +type errorMsgs []*Error var _ error = &Error{} @@ -66,13 +65,13 @@ func (msg *Error) JSON() interface{} { return json } -// Implements the json.Marshaller interface +// MarshalJSON implements the json.Marshaller interface. func (msg *Error) MarshalJSON() ([]byte, error) { return json.Marshal(msg.JSON()) } -// Implements the error interface -func (msg *Error) Error() string { +// Error implements the error interface +func (msg Error) Error() string { return msg.Err.Error() } @@ -80,8 +79,8 @@ func (msg *Error) IsType(flags ErrorType) bool { return (msg.Type & flags) > 0 } -// Returns a readonly copy filterd the byte. -// ie ByType(gin.ErrorTypePublic) returns a slice of errors with type=ErrorTypePublic +// ByType returns a readonly copy filtered the byte. +// ie ByType(gin.ErrorTypePublic) returns a slice of errors with type=ErrorTypePublic. func (a errorMsgs) ByType(typ ErrorType) errorMsgs { if len(a) == 0 { return nil @@ -89,7 +88,7 @@ func (a errorMsgs) ByType(typ ErrorType) errorMsgs { if typ == ErrorTypeAny { return a } - var result errorMsgs = nil + var result errorMsgs for _, msg := range a { if msg.IsType(typ) { result = append(result, msg) @@ -98,24 +97,21 @@ func (a errorMsgs) ByType(typ ErrorType) errorMsgs { return result } -// Returns the last error in the slice. It returns nil if the array is empty. -// Shortcut for errors[len(errors)-1] +// Last returns the last error in the slice. It returns nil if the array is empty. +// Shortcut for errors[len(errors)-1]. func (a errorMsgs) Last() *Error { - length := len(a) - if length > 0 { + if length := len(a); length > 0 { return a[length-1] } return nil } -// Returns an array will all the error messages. -// Example -// ``` -// c.Error(errors.New("first")) -// c.Error(errors.New("second")) -// c.Error(errors.New("third")) -// c.Errors.Errors() // == []string{"first", "second", "third"} -// `` +// Errors returns an array will all the error messages. +// Example: +// c.Error(errors.New("first")) +// c.Error(errors.New("second")) +// c.Error(errors.New("third")) +// c.Errors.Errors() // == []string{"first", "second", "third"} func (a errorMsgs) Errors() []string { if len(a) == 0 { return nil @@ -152,7 +148,7 @@ func (a errorMsgs) String() string { } var buffer bytes.Buffer for i, msg := range a { - fmt.Fprintf(&buffer, "Error #%02d: %s\n", (i + 1), msg.Err) + fmt.Fprintf(&buffer, "Error #%02d: %s\n", i+1, msg.Err) if msg.Meta != nil { fmt.Fprintf(&buffer, " Meta: %v\n", msg.Meta) } diff --git a/vendor/github.com/gin-gonic/gin/fs.go b/vendor/github.com/gin-gonic/gin/fs.go index 6af3ded55..7a6738a68 100644 --- a/vendor/github.com/gin-gonic/gin/fs.go +++ b/vendor/github.com/gin-gonic/gin/fs.go @@ -1,3 +1,7 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + package gin import ( @@ -5,16 +9,15 @@ import ( "os" ) -type ( - onlyfilesFS struct { - fs http.FileSystem - } - neuteredReaddirFile struct { - http.File - } -) +type onlyfilesFS struct { + fs http.FileSystem +} + +type neuteredReaddirFile struct { + http.File +} -// Dir returns a http.Filesystem that can be used by http.FileServer(). It is used interally +// Dir returns a http.Filesystem that can be used by http.FileServer(). It is used internally // in router.Static(). // if listDirectory == true, then it works the same as http.Dir() otherwise it returns // a filesystem that prevents http.FileServer() to list the directory files. @@ -26,7 +29,7 @@ func Dir(root string, listDirectory bool) http.FileSystem { return &onlyfilesFS{fs} } -// Conforms to http.Filesystem +// Open conforms to http.Filesystem. func (fs onlyfilesFS) Open(name string) (http.File, error) { f, err := fs.fs.Open(name) if err != nil { @@ -35,7 +38,7 @@ func (fs onlyfilesFS) Open(name string) (http.File, error) { return neuteredReaddirFile{f}, nil } -// Overrides the http.File default implementation +// Readdir overrides the http.File default implementation. func (f neuteredReaddirFile) Readdir(count int) ([]os.FileInfo, error) { // this disables directory listing return nil, nil diff --git a/vendor/github.com/gin-gonic/gin/gin.go b/vendor/github.com/gin-gonic/gin/gin.go index 54b4e59f4..aa62e014f 100644 --- a/vendor/github.com/gin-gonic/gin/gin.go +++ b/vendor/github.com/gin-gonic/gin/gin.go @@ -14,72 +14,96 @@ import ( "github.com/gin-gonic/gin/render" ) -// Framework's version -const Version = "v1.0rc2" +const ( + // Version is Framework's version. + Version = "v1.3.0" + defaultMultipartMemory = 32 << 20 // 32 MB +) -var default404Body = []byte("404 page not found") -var default405Body = []byte("405 method not allowed") +var ( + default404Body = []byte("404 page not found") + default405Body = []byte("405 method not allowed") + defaultAppEngine bool +) type HandlerFunc func(*Context) type HandlersChain []HandlerFunc // Last returns the last handler in the chain. ie. the last handler is the main own. func (c HandlersChain) Last() HandlerFunc { - length := len(c) - if length > 0 { + if length := len(c); length > 0 { return c[length-1] } return nil } -type ( - RoutesInfo []RouteInfo - RouteInfo struct { - Method string - Path string - Handler string - } +type RouteInfo struct { + Method string + Path string + Handler string +} - // Engine is the framework's instance, it contains the muxer, middlewares and configuration settings. - // Create an instance of Engine, by using New() or Default() - Engine struct { - RouterGroup - HTMLRender render.HTMLRender - allNoRoute HandlersChain - allNoMethod HandlersChain - noRoute HandlersChain - noMethod HandlersChain - pool sync.Pool - trees methodTrees - - // Enables automatic redirection if the current route can't be matched but a - // handler for the path with (without) the trailing slash exists. - // For example if /foo/ is requested but a route only exists for /foo, the - // client is redirected to /foo with http status code 301 for GET requests - // and 307 for all other request methods. - RedirectTrailingSlash bool - - // If enabled, the router tries to fix the current request path, if no - // handle is registered for it. - // First superfluous path elements like ../ or // are removed. - // Afterwards the router does a case-insensitive lookup of the cleaned path. - // If a handle can be found for this route, the router makes a redirection - // to the corrected path with status code 301 for GET requests and 307 for - // all other request methods. - // For example /FOO and /..//Foo could be redirected to /foo. - // RedirectTrailingSlash is independent of this option. - RedirectFixedPath bool - - // If enabled, the router checks if another method is allowed for the - // current route, if the current request can not be routed. - // If this is the case, the request is answered with 'Method Not Allowed' - // and HTTP status code 405. - // If no other Method is allowed, the request is delegated to the NotFound - // handler. - HandleMethodNotAllowed bool - ForwardedByClientIP bool - } -) +type RoutesInfo []RouteInfo + +// Engine is the framework's instance, it contains the muxer, middleware and configuration settings. +// Create an instance of Engine, by using New() or Default() +type Engine struct { + RouterGroup + + // Enables automatic redirection if the current route can't be matched but a + // handler for the path with (without) the trailing slash exists. + // For example if /foo/ is requested but a route only exists for /foo, the + // client is redirected to /foo with http status code 301 for GET requests + // and 307 for all other request methods. + RedirectTrailingSlash bool + + // If enabled, the router tries to fix the current request path, if no + // handle is registered for it. + // First superfluous path elements like ../ or // are removed. + // Afterwards the router does a case-insensitive lookup of the cleaned path. + // If a handle can be found for this route, the router makes a redirection + // to the corrected path with status code 301 for GET requests and 307 for + // all other request methods. + // For example /FOO and /..//Foo could be redirected to /foo. + // RedirectTrailingSlash is independent of this option. + RedirectFixedPath bool + + // If enabled, the router checks if another method is allowed for the + // current route, if the current request can not be routed. + // If this is the case, the request is answered with 'Method Not Allowed' + // and HTTP status code 405. + // If no other Method is allowed, the request is delegated to the NotFound + // handler. + HandleMethodNotAllowed bool + ForwardedByClientIP bool + + // #726 #755 If enabled, it will thrust some headers starting with + // 'X-AppEngine...' for better integration with that PaaS. + AppEngine bool + + // If enabled, the url.RawPath will be used to find parameters. + UseRawPath bool + + // If true, the path value will be unescaped. + // If UseRawPath is false (by default), the UnescapePathValues effectively is true, + // as url.Path gonna be used, which is already unescaped. + UnescapePathValues bool + + // Value of 'maxMemory' param that is given to http.Request's ParseMultipartForm + // method call. + MaxMultipartMemory int64 + + delims render.Delims + secureJsonPrefix string + HTMLRender render.HTMLRender + FuncMap template.FuncMap + allNoRoute HandlersChain + allNoMethod HandlersChain + noRoute HandlersChain + noMethod HandlersChain + pool sync.Pool + trees methodTrees +} var _ IRouter = &Engine{} @@ -89,6 +113,8 @@ var _ IRouter = &Engine{} // - RedirectFixedPath: false // - HandleMethodNotAllowed: false // - ForwardedByClientIP: true +// - UseRawPath: false +// - UnescapePathValues: true func New() *Engine { debugPrintWARNINGNew() engine := &Engine{ @@ -97,11 +123,18 @@ func New() *Engine { basePath: "/", root: true, }, + FuncMap: template.FuncMap{}, RedirectTrailingSlash: true, RedirectFixedPath: false, HandleMethodNotAllowed: false, ForwardedByClientIP: true, + AppEngine: defaultAppEngine, + UseRawPath: false, + UnescapePathValues: true, + MaxMultipartMemory: defaultMultipartMemory, trees: make(methodTrees, 0, 9), + delims: render.Delims{Left: "{{", Right: "}}"}, + secureJsonPrefix: "while(1);", } engine.RouterGroup.engine = engine engine.pool.New = func() interface{} { @@ -112,8 +145,9 @@ func New() *Engine { // Default returns an Engine instance with the Logger and Recovery middleware already attached. func Default() *Engine { + debugPrintWARNINGDefault() engine := New() - engine.Use(Recovery(), Logger()) + engine.Use(Logger(), Recovery()) return engine } @@ -121,48 +155,76 @@ func (engine *Engine) allocateContext() *Context { return &Context{engine: engine} } +func (engine *Engine) Delims(left, right string) *Engine { + engine.delims = render.Delims{Left: left, Right: right} + return engine +} + +// SecureJsonPrefix sets the secureJsonPrefix used in Context.SecureJSON. +func (engine *Engine) SecureJsonPrefix(prefix string) *Engine { + engine.secureJsonPrefix = prefix + return engine +} + +// LoadHTMLGlob loads HTML files identified by glob pattern +// and associates the result with HTML renderer. func (engine *Engine) LoadHTMLGlob(pattern string) { + left := engine.delims.Left + right := engine.delims.Right + templ := template.Must(template.New("").Delims(left, right).Funcs(engine.FuncMap).ParseGlob(pattern)) + if IsDebugging() { - engine.HTMLRender = render.HTMLDebug{Glob: pattern} - } else { - templ := template.Must(template.ParseGlob(pattern)) - engine.SetHTMLTemplate(templ) + debugPrintLoadTemplate(templ) + engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims} + return } + + engine.SetHTMLTemplate(templ) } +// LoadHTMLFiles loads a slice of HTML files +// and associates the result with HTML renderer. func (engine *Engine) LoadHTMLFiles(files ...string) { if IsDebugging() { - engine.HTMLRender = render.HTMLDebug{Files: files} - } else { - templ := template.Must(template.ParseFiles(files...)) - engine.SetHTMLTemplate(templ) + engine.HTMLRender = render.HTMLDebug{Files: files, FuncMap: engine.FuncMap, Delims: engine.delims} + return } + + templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseFiles(files...)) + engine.SetHTMLTemplate(templ) } +// SetHTMLTemplate associate a template with HTML renderer. func (engine *Engine) SetHTMLTemplate(templ *template.Template) { if len(engine.trees) > 0 { debugPrintWARNINGSetHTMLTemplate() } - engine.HTMLRender = render.HTMLProduction{Template: templ} + + engine.HTMLRender = render.HTMLProduction{Template: templ.Funcs(engine.FuncMap)} } -// Adds handlers for NoRoute. It return a 404 code by default. +// SetFuncMap sets the FuncMap used for template.FuncMap. +func (engine *Engine) SetFuncMap(funcMap template.FuncMap) { + engine.FuncMap = funcMap +} + +// NoRoute adds handlers for NoRoute. It return a 404 code by default. func (engine *Engine) NoRoute(handlers ...HandlerFunc) { engine.noRoute = handlers engine.rebuild404Handlers() } -// Sets the handlers called when... TODO +// NoMethod sets the handlers called when... TODO. func (engine *Engine) NoMethod(handlers ...HandlerFunc) { engine.noMethod = handlers engine.rebuild405Handlers() } -// Attachs a global middleware to the router. ie. the middlewares attached though Use() will be +// Use attachs a global middleware to the router. ie. the middleware attached though Use() will be // included in the handlers chain for every single request. Even 404, 405, static files... // For example, this is the right place for a logger or error management middleware. -func (engine *Engine) Use(middlewares ...HandlerFunc) IRoutes { - engine.RouterGroup.Use(middlewares...) +func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes { + engine.RouterGroup.Use(middleware...) engine.rebuild404Handlers() engine.rebuild405Handlers() return engine @@ -177,25 +239,15 @@ func (engine *Engine) rebuild405Handlers() { } func (engine *Engine) addRoute(method, path string, handlers HandlersChain) { - debugPrintRoute(method, path, handlers) - - if path[0] != '/' { - panic("path must begin with '/'") - } - if method == "" { - panic("HTTP method can not be empty") - } - if len(handlers) == 0 { - panic("there must be at least one handler") - } + assert1(path[0] == '/', "path must begin with '/'") + assert1(method != "", "HTTP method can not be empty") + assert1(len(handlers) > 0, "there must be at least one handler") + debugPrintRoute(method, path, handlers) root := engine.trees.get(method) if root == nil { root = new(node) - engine.trees = append(engine.trees, methodTree{ - method: method, - root: root, - }) + engine.trees = append(engine.trees, methodTree{method: method, root: root}) } root.addRoute(path, handlers) } @@ -226,19 +278,20 @@ func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo { // Run attaches the router to a http.Server and starts listening and serving HTTP requests. // It is a shortcut for http.ListenAndServe(addr, router) -// Note: this method will block the calling goroutine undefinitelly unless an error happens. -func (engine *Engine) Run(addr string) (err error) { - debugPrint("Listening and serving HTTP on %s\n", addr) +// Note: this method will block the calling goroutine indefinitely unless an error happens. +func (engine *Engine) Run(addr ...string) (err error) { defer func() { debugPrintError(err) }() - err = http.ListenAndServe(addr, engine) + address := resolveAddress(addr) + debugPrint("Listening and serving HTTP on %s\n", address) + err = http.ListenAndServe(address, engine) return } // RunTLS attaches the router to a http.Server and starts listening and serving HTTPS (secure) requests. // It is a shortcut for http.ListenAndServeTLS(addr, certFile, keyFile, router) -// Note: this method will block the calling goroutine undefinitelly unless an error happens. -func (engine *Engine) RunTLS(addr string, certFile string, keyFile string) (err error) { +// Note: this method will block the calling goroutine indefinitely unless an error happens. +func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) { debugPrint("Listening and serving HTTPS on %s\n", addr) defer func() { debugPrintError(err) }() @@ -248,7 +301,7 @@ func (engine *Engine) RunTLS(addr string, certFile string, keyFile string) (err // RunUnix attaches the router to a http.Server and starts listening and serving HTTP requests // through the specified unix socket (ie. a file). -// Note: this method will block the calling goroutine undefinitelly unless an error happens. +// Note: this method will block the calling goroutine indefinitely unless an error happens. func (engine *Engine) RunUnix(file string) (err error) { debugPrint("Listening and serving HTTP on unix:/%s", file) defer func() { debugPrintError(err) }() @@ -263,7 +316,7 @@ func (engine *Engine) RunUnix(file string) (err error) { return } -// Conforms to the http.Handler interface. +// ServeHTTP conforms to the http.Handler interface. func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { c := engine.pool.Get().(*Context) c.writermem.reset(w) @@ -275,51 +328,66 @@ func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { engine.pool.Put(c) } -func (engine *Engine) handleHTTPRequest(context *Context) { - httpMethod := context.Request.Method - path := context.Request.URL.Path +// HandleContext re-enter a context that has been rewritten. +// This can be done by setting c.Request.URL.Path to your new target. +// Disclaimer: You can loop yourself to death with this, use wisely. +func (engine *Engine) HandleContext(c *Context) { + c.reset() + engine.handleHTTPRequest(c) + engine.pool.Put(c) +} + +func (engine *Engine) handleHTTPRequest(c *Context) { + httpMethod := c.Request.Method + path := c.Request.URL.Path + unescape := false + if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 { + path = c.Request.URL.RawPath + unescape = engine.UnescapePathValues + } // Find root of the tree for the given HTTP method t := engine.trees for i, tl := 0, len(t); i < tl; i++ { - if t[i].method == httpMethod { - root := t[i].root - // Find route in tree - handlers, params, tsr := root.getValue(path, context.Params) - if handlers != nil { - context.handlers = handlers - context.Params = params - context.Next() - context.writermem.WriteHeaderNow() + if t[i].method != httpMethod { + continue + } + root := t[i].root + // Find route in tree + handlers, params, tsr := root.getValue(path, c.Params, unescape) + if handlers != nil { + c.handlers = handlers + c.Params = params + c.Next() + c.writermem.WriteHeaderNow() + return + } + if httpMethod != "CONNECT" && path != "/" { + if tsr && engine.RedirectTrailingSlash { + redirectTrailingSlash(c) + return + } + if engine.RedirectFixedPath && redirectFixedPath(c, root, engine.RedirectFixedPath) { return - - } else if httpMethod != "CONNECT" && path != "/" { - if tsr && engine.RedirectTrailingSlash { - redirectTrailingSlash(context) - return - } - if engine.RedirectFixedPath && redirectFixedPath(context, root, engine.RedirectFixedPath) { - return - } } - break } + break } - // TODO: unit test if engine.HandleMethodNotAllowed { for _, tree := range engine.trees { - if tree.method != httpMethod { - if handlers, _, _ := tree.root.getValue(path, nil); handlers != nil { - context.handlers = engine.allNoMethod - serveError(context, 405, default405Body) - return - } + if tree.method == httpMethod { + continue + } + if handlers, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil { + c.handlers = engine.allNoMethod + serveError(c, http.StatusMethodNotAllowed, default405Body) + return } } } - context.handlers = engine.allNoRoute - serveError(context, 404, default404Body) + c.handlers = engine.allNoRoute + serveError(c, http.StatusNotFound, default404Body) } var mimePlain = []string{MIMEPlain} @@ -327,28 +395,29 @@ var mimePlain = []string{MIMEPlain} func serveError(c *Context, code int, defaultMessage []byte) { c.writermem.status = code c.Next() - if !c.writermem.Written() { - if c.writermem.Status() == code { - c.writermem.Header()["Content-Type"] = mimePlain - c.Writer.Write(defaultMessage) - } else { - c.writermem.WriteHeaderNow() - } + if c.writermem.Written() { + return + } + if c.writermem.Status() == code { + c.writermem.Header()["Content-Type"] = mimePlain + c.Writer.Write(defaultMessage) + return } + c.writermem.WriteHeaderNow() + return } func redirectTrailingSlash(c *Context) { req := c.Request path := req.URL.Path - code := 301 // Permanent redirect, request with GET method + code := http.StatusMovedPermanently // Permanent redirect, request with GET method if req.Method != "GET" { - code = 307 + code = http.StatusTemporaryRedirect } - if len(path) > 1 && path[len(path)-1] == '/' { - req.URL.Path = path[:len(path)-1] - } else { - req.URL.Path = path + "/" + req.URL.Path = path + "/" + if length := len(path); length > 1 && path[length-1] == '/' { + req.URL.Path = path[:length-1] } debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String()) http.Redirect(c.Writer, req, req.URL.String(), code) @@ -359,14 +428,10 @@ func redirectFixedPath(c *Context, root *node, trailingSlash bool) bool { req := c.Request path := req.URL.Path - fixedPath, found := root.findCaseInsensitivePath( - cleanPath(path), - trailingSlash, - ) - if found { - code := 301 // Permanent redirect, request with GET method + if fixedPath, ok := root.findCaseInsensitivePath(cleanPath(path), trailingSlash); ok { + code := http.StatusMovedPermanently // Permanent redirect, request with GET method if req.Method != "GET" { - code = 307 + code = http.StatusTemporaryRedirect } req.URL.Path = string(fixedPath) debugPrint("redirecting request %d: %s --> %s", code, path, req.URL.String()) diff --git a/vendor/github.com/gin-gonic/gin/json/json.go b/vendor/github.com/gin-gonic/gin/json/json.go new file mode 100644 index 000000000..aa76aa309 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/json/json.go @@ -0,0 +1,15 @@ +// Copyright 2017 Bo-Yi Wu. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +// +build !jsoniter + +package json + +import "encoding/json" + +var ( + Marshal = json.Marshal + MarshalIndent = json.MarshalIndent + NewDecoder = json.NewDecoder +) diff --git a/vendor/github.com/gin-gonic/gin/json/jsoniter.go b/vendor/github.com/gin-gonic/gin/json/jsoniter.go new file mode 100644 index 000000000..ffe1424ac --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/json/jsoniter.go @@ -0,0 +1,16 @@ +// Copyright 2017 Bo-Yi Wu. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +// +build jsoniter + +package json + +import "github.com/json-iterator/go" + +var ( + json = jsoniter.ConfigCompatibleWithStandardLibrary + Marshal = json.Marshal + MarshalIndent = json.MarshalIndent + NewDecoder = json.NewDecoder +) diff --git a/vendor/github.com/gin-gonic/gin/logger.go b/vendor/github.com/gin-gonic/gin/logger.go index e0f9b3673..1a8df6010 100644 --- a/vendor/github.com/gin-gonic/gin/logger.go +++ b/vendor/github.com/gin-gonic/gin/logger.go @@ -7,84 +7,123 @@ package gin import ( "fmt" "io" + "net/http" + "os" "time" + + "github.com/mattn/go-isatty" ) var ( - green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109}) - white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109}) - yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109}) - red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109}) - blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109}) - magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109}) - cyan = string([]byte{27, 91, 57, 55, 59, 52, 54, 109}) - reset = string([]byte{27, 91, 48, 109}) + green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109}) + white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109}) + yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109}) + red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109}) + blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109}) + magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109}) + cyan = string([]byte{27, 91, 57, 55, 59, 52, 54, 109}) + reset = string([]byte{27, 91, 48, 109}) + disableColor = false ) +// DisableConsoleColor disables color output in the console. +func DisableConsoleColor() { + disableColor = true +} + +// ErrorLogger returns a handlerfunc for any error type. func ErrorLogger() HandlerFunc { return ErrorLoggerT(ErrorTypeAny) } +// ErrorLoggerT returns a handlerfunc for a given error type. func ErrorLoggerT(typ ErrorType) HandlerFunc { return func(c *Context) { c.Next() - // avoid writting if we already wrote into the response body - if !c.Writer.Written() { - errors := c.Errors.ByType(typ) - if len(errors) > 0 { - c.JSON(-1, errors) - } + errors := c.Errors.ByType(typ) + if len(errors) > 0 { + c.JSON(-1, errors) } } } -// Instances a Logger middleware that will write the logs to gin.DefaultWriter -// By default gin.DefaultWriter = os.Stdout +// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter. +// By default gin.DefaultWriter = os.Stdout. func Logger() HandlerFunc { return LoggerWithWriter(DefaultWriter) } -// Instance a Logger middleware with the specified writter buffer. +// LoggerWithWriter instance a Logger middleware with the specified writter buffer. // Example: os.Stdout, a file opened in write mode, a socket... -func LoggerWithWriter(out io.Writer) HandlerFunc { +func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc { + isTerm := true + + if w, ok := out.(*os.File); !ok || + (os.Getenv("TERM") == "dumb" || (!isatty.IsTerminal(w.Fd()) && !isatty.IsCygwinTerminal(w.Fd()))) || + disableColor { + isTerm = false + } + + var skip map[string]struct{} + + if length := len(notlogged); length > 0 { + skip = make(map[string]struct{}, length) + + for _, path := range notlogged { + skip[path] = struct{}{} + } + } + return func(c *Context) { // Start timer start := time.Now() path := c.Request.URL.Path + raw := c.Request.URL.RawQuery // Process request c.Next() - // Stop timer - end := time.Now() - latency := end.Sub(start) - - clientIP := c.ClientIP() - method := c.Request.Method - statusCode := c.Writer.Status() - statusColor := colorForStatus(statusCode) - methodColor := colorForMethod(method) - comment := c.Errors.ByType(ErrorTypePrivate).String() - - fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %s |%s %s %-7s %s\n%s", - end.Format("2006/01/02 - 15:04:05"), - statusColor, statusCode, reset, - latency, - clientIP, - methodColor, reset, method, - path, - comment, - ) + // Log only when path is not being skipped + if _, ok := skip[path]; !ok { + // Stop timer + end := time.Now() + latency := end.Sub(start) + + clientIP := c.ClientIP() + method := c.Request.Method + statusCode := c.Writer.Status() + var statusColor, methodColor, resetColor string + if isTerm { + statusColor = colorForStatus(statusCode) + methodColor = colorForMethod(method) + resetColor = reset + } + comment := c.Errors.ByType(ErrorTypePrivate).String() + + if raw != "" { + path = path + "?" + raw + } + + fmt.Fprintf(out, "[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s", + end.Format("2006/01/02 - 15:04:05"), + statusColor, statusCode, resetColor, + latency, + clientIP, + methodColor, method, resetColor, + path, + comment, + ) + } } } func colorForStatus(code int) string { switch { - case code >= 200 && code < 300: + case code >= http.StatusOK && code < http.StatusMultipleChoices: return green - case code >= 300 && code < 400: + case code >= http.StatusMultipleChoices && code < http.StatusBadRequest: return white - case code >= 400 && code < 500: + case code >= http.StatusBadRequest && code < http.StatusInternalServerError: return yellow default: return red diff --git a/vendor/github.com/gin-gonic/gin/mode.go b/vendor/github.com/gin-gonic/gin/mode.go index 15efaeb87..9df4e45fa 100644 --- a/vendor/github.com/gin-gonic/gin/mode.go +++ b/vendor/github.com/gin-gonic/gin/mode.go @@ -9,38 +9,42 @@ import ( "os" "github.com/gin-gonic/gin/binding" - "github.com/mattn/go-colorable" ) const ENV_GIN_MODE = "GIN_MODE" const ( - DebugMode string = "debug" - ReleaseMode string = "release" - TestMode string = "test" + DebugMode = "debug" + ReleaseMode = "release" + TestMode = "test" ) const ( - debugCode = iota - releaseCode = iota - testCode = iota + debugCode = iota + releaseCode + testCode ) -var DefaultWriter io.Writer = colorable.NewColorableStdout() -var ginMode int = debugCode -var modeName string = DebugMode +// DefaultWriter is the default io.Writer used the Gin for debug output and +// middleware output like Logger() or Recovery(). +// Note that both Logger and Recovery provides custom ways to configure their +// output io.Writer. +// To support coloring in Windows use: +// import "github.com/mattn/go-colorable" +// gin.DefaultWriter = colorable.NewColorableStdout() +var DefaultWriter io.Writer = os.Stdout +var DefaultErrorWriter io.Writer = os.Stderr + +var ginMode = debugCode +var modeName = DebugMode func init() { mode := os.Getenv(ENV_GIN_MODE) - if len(mode) == 0 { - SetMode(DebugMode) - } else { - SetMode(mode) - } + SetMode(mode) } func SetMode(value string) { switch value { - case DebugMode: + case DebugMode, "": ginMode = debugCode case ReleaseMode: ginMode = releaseCode @@ -49,6 +53,9 @@ func SetMode(value string) { default: panic("gin mode unknown: " + value) } + if value == "" { + value = DebugMode + } modeName = value } @@ -56,6 +63,10 @@ func DisableBindValidation() { binding.Validator = nil } +func EnableJsonDecoderUseNumber() { + binding.EnableDecoderUseNumber = true +} + func Mode() string { return modeName } diff --git a/vendor/github.com/gin-gonic/gin/path.go b/vendor/github.com/gin-gonic/gin/path.go index 43cdd0472..d1f596228 100644 --- a/vendor/github.com/gin-gonic/gin/path.go +++ b/vendor/github.com/gin-gonic/gin/path.go @@ -1,11 +1,11 @@ // Copyright 2013 Julien Schmidt. All rights reserved. // Based on the path package, Copyright 2009 The Go Authors. // Use of this source code is governed by a BSD-style license that can be found -// in the LICENSE file. +// at https://github.com/julienschmidt/httprouter/blob/master/LICENSE. package gin -// CleanPath is the URL version of path.Clean, it returns a canonical URL path +// cleanPath is the URL version of path.Clean, it returns a canonical URL path // for p, eliminating . and .. elements. // // The following rules are applied iteratively until no further processing can @@ -17,7 +17,7 @@ package gin // 4. Eliminate .. elements that begin a rooted path: // that is, replace "/.." by "/" at the beginning of a path. // -// If the result of this process is an empty string, "/" is returned +// If the result of this process is an empty string, "/" is returned. func cleanPath(p string) string { // Turn empty string into "/" if p == "" { @@ -41,7 +41,7 @@ func cleanPath(p string) string { buf[0] = '/' } - trailing := n > 2 && p[n-1] == '/' + trailing := n > 1 && p[n-1] == '/' // A bit more clunky without a 'lazybuf' like the path package, but the loop // gets completely inlined (bufApp). So in contrast to the path package this @@ -59,11 +59,11 @@ func cleanPath(p string) string { case p[r] == '.' && p[r+1] == '/': // . element - r++ + r += 2 case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'): // .. element: remove to last / - r += 2 + r += 3 if w > 1 { // can backtrack @@ -109,7 +109,7 @@ func cleanPath(p string) string { return string(buf[:w]) } -// internal helper to lazily create a buffer if necessary +// internal helper to lazily create a buffer if necessary. func bufApp(buf *[]byte, s string, w int, c byte) { if *buf == nil { if s[w] == c { diff --git a/vendor/github.com/gin-gonic/gin/recovery.go b/vendor/github.com/gin-gonic/gin/recovery.go index e296e3390..61c5bd531 100644 --- a/vendor/github.com/gin-gonic/gin/recovery.go +++ b/vendor/github.com/gin-gonic/gin/recovery.go @@ -10,7 +10,10 @@ import ( "io" "io/ioutil" "log" + "net/http" + "net/http/httputil" "runtime" + "time" ) var ( @@ -22,29 +25,31 @@ var ( // Recovery returns a middleware that recovers from any panics and writes a 500 if there was one. func Recovery() HandlerFunc { - return RecoveryWithWriter(DefaultWriter) + return RecoveryWithWriter(DefaultErrorWriter) } +// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one. func RecoveryWithWriter(out io.Writer) HandlerFunc { var logger *log.Logger if out != nil { - logger = log.New(out, "", log.LstdFlags) + logger = log.New(out, "\n\n\x1b[31m", log.LstdFlags) } return func(c *Context) { defer func() { if err := recover(); err != nil { if logger != nil { stack := stack(3) - logger.Printf("Panic recovery -> %s\n%s\n", err, stack) + httprequest, _ := httputil.DumpRequest(c.Request, false) + logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s", timeFormat(time.Now()), string(httprequest), err, stack, reset) } - c.AbortWithStatus(500) + c.AbortWithStatus(http.StatusInternalServerError) } }() c.Next() } } -// stack returns a nicely formated stack frame, skipping skip frames +// stack returns a nicely formatted stack frame, skipping skip frames. func stack(skip int) []byte { buf := new(bytes.Buffer) // the returned data // As we loop, we open files and read them. These variables record the currently @@ -104,3 +109,8 @@ func function(pc uintptr) []byte { name = bytes.Replace(name, centerDot, dot, -1) return name } + +func timeFormat(t time.Time) string { + var timeString = t.Format("2006/01/02 - 15:04:05") + return timeString +} diff --git a/vendor/github.com/gin-gonic/gin/render/data.go b/vendor/github.com/gin-gonic/gin/render/data.go index efa75d559..331949139 100644 --- a/vendor/github.com/gin-gonic/gin/render/data.go +++ b/vendor/github.com/gin-gonic/gin/render/data.go @@ -11,10 +11,13 @@ type Data struct { Data []byte } -func (r Data) Render(w http.ResponseWriter) error { - if len(r.ContentType) > 0 { - w.Header()["Content-Type"] = []string{r.ContentType} - } - w.Write(r.Data) - return nil +// Render (Data) writes data with custom ContentType. +func (r Data) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + _, err = w.Write(r.Data) + return +} + +func (r Data) WriteContentType(w http.ResponseWriter) { + writeContentType(w, []string{r.ContentType}) } diff --git a/vendor/github.com/gin-gonic/gin/render/html.go b/vendor/github.com/gin-gonic/gin/render/html.go index 01f6bf220..1e3be65b9 100644 --- a/vendor/github.com/gin-gonic/gin/render/html.go +++ b/vendor/github.com/gin-gonic/gin/render/html.go @@ -9,26 +9,32 @@ import ( "net/http" ) -type ( - HTMLRender interface { - Instance(string, interface{}) Render - } +type Delims struct { + Left string + Right string +} - HTMLProduction struct { - Template *template.Template - } +type HTMLRender interface { + Instance(string, interface{}) Render +} - HTMLDebug struct { - Files []string - Glob string - } +type HTMLProduction struct { + Template *template.Template + Delims Delims +} - HTML struct { - Template *template.Template - Name string - Data interface{} - } -) +type HTMLDebug struct { + Files []string + Glob string + Delims Delims + FuncMap template.FuncMap +} + +type HTML struct { + Template *template.Template + Name string + Data interface{} +} var htmlContentType = []string{"text/html; charset=utf-8"} @@ -48,20 +54,27 @@ func (r HTMLDebug) Instance(name string, data interface{}) Render { } } func (r HTMLDebug) loadTemplate() *template.Template { + if r.FuncMap == nil { + r.FuncMap = template.FuncMap{} + } if len(r.Files) > 0 { - return template.Must(template.ParseFiles(r.Files...)) + return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseFiles(r.Files...)) } - if len(r.Glob) > 0 { - return template.Must(template.ParseGlob(r.Glob)) + if r.Glob != "" { + return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseGlob(r.Glob)) } panic("the HTML debug render was created without files or glob pattern") } func (r HTML) Render(w http.ResponseWriter) error { - writeContentType(w, htmlContentType) - if len(r.Name) == 0 { + r.WriteContentType(w) + + if r.Name == "" { return r.Template.Execute(w, r.Data) - } else { - return r.Template.ExecuteTemplate(w, r.Name, r.Data) } + return r.Template.ExecuteTemplate(w, r.Name, r.Data) +} + +func (r HTML) WriteContentType(w http.ResponseWriter) { + writeContentType(w, htmlContentType) } diff --git a/vendor/github.com/gin-gonic/gin/render/json.go b/vendor/github.com/gin-gonic/gin/render/json.go old mode 100644 new mode 100755 index 32e6058db..6e5089a0c --- a/vendor/github.com/gin-gonic/gin/render/json.go +++ b/vendor/github.com/gin-gonic/gin/render/json.go @@ -5,28 +5,65 @@ package render import ( - "encoding/json" + "bytes" + "fmt" + "html/template" "net/http" + + "github.com/gin-gonic/gin/json" ) -type ( - JSON struct { - Data interface{} - } +type JSON struct { + Data interface{} +} - IndentedJSON struct { - Data interface{} - } -) +type IndentedJSON struct { + Data interface{} +} + +type SecureJSON struct { + Prefix string + Data interface{} +} + +type JsonpJSON struct { + Callback string + Data interface{} +} + +type AsciiJSON struct { + Data interface{} +} + +type SecureJSONPrefix string var jsonContentType = []string{"application/json; charset=utf-8"} +var jsonpContentType = []string{"application/javascript; charset=utf-8"} +var jsonAsciiContentType = []string{"application/json"} -func (r JSON) Render(w http.ResponseWriter) error { - return WriteJSON(w, r.Data) +func (r JSON) Render(w http.ResponseWriter) (err error) { + if err = WriteJSON(w, r.Data); err != nil { + panic(err) + } + return } -func (r IndentedJSON) Render(w http.ResponseWriter) error { +func (r JSON) WriteContentType(w http.ResponseWriter) { writeContentType(w, jsonContentType) +} + +func WriteJSON(w http.ResponseWriter, obj interface{}) error { + writeContentType(w, jsonContentType) + jsonBytes, err := json.Marshal(obj) + if err != nil { + return err + } + w.Write(jsonBytes) + return nil +} + +func (r IndentedJSON) Render(w http.ResponseWriter) error { + r.WriteContentType(w) jsonBytes, err := json.MarshalIndent(r.Data, "", " ") if err != nil { return err @@ -35,7 +72,75 @@ func (r IndentedJSON) Render(w http.ResponseWriter) error { return nil } -func WriteJSON(w http.ResponseWriter, obj interface{}) error { +func (r IndentedJSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonContentType) +} + +func (r SecureJSON) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + jsonBytes, err := json.Marshal(r.Data) + if err != nil { + return err + } + // if the jsonBytes is array values + if bytes.HasPrefix(jsonBytes, []byte("[")) && bytes.HasSuffix(jsonBytes, []byte("]")) { + w.Write([]byte(r.Prefix)) + } + w.Write(jsonBytes) + return nil +} + +func (r SecureJSON) WriteContentType(w http.ResponseWriter) { writeContentType(w, jsonContentType) - return json.NewEncoder(w).Encode(obj) +} + +func (r JsonpJSON) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + ret, err := json.Marshal(r.Data) + if err != nil { + return err + } + + if r.Callback == "" { + w.Write(ret) + return nil + } + + callback := template.JSEscapeString(r.Callback) + w.Write([]byte(callback)) + w.Write([]byte("(")) + w.Write(ret) + w.Write([]byte(")")) + + return nil +} + +func (r JsonpJSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonpContentType) +} + +func (r AsciiJSON) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + ret, err := json.Marshal(r.Data) + if err != nil { + return err + } + + var buffer bytes.Buffer + for _, r := range string(ret) { + cvt := "" + if r < 128 { + cvt = string(r) + } else { + cvt = fmt.Sprintf("\\u%04x", int64(r)) + } + buffer.WriteString(cvt) + } + + w.Write(buffer.Bytes()) + return nil +} + +func (r AsciiJSON) WriteContentType(w http.ResponseWriter) { + writeContentType(w, jsonAsciiContentType) } diff --git a/vendor/github.com/gin-gonic/gin/render/msgpack.go b/vendor/github.com/gin-gonic/gin/render/msgpack.go new file mode 100644 index 000000000..e6c13e588 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/msgpack.go @@ -0,0 +1,31 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "net/http" + + "github.com/ugorji/go/codec" +) + +type MsgPack struct { + Data interface{} +} + +var msgpackContentType = []string{"application/msgpack; charset=utf-8"} + +func (r MsgPack) WriteContentType(w http.ResponseWriter) { + writeContentType(w, msgpackContentType) +} + +func (r MsgPack) Render(w http.ResponseWriter) error { + return WriteMsgPack(w, r.Data) +} + +func WriteMsgPack(w http.ResponseWriter, obj interface{}) error { + writeContentType(w, msgpackContentType) + var h codec.Handle = new(codec.MsgpackHandle) + return codec.NewEncoder(w, h).Encode(obj) +} diff --git a/vendor/github.com/gin-gonic/gin/render/reader.go b/vendor/github.com/gin-gonic/gin/render/reader.go new file mode 100644 index 000000000..be2132c8f --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/reader.go @@ -0,0 +1,36 @@ +package render + +import ( + "io" + "net/http" + "strconv" +) + +type Reader struct { + ContentType string + ContentLength int64 + Reader io.Reader + Headers map[string]string +} + +// Render (Reader) writes data with custom ContentType and headers. +func (r Reader) Render(w http.ResponseWriter) (err error) { + r.WriteContentType(w) + r.Headers["Content-Length"] = strconv.FormatInt(r.ContentLength, 10) + r.writeHeaders(w, r.Headers) + _, err = io.Copy(w, r.Reader) + return +} + +func (r Reader) WriteContentType(w http.ResponseWriter) { + writeContentType(w, []string{r.ContentType}) +} + +func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) { + header := w.Header() + for k, v := range headers { + if val := header[k]; len(val) == 0 { + header[k] = []string{v} + } + } +} diff --git a/vendor/github.com/gin-gonic/gin/render/redirect.go b/vendor/github.com/gin-gonic/gin/render/redirect.go index d64e4d75e..a0634f5a7 100644 --- a/vendor/github.com/gin-gonic/gin/render/redirect.go +++ b/vendor/github.com/gin-gonic/gin/render/redirect.go @@ -16,9 +16,13 @@ type Redirect struct { } func (r Redirect) Render(w http.ResponseWriter) error { - if r.Code < 300 || r.Code > 308 { + // todo(thinkerou): go1.6 not support StatusPermanentRedirect(308) + // when we upgrade go version we can use http.StatusPermanentRedirect + if (r.Code < 300 || r.Code > 308) && r.Code != 201 { panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code)) } http.Redirect(w, r.Request, r.Location, r.Code) return nil } + +func (r Redirect) WriteContentType(http.ResponseWriter) {} diff --git a/vendor/github.com/gin-gonic/gin/render/render.go b/vendor/github.com/gin-gonic/gin/render/render.go old mode 100644 new mode 100755 index 994fcd7c7..4ff1c7b63 --- a/vendor/github.com/gin-gonic/gin/render/render.go +++ b/vendor/github.com/gin-gonic/gin/render/render.go @@ -8,11 +8,14 @@ import "net/http" type Render interface { Render(http.ResponseWriter) error + WriteContentType(w http.ResponseWriter) } var ( _ Render = JSON{} _ Render = IndentedJSON{} + _ Render = SecureJSON{} + _ Render = JsonpJSON{} _ Render = XML{} _ Render = String{} _ Render = Redirect{} @@ -20,6 +23,10 @@ var ( _ Render = HTML{} _ HTMLRender = HTMLDebug{} _ HTMLRender = HTMLProduction{} + _ Render = YAML{} + _ Render = MsgPack{} + _ Render = Reader{} + _ Render = AsciiJSON{} ) func writeContentType(w http.ResponseWriter, value []string) { diff --git a/vendor/github.com/gin-gonic/gin/render/text.go b/vendor/github.com/gin-gonic/gin/render/text.go index 5a9e280bd..74cd26bee 100644 --- a/vendor/github.com/gin-gonic/gin/render/text.go +++ b/vendor/github.com/gin-gonic/gin/render/text.go @@ -22,9 +22,12 @@ func (r String) Render(w http.ResponseWriter) error { return nil } -func WriteString(w http.ResponseWriter, format string, data []interface{}) { +func (r String) WriteContentType(w http.ResponseWriter) { writeContentType(w, plainContentType) +} +func WriteString(w http.ResponseWriter, format string, data []interface{}) { + writeContentType(w, plainContentType) if len(data) > 0 { fmt.Fprintf(w, format, data...) } else { diff --git a/vendor/github.com/gin-gonic/gin/render/xml.go b/vendor/github.com/gin-gonic/gin/render/xml.go index be22e6f21..cff1ac3e8 100644 --- a/vendor/github.com/gin-gonic/gin/render/xml.go +++ b/vendor/github.com/gin-gonic/gin/render/xml.go @@ -16,6 +16,10 @@ type XML struct { var xmlContentType = []string{"application/xml; charset=utf-8"} func (r XML) Render(w http.ResponseWriter) error { - writeContentType(w, xmlContentType) + r.WriteContentType(w) return xml.NewEncoder(w).Encode(r.Data) } + +func (r XML) WriteContentType(w http.ResponseWriter) { + writeContentType(w, xmlContentType) +} diff --git a/vendor/github.com/gin-gonic/gin/render/yaml.go b/vendor/github.com/gin-gonic/gin/render/yaml.go new file mode 100644 index 000000000..25d0ebd47 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/render/yaml.go @@ -0,0 +1,33 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import ( + "net/http" + + "gopkg.in/yaml.v2" +) + +type YAML struct { + Data interface{} +} + +var yamlContentType = []string{"application/x-yaml; charset=utf-8"} + +func (r YAML) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + + bytes, err := yaml.Marshal(r.Data) + if err != nil { + return err + } + + w.Write(bytes) + return nil +} + +func (r YAML) WriteContentType(w http.ResponseWriter) { + writeContentType(w, yamlContentType) +} diff --git a/vendor/github.com/gin-gonic/gin/response_writer.go b/vendor/github.com/gin-gonic/gin/response_writer.go index fcbe230d0..923b53f8b 100644 --- a/vendor/github.com/gin-gonic/gin/response_writer.go +++ b/vendor/github.com/gin-gonic/gin/response_writer.go @@ -13,39 +13,37 @@ import ( const ( noWritten = -1 - defaultStatus = 200 + defaultStatus = http.StatusOK ) -type ( - ResponseWriter interface { - http.ResponseWriter - http.Hijacker - http.Flusher - http.CloseNotifier +type responseWriterBase interface { + http.ResponseWriter + http.Hijacker + http.Flusher + http.CloseNotifier - // Returns the HTTP response status code of the current request. - Status() int + // Returns the HTTP response status code of the current request. + Status() int - // Returns the number of bytes already written into the response http body. - // See Written() - Size() int + // Returns the number of bytes already written into the response http body. + // See Written() + Size() int - // Writes the string into the response body. - WriteString(string) (int, error) + // Writes the string into the response body. + WriteString(string) (int, error) - // Returns true if the response body was already written. - Written() bool + // Returns true if the response body was already written. + Written() bool - // Forces to write the http header (status code + headers). - WriteHeaderNow() - } + // Forces to write the http header (status code + headers). + WriteHeaderNow() +} - responseWriter struct { - http.ResponseWriter - size int - status int - } -) +type responseWriter struct { + http.ResponseWriter + size int + status int +} var _ ResponseWriter = &responseWriter{} @@ -97,7 +95,7 @@ func (w *responseWriter) Written() bool { return w.size != noWritten } -// Implements the http.Hijacker interface +// Hijack implements the http.Hijacker interface. func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { if w.size < 0 { w.size = 0 @@ -105,12 +103,13 @@ func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { return w.ResponseWriter.(http.Hijacker).Hijack() } -// Implements the http.CloseNotify interface +// CloseNotify implements the http.CloseNotify interface. func (w *responseWriter) CloseNotify() <-chan bool { return w.ResponseWriter.(http.CloseNotifier).CloseNotify() } -// Implements the http.Flush interface +// Flush implements the http.Flush interface. func (w *responseWriter) Flush() { + w.WriteHeaderNow() w.ResponseWriter.(http.Flusher).Flush() } diff --git a/vendor/github.com/gin-gonic/gin/response_writer_1.7.go b/vendor/github.com/gin-gonic/gin/response_writer_1.7.go new file mode 100644 index 000000000..801d196b0 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/response_writer_1.7.go @@ -0,0 +1,12 @@ +// +build !go1.8 + +// Copyright 2018 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +// ResponseWriter ... +type ResponseWriter interface { + responseWriterBase +} diff --git a/vendor/github.com/gin-gonic/gin/response_writer_1.8.go b/vendor/github.com/gin-gonic/gin/response_writer_1.8.go new file mode 100644 index 000000000..527c00383 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/response_writer_1.8.go @@ -0,0 +1,25 @@ +// +build go1.8 + +// Copyright 2018 Gin Core Team. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import ( + "net/http" +) + +// ResponseWriter ... +type ResponseWriter interface { + responseWriterBase + // get the http.Pusher for server push + Pusher() http.Pusher +} + +func (w *responseWriter) Pusher() (pusher http.Pusher) { + if pusher, ok := w.ResponseWriter.(http.Pusher); ok { + return pusher + } + return nil +} diff --git a/vendor/github.com/gin-gonic/gin/routergroup.go b/vendor/github.com/gin-gonic/gin/routergroup.go index c91c4675c..876a61b83 100644 --- a/vendor/github.com/gin-gonic/gin/routergroup.go +++ b/vendor/github.com/gin-gonic/gin/routergroup.go @@ -11,45 +11,43 @@ import ( "strings" ) -type ( - IRouter interface { - IRoutes - Group(string, ...HandlerFunc) *RouterGroup - } +type IRouter interface { + IRoutes + Group(string, ...HandlerFunc) *RouterGroup +} - IRoutes interface { - Use(...HandlerFunc) IRoutes - - Handle(string, string, ...HandlerFunc) IRoutes - Any(string, ...HandlerFunc) IRoutes - GET(string, ...HandlerFunc) IRoutes - POST(string, ...HandlerFunc) IRoutes - DELETE(string, ...HandlerFunc) IRoutes - PATCH(string, ...HandlerFunc) IRoutes - PUT(string, ...HandlerFunc) IRoutes - OPTIONS(string, ...HandlerFunc) IRoutes - HEAD(string, ...HandlerFunc) IRoutes - - StaticFile(string, string) IRoutes - Static(string, string) IRoutes - StaticFS(string, http.FileSystem) IRoutes - } +type IRoutes interface { + Use(...HandlerFunc) IRoutes - // RouterGroup is used internally to configure router, a RouterGroup is associated with a prefix - // and an array of handlers (middlewares) - RouterGroup struct { - Handlers HandlersChain - basePath string - engine *Engine - root bool - } -) + Handle(string, string, ...HandlerFunc) IRoutes + Any(string, ...HandlerFunc) IRoutes + GET(string, ...HandlerFunc) IRoutes + POST(string, ...HandlerFunc) IRoutes + DELETE(string, ...HandlerFunc) IRoutes + PATCH(string, ...HandlerFunc) IRoutes + PUT(string, ...HandlerFunc) IRoutes + OPTIONS(string, ...HandlerFunc) IRoutes + HEAD(string, ...HandlerFunc) IRoutes + + StaticFile(string, string) IRoutes + Static(string, string) IRoutes + StaticFS(string, http.FileSystem) IRoutes +} + +// RouterGroup is used internally to configure router, a RouterGroup is associated with a prefix +// and an array of handlers (middleware). +type RouterGroup struct { + Handlers HandlersChain + basePath string + engine *Engine + root bool +} var _ IRouter = &RouterGroup{} -// Use adds middlewares to the group, see example code in github. -func (group *RouterGroup) Use(middlewares ...HandlerFunc) IRoutes { - group.Handlers = append(group.Handlers, middlewares...) +// Use adds middleware to the group, see example code in github. +func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes { + group.Handlers = append(group.Handlers, middleware...) return group.returnObj() } @@ -74,8 +72,8 @@ func (group *RouterGroup) handle(httpMethod, relativePath string, handlers Handl return group.returnObj() } -// Handle registers a new request handle and middlewares with the given path and method. -// The last handler should be the real handler, the other ones should be middlewares that can and should be shared among different routes. +// Handle registers a new request handle and middleware with the given path and method. +// The last handler should be the real handler, the other ones should be middleware that can and should be shared among different routes. // See the example code in github. // // For GET, POST, PUT, PATCH and DELETE requests the respective shortcut @@ -91,43 +89,43 @@ func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...Ha return group.handle(httpMethod, relativePath, handlers) } -// POST is a shortcut for router.Handle("POST", path, handle) +// POST is a shortcut for router.Handle("POST", path, handle). func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes { return group.handle("POST", relativePath, handlers) } -// GET is a shortcut for router.Handle("GET", path, handle) +// GET is a shortcut for router.Handle("GET", path, handle). func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes { return group.handle("GET", relativePath, handlers) } -// DELETE is a shortcut for router.Handle("DELETE", path, handle) +// DELETE is a shortcut for router.Handle("DELETE", path, handle). func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes { return group.handle("DELETE", relativePath, handlers) } -// PATCH is a shortcut for router.Handle("PATCH", path, handle) +// PATCH is a shortcut for router.Handle("PATCH", path, handle). func (group *RouterGroup) PATCH(relativePath string, handlers ...HandlerFunc) IRoutes { return group.handle("PATCH", relativePath, handlers) } -// PUT is a shortcut for router.Handle("PUT", path, handle) +// PUT is a shortcut for router.Handle("PUT", path, handle). func (group *RouterGroup) PUT(relativePath string, handlers ...HandlerFunc) IRoutes { return group.handle("PUT", relativePath, handlers) } -// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle) +// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle). func (group *RouterGroup) OPTIONS(relativePath string, handlers ...HandlerFunc) IRoutes { return group.handle("OPTIONS", relativePath, handlers) } -// HEAD is a shortcut for router.Handle("HEAD", path, handle) +// HEAD is a shortcut for router.Handle("HEAD", path, handle). func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) IRoutes { return group.handle("HEAD", relativePath, handlers) } // Any registers a route that matches all the HTTP methods. -// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE +// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE. func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes { group.handle("GET", relativePath, handlers) group.handle("POST", relativePath, handlers) @@ -141,7 +139,7 @@ func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRou return group.returnObj() } -// StaticFile registers a single route in order to server a single file of the local filesystem. +// StaticFile registers a single route in order to serve a single file of the local filesystem. // router.StaticFile("favicon.ico", "./resources/favicon.ico") func (group *RouterGroup) StaticFile(relativePath, filepath string) IRoutes { if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") { @@ -186,7 +184,7 @@ func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileS _, nolisting := fs.(*onlyfilesFS) return func(c *Context) { if nolisting { - c.Writer.WriteHeader(404) + c.Writer.WriteHeader(http.StatusNotFound) } fileServer.ServeHTTP(c.Writer, c.Request) } diff --git a/vendor/github.com/gin-gonic/gin/test_helpers.go b/vendor/github.com/gin-gonic/gin/test_helpers.go new file mode 100644 index 000000000..3a7a5ddf6 --- /dev/null +++ b/vendor/github.com/gin-gonic/gin/test_helpers.go @@ -0,0 +1,16 @@ +// Copyright 2017 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package gin + +import "net/http" + +// CreateTestContext returns a fresh engine and context for testing purposes +func CreateTestContext(w http.ResponseWriter) (c *Context, r *Engine) { + r = New() + c = r.allocateContext() + c.reset() + c.writermem.reset(w) + return +} diff --git a/vendor/github.com/gin-gonic/gin/tree.go b/vendor/github.com/gin-gonic/gin/tree.go index c87e0d89b..b65306652 100644 --- a/vendor/github.com/gin-gonic/gin/tree.go +++ b/vendor/github.com/gin-gonic/gin/tree.go @@ -1,10 +1,11 @@ // Copyright 2013 Julien Schmidt. All rights reserved. // Use of this source code is governed by a BSD-style license that can be found -// in the LICENSE file. +// at https://github.com/julienschmidt/httprouter/blob/master/LICENSE package gin import ( + "net/url" "strings" "unicode" ) @@ -20,7 +21,7 @@ type Param struct { // It is therefore safe to read values by the index. type Params []Param -// ByName returns the value of the first Param which key matches the given name. +// Get returns the value of the first Param which key matches the given name. // If no matching Param is found, an empty string is returned. func (ps Params) Get(name string) (string, bool) { for _, entry := range ps { @@ -31,6 +32,8 @@ func (ps Params) Get(name string) (string, bool) { return "", false } +// ByName returns the value of the first Param which key matches the given name. +// If no matching Param is found, an empty string is returned. func (ps Params) ByName(name string) (va string) { va, _ = ps.Get(name) return @@ -76,23 +79,24 @@ func countParams(path string) uint8 { type nodeType uint8 const ( - static nodeType = 0 - param nodeType = 1 - catchAll nodeType = 2 + static nodeType = iota // default + root + param + catchAll ) type node struct { path string - wildChild bool - nType nodeType - maxParams uint8 indices string children []*node handlers HandlersChain priority uint32 + nType nodeType + maxParams uint8 + wildChild bool } -// increments priority of the given child and reorders if necessary +// increments priority of the given child and reorders if necessary. func (n *node) incrementChildPrio(pos int) int { n.children[pos].priority++ prio := n.children[pos].priority @@ -101,9 +105,7 @@ func (n *node) incrementChildPrio(pos int) int { newPos := pos for newPos > 0 && n.children[newPos-1].priority < prio { // swap node positions - tmpN := n.children[newPos-1] - n.children[newPos-1] = n.children[newPos] - n.children[newPos] = tmpN + n.children[newPos-1], n.children[newPos] = n.children[newPos], n.children[newPos-1] newPos-- } @@ -230,7 +232,7 @@ func (n *node) addRoute(path string, handlers HandlersChain) { } else if i == len(path) { // Make node a (in-path) leaf if n.handlers != nil { - panic("handlers are already registered for path ''" + fullPath + "'") + panic("handlers are already registered for path '" + fullPath + "'") } n.handlers = handlers } @@ -238,13 +240,14 @@ func (n *node) addRoute(path string, handlers HandlersChain) { } } else { // Empty tree n.insertChild(numParams, path, fullPath, handlers) + n.nType = root } } func (n *node) insertChild(numParams uint8, path string, fullPath string, handlers HandlersChain) { var offset int // already handled bytes of the path - // find prefix until first wildcard (beginning with ':'' or '*'') + // find prefix until first wildcard (beginning with ':' or '*') for i, max := 0, len(path); numParams > 0; i++ { c := path[i] if c != ':' && c != '*' { @@ -354,12 +357,12 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle n.handlers = handlers } -// Returns the handle registered with the given path (key). The values of +// getValue returns the handle registered with the given path (key). The values of // wildcards are saved to a map. // If no handle can be found, a TSR (trailing slash redirect) recommendation is // made if a handle exists with an extra (without the) trailing slash for the // given path. -func (n *node) getValue(path string, po Params) (handlers HandlersChain, p Params, tsr bool) { +func (n *node) getValue(path string, po Params, unescape bool) (handlers HandlersChain, p Params, tsr bool) { p = po walk: // Outer loop for walking the tree for { @@ -381,7 +384,7 @@ walk: // Outer loop for walking the tree // Nothing found. // We can recommend to redirect to the same URL without a // trailing slash if a leaf exists for that path. - tsr = (path == "/" && n.handlers != nil) + tsr = path == "/" && n.handlers != nil return } @@ -402,7 +405,15 @@ walk: // Outer loop for walking the tree i := len(p) p = p[:i+1] // expand slice within preallocated capacity p[i].Key = n.path[1:] - p[i].Value = path[:end] + val := path[:end] + if unescape { + var err error + if p[i].Value, err = url.QueryUnescape(val); err != nil { + p[i].Value = val // fallback, in case of error + } + } else { + p[i].Value = val + } // we need to go deeper! if end < len(path) { @@ -413,17 +424,18 @@ walk: // Outer loop for walking the tree } // ... but we can't - tsr = (len(path) == end+1) + tsr = len(path) == end+1 return } if handlers = n.handlers; handlers != nil { return - } else if len(n.children) == 1 { + } + if len(n.children) == 1 { // No handle found. Check if a handle for this path + a // trailing slash exists for TSR recommendation n = n.children[0] - tsr = (n.path == "/" && n.handlers != nil) + tsr = n.path == "/" && n.handlers != nil } return @@ -436,7 +448,14 @@ walk: // Outer loop for walking the tree i := len(p) p = p[:i+1] // expand slice within preallocated capacity p[i].Key = n.path[2:] - p[i].Value = path + if unescape { + var err error + if p[i].Value, err = url.QueryUnescape(path); err != nil { + p[i].Value = path // fallback, in case of error + } + } else { + p[i].Value = path + } handlers = n.handlers return @@ -452,6 +471,11 @@ walk: // Outer loop for walking the tree return } + if path == "/" && n.wildChild && n.nType != root { + tsr = true + return + } + // No handle found. Check if a handle for this path + a // trailing slash exists for trailing slash recommendation for i := 0; i < len(n.indices); i++ { @@ -475,7 +499,7 @@ walk: // Outer loop for walking the tree } } -// Makes a case-insensitive lookup of the given path and tries to find a handler. +// findCaseInsensitivePath makes a case-insensitive lookup of the given path and tries to find a handler. // It can optionally also fix trailing slashes. // It returns the case-corrected path and a bool indicating whether the lookup // was successful. @@ -506,7 +530,7 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa // Nothing found. We can recommend to redirect to the same URL // without a trailing slash if a leaf exists for that path - found = (fixTrailingSlash && path == "/" && n.handlers != nil) + found = fixTrailingSlash && path == "/" && n.handlers != nil return } diff --git a/vendor/github.com/gin-gonic/gin/utils.go b/vendor/github.com/gin-gonic/gin/utils.go index 7e6468768..bf32c775a 100644 --- a/vendor/github.com/gin-gonic/gin/utils.go +++ b/vendor/github.com/gin-gonic/gin/utils.go @@ -7,6 +7,7 @@ package gin import ( "encoding/xml" "net/http" + "os" "path" "reflect" "runtime" @@ -32,21 +33,26 @@ func Bind(val interface{}) HandlerFunc { } } +// WrapF is a helper function for wrapping http.HandlerFunc +// Returns a Gin middleware func WrapF(f http.HandlerFunc) HandlerFunc { return func(c *Context) { f(c.Writer, c.Request) } } +// WrapH is a helper function for wrapping http.Handler +// Returns a Gin middleware func WrapH(h http.Handler) HandlerFunc { return func(c *Context) { h.ServeHTTP(c.Writer, c.Request) } } +// H is a shortcut for map[string]interface{} type H map[string]interface{} -// Allows type H to be used with xml.Marshal +// MarshalXML allows type H to be used with xml.Marshal. func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error { start.Name = xml.Name{ Space: "", @@ -64,10 +70,14 @@ func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error { return err } } - if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil { - return err + + return e.EncodeToken(xml.EndElement{Name: start.Name}) +} + +func assert1(guard bool, text string) { + if !guard { + panic(text) } - return nil } func filterFlags(content string) string { @@ -93,12 +103,7 @@ func parseAccept(acceptHeader string) []string { parts := strings.Split(acceptHeader, ",") out := make([]string, 0, len(parts)) for _, part := range parts { - index := strings.IndexByte(part, ';') - if index >= 0 { - part = part[0:index] - } - part = strings.TrimSpace(part) - if len(part) > 0 { + if part = strings.TrimSpace(strings.Split(part, ";")[0]); part != "" { out = append(out, part) } } @@ -106,11 +111,10 @@ func parseAccept(acceptHeader string) []string { } func lastChar(str string) uint8 { - size := len(str) - if size == 0 { + if str == "" { panic("The length of the string can't be 0") } - return str[size-1] + return str[len(str)-1] } func nameOfFunction(f interface{}) string { @@ -118,7 +122,7 @@ func nameOfFunction(f interface{}) string { } func joinPaths(absolutePath, relativePath string) string { - if len(relativePath) == 0 { + if relativePath == "" { return absolutePath } @@ -129,3 +133,19 @@ func joinPaths(absolutePath, relativePath string) string { } return finalPath } + +func resolveAddress(addr []string) string { + switch len(addr) { + case 0: + if port := os.Getenv("PORT"); port != "" { + debugPrint("Environment variable PORT=\"%s\"", port) + return ":" + port + } + debugPrint("Environment variable PORT is undefined. Using port :8080 by default") + return ":8080" + case 1: + return addr[0] + default: + panic("too much parameters") + } +} diff --git a/vendor/github.com/gin-gonic/gin/wercker.yml b/vendor/github.com/gin-gonic/gin/wercker.yml deleted file mode 100644 index 3ab8084cc..000000000 --- a/vendor/github.com/gin-gonic/gin/wercker.yml +++ /dev/null @@ -1 +0,0 @@ -box: wercker/default \ No newline at end of file diff --git a/vendor/github.com/go-ini/ini/.github/ISSUE_TEMPLATE.md b/vendor/github.com/go-ini/ini/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 849f69f4b..000000000 --- a/vendor/github.com/go-ini/ini/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,5 +0,0 @@ -### Please give general description of the problem - -### Please provide code snippets to reproduce the problem described above - -### Do you have any suggestion to fix the problem? \ No newline at end of file diff --git a/vendor/github.com/go-ini/ini/.github/PULL_REQUEST_TEMPLATE.md b/vendor/github.com/go-ini/ini/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index b4565aeb5..000000000 --- a/vendor/github.com/go-ini/ini/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,3 +0,0 @@ -### What problem should be fixed? - -### Have you added test cases to catch the problem? diff --git a/vendor/github.com/go-ini/ini/.travis.yml b/vendor/github.com/go-ini/ini/.travis.yml deleted file mode 100644 index b097527e1..000000000 --- a/vendor/github.com/go-ini/ini/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -sudo: false -language: go -go: - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - 1.9.x - -script: - - go get golang.org/x/tools/cmd/cover - - go get github.com/smartystreets/goconvey - - mkdir -p $HOME/gopath/src/gopkg.in - - ln -s $HOME/gopath/src/github.com/go-ini/ini $HOME/gopath/src/gopkg.in/ini.v1 - - go test -v -cover -race diff --git a/vendor/github.com/go-ini/ini/Makefile b/vendor/github.com/go-ini/ini/Makefile deleted file mode 100644 index 1316911d2..000000000 --- a/vendor/github.com/go-ini/ini/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: build test bench vet coverage - -build: vet bench - -test: - go test -v -cover -race - -bench: - go test -v -cover -race -test.bench=. -test.benchmem - -vet: - go vet - -coverage: - go test -coverprofile=c.out && go tool cover -html=c.out && rm c.out \ No newline at end of file diff --git a/vendor/github.com/go-ini/ini/README.md b/vendor/github.com/go-ini/ini/README.md deleted file mode 100644 index f4ff27cd3..000000000 --- a/vendor/github.com/go-ini/ini/README.md +++ /dev/null @@ -1,763 +0,0 @@ -INI [![Build Status](https://travis-ci.org/go-ini/ini.svg?branch=master)](https://travis-ci.org/go-ini/ini) [![Sourcegraph](https://sourcegraph.com/github.com/go-ini/ini/-/badge.svg)](https://sourcegraph.com/github.com/go-ini/ini?badge) -=== - -![](https://avatars0.githubusercontent.com/u/10216035?v=3&s=200) - -Package ini provides INI file read and write functionality in Go. - -[简体中文](README_ZH.md) - -## Feature - -- Load multiple data sources(`[]byte`, file and `io.ReadCloser`) with overwrites. -- Read with recursion values. -- Read with parent-child sections. -- Read with auto-increment key names. -- Read with multiple-line values. -- Read with tons of helper methods. -- Read and convert values to Go types. -- Read and **WRITE** comments of sections and keys. -- Manipulate sections, keys and comments with ease. -- Keep sections and keys in order as you parse and save. - -## Installation - -To use a tagged revision: - - go get gopkg.in/ini.v1 - -To use with latest changes: - - go get github.com/go-ini/ini - -Please add `-u` flag to update in the future. - -### Testing - -If you want to test on your machine, please apply `-t` flag: - - go get -t gopkg.in/ini.v1 - -Please add `-u` flag to update in the future. - -## Getting Started - -### Loading from data sources - -A **Data Source** is either raw data in type `[]byte`, a file name with type `string` or `io.ReadCloser`. You can load **as many data sources as you want**. Passing other types will simply return an error. - -```go -cfg, err := ini.Load([]byte("raw data"), "filename", ioutil.NopCloser(bytes.NewReader([]byte("some other data")))) -``` - -Or start with an empty object: - -```go -cfg := ini.Empty() -``` - -When you cannot decide how many data sources to load at the beginning, you will still be able to **Append()** them later. - -```go -err := cfg.Append("other file", []byte("other raw data")) -``` - -If you have a list of files with possibilities that some of them may not available at the time, and you don't know exactly which ones, you can use `LooseLoad` to ignore nonexistent files without returning error. - -```go -cfg, err := ini.LooseLoad("filename", "filename_404") -``` - -The cool thing is, whenever the file is available to load while you're calling `Reload` method, it will be counted as usual. - -#### Ignore cases of key name - -When you do not care about cases of section and key names, you can use `InsensitiveLoad` to force all names to be lowercased while parsing. - -```go -cfg, err := ini.InsensitiveLoad("filename") -//... - -// sec1 and sec2 are the exactly same section object -sec1, err := cfg.GetSection("Section") -sec2, err := cfg.GetSection("SecTIOn") - -// key1 and key2 are the exactly same key object -key1, err := sec1.GetKey("Key") -key2, err := sec2.GetKey("KeY") -``` - -#### MySQL-like boolean key - -MySQL's configuration allows a key without value as follows: - -```ini -[mysqld] -... -skip-host-cache -skip-name-resolve -``` - -By default, this is considered as missing value. But if you know you're going to deal with those cases, you can assign advanced load options: - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{AllowBooleanKeys: true}, "my.cnf")) -``` - -The value of those keys are always `true`, and when you save to a file, it will keep in the same foramt as you read. - -To generate such keys in your program, you could use `NewBooleanKey`: - -```go -key, err := sec.NewBooleanKey("skip-host-cache") -``` - -#### Comment - -Take care that following format will be treated as comment: - -1. Line begins with `#` or `;` -2. Words after `#` or `;` -3. Words after section name (i.e words after `[some section name]`) - -If you want to save a value with `#` or `;`, please quote them with ``` ` ``` or ``` """ ```. - -Alternatively, you can use following `LoadOptions` to completely ignore inline comments: - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{IgnoreInlineComment: true}, "app.ini")) -``` - -### Working with sections - -To get a section, you would need to: - -```go -section, err := cfg.GetSection("section name") -``` - -For a shortcut for default section, just give an empty string as name: - -```go -section, err := cfg.GetSection("") -``` - -When you're pretty sure the section exists, following code could make your life easier: - -```go -section := cfg.Section("section name") -``` - -What happens when the section somehow does not exist? Don't panic, it automatically creates and returns a new section to you. - -To create a new section: - -```go -err := cfg.NewSection("new section") -``` - -To get a list of sections or section names: - -```go -sections := cfg.Sections() -names := cfg.SectionStrings() -``` - -### Working with keys - -To get a key under a section: - -```go -key, err := cfg.Section("").GetKey("key name") -``` - -Same rule applies to key operations: - -```go -key := cfg.Section("").Key("key name") -``` - -To check if a key exists: - -```go -yes := cfg.Section("").HasKey("key name") -``` - -To create a new key: - -```go -err := cfg.Section("").NewKey("name", "value") -``` - -To get a list of keys or key names: - -```go -keys := cfg.Section("").Keys() -names := cfg.Section("").KeyStrings() -``` - -To get a clone hash of keys and corresponding values: - -```go -hash := cfg.Section("").KeysHash() -``` - -### Working with values - -To get a string value: - -```go -val := cfg.Section("").Key("key name").String() -``` - -To validate key value on the fly: - -```go -val := cfg.Section("").Key("key name").Validate(func(in string) string { - if len(in) == 0 { - return "default" - } - return in -}) -``` - -If you do not want any auto-transformation (such as recursive read) for the values, you can get raw value directly (this way you get much better performance): - -```go -val := cfg.Section("").Key("key name").Value() -``` - -To check if raw value exists: - -```go -yes := cfg.Section("").HasValue("test value") -``` - -To get value with types: - -```go -// For boolean values: -// true when value is: 1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On -// false when value is: 0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off -v, err = cfg.Section("").Key("BOOL").Bool() -v, err = cfg.Section("").Key("FLOAT64").Float64() -v, err = cfg.Section("").Key("INT").Int() -v, err = cfg.Section("").Key("INT64").Int64() -v, err = cfg.Section("").Key("UINT").Uint() -v, err = cfg.Section("").Key("UINT64").Uint64() -v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339) -v, err = cfg.Section("").Key("TIME").Time() // RFC3339 - -v = cfg.Section("").Key("BOOL").MustBool() -v = cfg.Section("").Key("FLOAT64").MustFloat64() -v = cfg.Section("").Key("INT").MustInt() -v = cfg.Section("").Key("INT64").MustInt64() -v = cfg.Section("").Key("UINT").MustUint() -v = cfg.Section("").Key("UINT64").MustUint64() -v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339) -v = cfg.Section("").Key("TIME").MustTime() // RFC3339 - -// Methods start with Must also accept one argument for default value -// when key not found or fail to parse value to given type. -// Except method MustString, which you have to pass a default value. - -v = cfg.Section("").Key("String").MustString("default") -v = cfg.Section("").Key("BOOL").MustBool(true) -v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25) -v = cfg.Section("").Key("INT").MustInt(10) -v = cfg.Section("").Key("INT64").MustInt64(99) -v = cfg.Section("").Key("UINT").MustUint(3) -v = cfg.Section("").Key("UINT64").MustUint64(6) -v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now()) -v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339 -``` - -What if my value is three-line long? - -```ini -[advance] -ADDRESS = """404 road, -NotFound, State, 5000 -Earth""" -``` - -Not a problem! - -```go -cfg.Section("advance").Key("ADDRESS").String() - -/* --- start --- -404 road, -NotFound, State, 5000 -Earth ------- end --- */ -``` - -That's cool, how about continuation lines? - -```ini -[advance] -two_lines = how about \ - continuation lines? -lots_of_lines = 1 \ - 2 \ - 3 \ - 4 -``` - -Piece of cake! - -```go -cfg.Section("advance").Key("two_lines").String() // how about continuation lines? -cfg.Section("advance").Key("lots_of_lines").String() // 1 2 3 4 -``` - -Well, I hate continuation lines, how do I disable that? - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{ - IgnoreContinuation: true, -}, "filename") -``` - -Holy crap! - -Note that single quotes around values will be stripped: - -```ini -foo = "some value" // foo: some value -bar = 'some value' // bar: some value -``` - -Sometimes you downloaded file from [Crowdin](https://crowdin.com/) has values like the following (value is surrounded by double quotes and quotes in the value are escaped): - -```ini -create_repo="created repository %s" -``` - -How do you transform this to regular format automatically? - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{UnescapeValueDoubleQuotes: true}, "en-US.ini")) -cfg.Section("").Key("create_repo").String() -// You got: created repository %s -``` - -That's all? Hmm, no. - -#### Helper methods of working with values - -To get value with given candidates: - -```go -v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"}) -v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75}) -v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30}) -v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30}) -v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9}) -v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9}) -v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3}) -v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339 -``` - -Default value will be presented if value of key is not in candidates you given, and default value does not need be one of candidates. - -To validate value in a given range: - -```go -vals = cfg.Section("").Key("FLOAT64").RangeFloat64(0.0, 1.1, 2.2) -vals = cfg.Section("").Key("INT").RangeInt(0, 10, 20) -vals = cfg.Section("").Key("INT64").RangeInt64(0, 10, 20) -vals = cfg.Section("").Key("UINT").RangeUint(0, 3, 9) -vals = cfg.Section("").Key("UINT64").RangeUint64(0, 3, 9) -vals = cfg.Section("").Key("TIME").RangeTimeFormat(time.RFC3339, time.Now(), minTime, maxTime) -vals = cfg.Section("").Key("TIME").RangeTime(time.Now(), minTime, maxTime) // RFC3339 -``` - -##### Auto-split values into a slice - -To use zero value of type for invalid inputs: - -```go -// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] -// Input: how, 2.2, are, you -> [0.0 2.2 0.0 0.0] -vals = cfg.Section("").Key("STRINGS").Strings(",") -vals = cfg.Section("").Key("FLOAT64S").Float64s(",") -vals = cfg.Section("").Key("INTS").Ints(",") -vals = cfg.Section("").Key("INT64S").Int64s(",") -vals = cfg.Section("").Key("UINTS").Uints(",") -vals = cfg.Section("").Key("UINT64S").Uint64s(",") -vals = cfg.Section("").Key("TIMES").Times(",") -``` - -To exclude invalid values out of result slice: - -```go -// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] -// Input: how, 2.2, are, you -> [2.2] -vals = cfg.Section("").Key("FLOAT64S").ValidFloat64s(",") -vals = cfg.Section("").Key("INTS").ValidInts(",") -vals = cfg.Section("").Key("INT64S").ValidInt64s(",") -vals = cfg.Section("").Key("UINTS").ValidUints(",") -vals = cfg.Section("").Key("UINT64S").ValidUint64s(",") -vals = cfg.Section("").Key("TIMES").ValidTimes(",") -``` - -Or to return nothing but error when have invalid inputs: - -```go -// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] -// Input: how, 2.2, are, you -> error -vals = cfg.Section("").Key("FLOAT64S").StrictFloat64s(",") -vals = cfg.Section("").Key("INTS").StrictInts(",") -vals = cfg.Section("").Key("INT64S").StrictInt64s(",") -vals = cfg.Section("").Key("UINTS").StrictUints(",") -vals = cfg.Section("").Key("UINT64S").StrictUint64s(",") -vals = cfg.Section("").Key("TIMES").StrictTimes(",") -``` - -### Save your configuration - -Finally, it's time to save your configuration to somewhere. - -A typical way to save configuration is writing it to a file: - -```go -// ... -err = cfg.SaveTo("my.ini") -err = cfg.SaveToIndent("my.ini", "\t") -``` - -Another way to save is writing to a `io.Writer` interface: - -```go -// ... -cfg.WriteTo(writer) -cfg.WriteToIndent(writer, "\t") -``` - -By default, spaces are used to align "=" sign between key and values, to disable that: - -```go -ini.PrettyFormat = false -``` - -## Advanced Usage - -### Recursive Values - -For all value of keys, there is a special syntax `%()s`, where `` is the key name in same section or default section, and `%()s` will be replaced by corresponding value(empty string if key not found). You can use this syntax at most 99 level of recursions. - -```ini -NAME = ini - -[author] -NAME = Unknwon -GITHUB = https://github.com/%(NAME)s - -[package] -FULL_NAME = github.com/go-ini/%(NAME)s -``` - -```go -cfg.Section("author").Key("GITHUB").String() // https://github.com/Unknwon -cfg.Section("package").Key("FULL_NAME").String() // github.com/go-ini/ini -``` - -### Parent-child Sections - -You can use `.` in section name to indicate parent-child relationship between two or more sections. If the key not found in the child section, library will try again on its parent section until there is no parent section. - -```ini -NAME = ini -VERSION = v1 -IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s - -[package] -CLONE_URL = https://%(IMPORT_PATH)s - -[package.sub] -``` - -```go -cfg.Section("package.sub").Key("CLONE_URL").String() // https://gopkg.in/ini.v1 -``` - -#### Retrieve parent keys available to a child section - -```go -cfg.Section("package.sub").ParentKeys() // ["CLONE_URL"] -``` - -### Unparseable Sections - -Sometimes, you have sections that do not contain key-value pairs but raw content, to handle such case, you can use `LoadOptions.UnparsableSections`: - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{UnparseableSections: []string{"COMMENTS"}}, `[COMMENTS] -<1> This slide has the fuel listed in the wrong units `)) - -body := cfg.Section("COMMENTS").Body() - -/* --- start --- -<1> This slide has the fuel listed in the wrong units ------- end --- */ -``` - -### Auto-increment Key Names - -If key name is `-` in data source, then it would be seen as special syntax for auto-increment key name start from 1, and every section is independent on counter. - -```ini -[features] --: Support read/write comments of keys and sections --: Support auto-increment of key names --: Support load multiple files to overwrite key values -``` - -```go -cfg.Section("features").KeyStrings() // []{"#1", "#2", "#3"} -``` - -### Map To Struct - -Want more objective way to play with INI? Cool. - -```ini -Name = Unknwon -age = 21 -Male = true -Born = 1993-01-01T20:17:05Z - -[Note] -Content = Hi is a good man! -Cities = HangZhou, Boston -``` - -```go -type Note struct { - Content string - Cities []string -} - -type Person struct { - Name string - Age int `ini:"age"` - Male bool - Born time.Time - Note - Created time.Time `ini:"-"` -} - -func main() { - cfg, err := ini.Load("path/to/ini") - // ... - p := new(Person) - err = cfg.MapTo(p) - // ... - - // Things can be simpler. - err = ini.MapTo(p, "path/to/ini") - // ... - - // Just map a section? Fine. - n := new(Note) - err = cfg.Section("Note").MapTo(n) - // ... -} -``` - -Can I have default value for field? Absolutely. - -Assign it before you map to struct. It will keep the value as it is if the key is not presented or got wrong type. - -```go -// ... -p := &Person{ - Name: "Joe", -} -// ... -``` - -It's really cool, but what's the point if you can't give me my file back from struct? - -### Reflect From Struct - -Why not? - -```go -type Embeded struct { - Dates []time.Time `delim:"|" comment:"Time data"` - Places []string `ini:"places,omitempty"` - None []int `ini:",omitempty"` -} - -type Author struct { - Name string `ini:"NAME"` - Male bool - Age int `comment:"Author's age"` - GPA float64 - NeverMind string `ini:"-"` - *Embeded `comment:"Embeded section"` -} - -func main() { - a := &Author{"Unknwon", true, 21, 2.8, "", - &Embeded{ - []time.Time{time.Now(), time.Now()}, - []string{"HangZhou", "Boston"}, - []int{}, - }} - cfg := ini.Empty() - err = ini.ReflectFrom(cfg, a) - // ... -} -``` - -So, what do I get? - -```ini -NAME = Unknwon -Male = true -; Author's age -Age = 21 -GPA = 2.8 - -; Embeded section -[Embeded] -; Time data -Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00 -places = HangZhou,Boston -``` - -#### Name Mapper - -To save your time and make your code cleaner, this library supports [`NameMapper`](https://gowalker.org/gopkg.in/ini.v1#NameMapper) between struct field and actual section and key name. - -There are 2 built-in name mappers: - -- `AllCapsUnderscore`: it converts to format `ALL_CAPS_UNDERSCORE` then match section or key. -- `TitleUnderscore`: it converts to format `title_underscore` then match section or key. - -To use them: - -```go -type Info struct { - PackageName string -} - -func main() { - err = ini.MapToWithMapper(&Info{}, ini.TitleUnderscore, []byte("package_name=ini")) - // ... - - cfg, err := ini.Load([]byte("PACKAGE_NAME=ini")) - // ... - info := new(Info) - cfg.NameMapper = ini.AllCapsUnderscore - err = cfg.MapTo(info) - // ... -} -``` - -Same rules of name mapper apply to `ini.ReflectFromWithMapper` function. - -#### Value Mapper - -To expand values (e.g. from environment variables), you can use the `ValueMapper` to transform values: - -```go -type Env struct { - Foo string `ini:"foo"` -} - -func main() { - cfg, err := ini.Load([]byte("[env]\nfoo = ${MY_VAR}\n") - cfg.ValueMapper = os.ExpandEnv - // ... - env := &Env{} - err = cfg.Section("env").MapTo(env) -} -``` - -This would set the value of `env.Foo` to the value of the environment variable `MY_VAR`. - -#### Other Notes On Map/Reflect - -Any embedded struct is treated as a section by default, and there is no automatic parent-child relations in map/reflect feature: - -```go -type Child struct { - Age string -} - -type Parent struct { - Name string - Child -} - -type Config struct { - City string - Parent -} -``` - -Example configuration: - -```ini -City = Boston - -[Parent] -Name = Unknwon - -[Child] -Age = 21 -``` - -What if, yes, I'm paranoid, I want embedded struct to be in the same section. Well, all roads lead to Rome. - -```go -type Child struct { - Age string -} - -type Parent struct { - Name string - Child `ini:"Parent"` -} - -type Config struct { - City string - Parent -} -``` - -Example configuration: - -```ini -City = Boston - -[Parent] -Name = Unknwon -Age = 21 -``` - -## Getting Help - -- [API Documentation](https://gowalker.org/gopkg.in/ini.v1) -- [File An Issue](https://github.com/go-ini/ini/issues/new) - -## FAQs - -### What does `BlockMode` field do? - -By default, library lets you read and write values so we need a locker to make sure your data is safe. But in cases that you are very sure about only reading data through the library, you can set `cfg.BlockMode = false` to speed up read operations about **50-70%** faster. - -### Why another INI library? - -Many people are using my another INI library [goconfig](https://github.com/Unknwon/goconfig), so the reason for this one is I would like to make more Go style code. Also when you set `cfg.BlockMode = false`, this one is about **10-30%** faster. - -To make those changes I have to confirm API broken, so it's safer to keep it in another place and start using `gopkg.in` to version my package at this time.(PS: shorter import path) - -## License - -This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text. diff --git a/vendor/github.com/go-ini/ini/README_ZH.md b/vendor/github.com/go-ini/ini/README_ZH.md deleted file mode 100644 index 69aefef12..000000000 --- a/vendor/github.com/go-ini/ini/README_ZH.md +++ /dev/null @@ -1,750 +0,0 @@ -本包提供了 Go 语言中读写 INI 文件的功能。 - -## 功能特性 - -- 支持覆盖加载多个数据源(`[]byte`、文件和 `io.ReadCloser`) -- 支持递归读取键值 -- 支持读取父子分区 -- 支持读取自增键名 -- 支持读取多行的键值 -- 支持大量辅助方法 -- 支持在读取时直接转换为 Go 语言类型 -- 支持读取和 **写入** 分区和键的注释 -- 轻松操作分区、键值和注释 -- 在保存文件时分区和键值会保持原有的顺序 - -## 下载安装 - -使用一个特定版本: - - go get gopkg.in/ini.v1 - -使用最新版: - - go get github.com/go-ini/ini - -如需更新请添加 `-u` 选项。 - -### 测试安装 - -如果您想要在自己的机器上运行测试,请使用 `-t` 标记: - - go get -t gopkg.in/ini.v1 - -如需更新请添加 `-u` 选项。 - -## 开始使用 - -### 从数据源加载 - -一个 **数据源** 可以是 `[]byte` 类型的原始数据,`string` 类型的文件路径或 `io.ReadCloser`。您可以加载 **任意多个** 数据源。如果您传递其它类型的数据源,则会直接返回错误。 - -```go -cfg, err := ini.Load([]byte("raw data"), "filename", ioutil.NopCloser(bytes.NewReader([]byte("some other data")))) -``` - -或者从一个空白的文件开始: - -```go -cfg := ini.Empty() -``` - -当您在一开始无法决定需要加载哪些数据源时,仍可以使用 **Append()** 在需要的时候加载它们。 - -```go -err := cfg.Append("other file", []byte("other raw data")) -``` - -当您想要加载一系列文件,但是不能够确定其中哪些文件是不存在的,可以通过调用函数 `LooseLoad` 来忽略它们(`Load` 会因为文件不存在而返回错误): - -```go -cfg, err := ini.LooseLoad("filename", "filename_404") -``` - -更牛逼的是,当那些之前不存在的文件在重新调用 `Reload` 方法的时候突然出现了,那么它们会被正常加载。 - -#### 忽略键名的大小写 - -有时候分区和键的名称大小写混合非常烦人,这个时候就可以通过 `InsensitiveLoad` 将所有分区和键名在读取里强制转换为小写: - -```go -cfg, err := ini.InsensitiveLoad("filename") -//... - -// sec1 和 sec2 指向同一个分区对象 -sec1, err := cfg.GetSection("Section") -sec2, err := cfg.GetSection("SecTIOn") - -// key1 和 key2 指向同一个键对象 -key1, err := sec1.GetKey("Key") -key2, err := sec2.GetKey("KeY") -``` - -#### 类似 MySQL 配置中的布尔值键 - -MySQL 的配置文件中会出现没有具体值的布尔类型的键: - -```ini -[mysqld] -... -skip-host-cache -skip-name-resolve -``` - -默认情况下这被认为是缺失值而无法完成解析,但可以通过高级的加载选项对它们进行处理: - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{AllowBooleanKeys: true}, "my.cnf")) -``` - -这些键的值永远为 `true`,且在保存到文件时也只会输出键名。 - -如果您想要通过程序来生成此类键,则可以使用 `NewBooleanKey`: - -```go -key, err := sec.NewBooleanKey("skip-host-cache") -``` - -#### 关于注释 - -下述几种情况的内容将被视为注释: - -1. 所有以 `#` 或 `;` 开头的行 -2. 所有在 `#` 或 `;` 之后的内容 -3. 分区标签后的文字 (即 `[分区名]` 之后的内容) - -如果你希望使用包含 `#` 或 `;` 的值,请使用 ``` ` ``` 或 ``` """ ``` 进行包覆。 - -除此之外,您还可以通过 `LoadOptions` 完全忽略行内注释: - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{IgnoreInlineComment: true}, "app.ini")) -``` - -### 操作分区(Section) - -获取指定分区: - -```go -section, err := cfg.GetSection("section name") -``` - -如果您想要获取默认分区,则可以用空字符串代替分区名: - -```go -section, err := cfg.GetSection("") -``` - -当您非常确定某个分区是存在的,可以使用以下简便方法: - -```go -section := cfg.Section("section name") -``` - -如果不小心判断错了,要获取的分区其实是不存在的,那会发生什么呢?没事的,它会自动创建并返回一个对应的分区对象给您。 - -创建一个分区: - -```go -err := cfg.NewSection("new section") -``` - -获取所有分区对象或名称: - -```go -sections := cfg.Sections() -names := cfg.SectionStrings() -``` - -### 操作键(Key) - -获取某个分区下的键: - -```go -key, err := cfg.Section("").GetKey("key name") -``` - -和分区一样,您也可以直接获取键而忽略错误处理: - -```go -key := cfg.Section("").Key("key name") -``` - -判断某个键是否存在: - -```go -yes := cfg.Section("").HasKey("key name") -``` - -创建一个新的键: - -```go -err := cfg.Section("").NewKey("name", "value") -``` - -获取分区下的所有键或键名: - -```go -keys := cfg.Section("").Keys() -names := cfg.Section("").KeyStrings() -``` - -获取分区下的所有键值对的克隆: - -```go -hash := cfg.Section("").KeysHash() -``` - -### 操作键值(Value) - -获取一个类型为字符串(string)的值: - -```go -val := cfg.Section("").Key("key name").String() -``` - -获取值的同时通过自定义函数进行处理验证: - -```go -val := cfg.Section("").Key("key name").Validate(func(in string) string { - if len(in) == 0 { - return "default" - } - return in -}) -``` - -如果您不需要任何对值的自动转变功能(例如递归读取),可以直接获取原值(这种方式性能最佳): - -```go -val := cfg.Section("").Key("key name").Value() -``` - -判断某个原值是否存在: - -```go -yes := cfg.Section("").HasValue("test value") -``` - -获取其它类型的值: - -```go -// 布尔值的规则: -// true 当值为:1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On -// false 当值为:0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off -v, err = cfg.Section("").Key("BOOL").Bool() -v, err = cfg.Section("").Key("FLOAT64").Float64() -v, err = cfg.Section("").Key("INT").Int() -v, err = cfg.Section("").Key("INT64").Int64() -v, err = cfg.Section("").Key("UINT").Uint() -v, err = cfg.Section("").Key("UINT64").Uint64() -v, err = cfg.Section("").Key("TIME").TimeFormat(time.RFC3339) -v, err = cfg.Section("").Key("TIME").Time() // RFC3339 - -v = cfg.Section("").Key("BOOL").MustBool() -v = cfg.Section("").Key("FLOAT64").MustFloat64() -v = cfg.Section("").Key("INT").MustInt() -v = cfg.Section("").Key("INT64").MustInt64() -v = cfg.Section("").Key("UINT").MustUint() -v = cfg.Section("").Key("UINT64").MustUint64() -v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339) -v = cfg.Section("").Key("TIME").MustTime() // RFC3339 - -// 由 Must 开头的方法名允许接收一个相同类型的参数来作为默认值, -// 当键不存在或者转换失败时,则会直接返回该默认值。 -// 但是,MustString 方法必须传递一个默认值。 - -v = cfg.Seciont("").Key("String").MustString("default") -v = cfg.Section("").Key("BOOL").MustBool(true) -v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25) -v = cfg.Section("").Key("INT").MustInt(10) -v = cfg.Section("").Key("INT64").MustInt64(99) -v = cfg.Section("").Key("UINT").MustUint(3) -v = cfg.Section("").Key("UINT64").MustUint64(6) -v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now()) -v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339 -``` - -如果我的值有好多行怎么办? - -```ini -[advance] -ADDRESS = """404 road, -NotFound, State, 5000 -Earth""" -``` - -嗯哼?小 case! - -```go -cfg.Section("advance").Key("ADDRESS").String() - -/* --- start --- -404 road, -NotFound, State, 5000 -Earth ------- end --- */ -``` - -赞爆了!那要是我属于一行的内容写不下想要写到第二行怎么办? - -```ini -[advance] -two_lines = how about \ - continuation lines? -lots_of_lines = 1 \ - 2 \ - 3 \ - 4 -``` - -简直是小菜一碟! - -```go -cfg.Section("advance").Key("two_lines").String() // how about continuation lines? -cfg.Section("advance").Key("lots_of_lines").String() // 1 2 3 4 -``` - -可是我有时候觉得两行连在一起特别没劲,怎么才能不自动连接两行呢? - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{ - IgnoreContinuation: true, -}, "filename") -``` - -哇靠给力啊! - -需要注意的是,值两侧的单引号会被自动剔除: - -```ini -foo = "some value" // foo: some value -bar = 'some value' // bar: some value -``` - -有时您会获得像从 [Crowdin](https://crowdin.com/) 网站下载的文件那样具有特殊格式的值(值使用双引号括起来,内部的双引号被转义): - -```ini -create_repo="创建了仓库 %s" -``` - -那么,怎么自动地将这类值进行处理呢? - -```go -cfg, err := ini.LoadSources(ini.LoadOptions{UnescapeValueDoubleQuotes: true}, "en-US.ini")) -cfg.Section("").Key("create_repo").String() -// You got: 创建了仓库 %s -``` - -这就是全部了?哈哈,当然不是。 - -#### 操作键值的辅助方法 - -获取键值时设定候选值: - -```go -v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"}) -v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75}) -v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30}) -v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30}) -v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9}) -v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9}) -v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3}) -v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339 -``` - -如果获取到的值不是候选值的任意一个,则会返回默认值,而默认值不需要是候选值中的一员。 - -验证获取的值是否在指定范围内: - -```go -vals = cfg.Section("").Key("FLOAT64").RangeFloat64(0.0, 1.1, 2.2) -vals = cfg.Section("").Key("INT").RangeInt(0, 10, 20) -vals = cfg.Section("").Key("INT64").RangeInt64(0, 10, 20) -vals = cfg.Section("").Key("UINT").RangeUint(0, 3, 9) -vals = cfg.Section("").Key("UINT64").RangeUint64(0, 3, 9) -vals = cfg.Section("").Key("TIME").RangeTimeFormat(time.RFC3339, time.Now(), minTime, maxTime) -vals = cfg.Section("").Key("TIME").RangeTime(time.Now(), minTime, maxTime) // RFC3339 -``` - -##### 自动分割键值到切片(slice) - -当存在无效输入时,使用零值代替: - -```go -// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] -// Input: how, 2.2, are, you -> [0.0 2.2 0.0 0.0] -vals = cfg.Section("").Key("STRINGS").Strings(",") -vals = cfg.Section("").Key("FLOAT64S").Float64s(",") -vals = cfg.Section("").Key("INTS").Ints(",") -vals = cfg.Section("").Key("INT64S").Int64s(",") -vals = cfg.Section("").Key("UINTS").Uints(",") -vals = cfg.Section("").Key("UINT64S").Uint64s(",") -vals = cfg.Section("").Key("TIMES").Times(",") -``` - -从结果切片中剔除无效输入: - -```go -// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] -// Input: how, 2.2, are, you -> [2.2] -vals = cfg.Section("").Key("FLOAT64S").ValidFloat64s(",") -vals = cfg.Section("").Key("INTS").ValidInts(",") -vals = cfg.Section("").Key("INT64S").ValidInt64s(",") -vals = cfg.Section("").Key("UINTS").ValidUints(",") -vals = cfg.Section("").Key("UINT64S").ValidUint64s(",") -vals = cfg.Section("").Key("TIMES").ValidTimes(",") -``` - -当存在无效输入时,直接返回错误: - -```go -// Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] -// Input: how, 2.2, are, you -> error -vals = cfg.Section("").Key("FLOAT64S").StrictFloat64s(",") -vals = cfg.Section("").Key("INTS").StrictInts(",") -vals = cfg.Section("").Key("INT64S").StrictInt64s(",") -vals = cfg.Section("").Key("UINTS").StrictUints(",") -vals = cfg.Section("").Key("UINT64S").StrictUint64s(",") -vals = cfg.Section("").Key("TIMES").StrictTimes(",") -``` - -### 保存配置 - -终于到了这个时刻,是时候保存一下配置了。 - -比较原始的做法是输出配置到某个文件: - -```go -// ... -err = cfg.SaveTo("my.ini") -err = cfg.SaveToIndent("my.ini", "\t") -``` - -另一个比较高级的做法是写入到任何实现 `io.Writer` 接口的对象中: - -```go -// ... -cfg.WriteTo(writer) -cfg.WriteToIndent(writer, "\t") -``` - -默认情况下,空格将被用于对齐键值之间的等号以美化输出结果,以下代码可以禁用该功能: - -```go -ini.PrettyFormat = false -``` - -## 高级用法 - -### 递归读取键值 - -在获取所有键值的过程中,特殊语法 `%()s` 会被应用,其中 `` 可以是相同分区或者默认分区下的键名。字符串 `%()s` 会被相应的键值所替代,如果指定的键不存在,则会用空字符串替代。您可以最多使用 99 层的递归嵌套。 - -```ini -NAME = ini - -[author] -NAME = Unknwon -GITHUB = https://github.com/%(NAME)s - -[package] -FULL_NAME = github.com/go-ini/%(NAME)s -``` - -```go -cfg.Section("author").Key("GITHUB").String() // https://github.com/Unknwon -cfg.Section("package").Key("FULL_NAME").String() // github.com/go-ini/ini -``` - -### 读取父子分区 - -您可以在分区名称中使用 `.` 来表示两个或多个分区之间的父子关系。如果某个键在子分区中不存在,则会去它的父分区中再次寻找,直到没有父分区为止。 - -```ini -NAME = ini -VERSION = v1 -IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s - -[package] -CLONE_URL = https://%(IMPORT_PATH)s - -[package.sub] -``` - -```go -cfg.Section("package.sub").Key("CLONE_URL").String() // https://gopkg.in/ini.v1 -``` - -#### 获取上级父分区下的所有键名 - -```go -cfg.Section("package.sub").ParentKeys() // ["CLONE_URL"] -``` - -### 无法解析的分区 - -如果遇到一些比较特殊的分区,它们不包含常见的键值对,而是没有固定格式的纯文本,则可以使用 `LoadOptions.UnparsableSections` 进行处理: - -```go -cfg, err := LoadSources(ini.LoadOptions{UnparseableSections: []string{"COMMENTS"}}, `[COMMENTS] -<1> This slide has the fuel listed in the wrong units `)) - -body := cfg.Section("COMMENTS").Body() - -/* --- start --- -<1> This slide has the fuel listed in the wrong units ------- end --- */ -``` - -### 读取自增键名 - -如果数据源中的键名为 `-`,则认为该键使用了自增键名的特殊语法。计数器从 1 开始,并且分区之间是相互独立的。 - -```ini -[features] --: Support read/write comments of keys and sections --: Support auto-increment of key names --: Support load multiple files to overwrite key values -``` - -```go -cfg.Section("features").KeyStrings() // []{"#1", "#2", "#3"} -``` - -### 映射到结构 - -想要使用更加面向对象的方式玩转 INI 吗?好主意。 - -```ini -Name = Unknwon -age = 21 -Male = true -Born = 1993-01-01T20:17:05Z - -[Note] -Content = Hi is a good man! -Cities = HangZhou, Boston -``` - -```go -type Note struct { - Content string - Cities []string -} - -type Person struct { - Name string - Age int `ini:"age"` - Male bool - Born time.Time - Note - Created time.Time `ini:"-"` -} - -func main() { - cfg, err := ini.Load("path/to/ini") - // ... - p := new(Person) - err = cfg.MapTo(p) - // ... - - // 一切竟可以如此的简单。 - err = ini.MapTo(p, "path/to/ini") - // ... - - // 嗯哼?只需要映射一个分区吗? - n := new(Note) - err = cfg.Section("Note").MapTo(n) - // ... -} -``` - -结构的字段怎么设置默认值呢?很简单,只要在映射之前对指定字段进行赋值就可以了。如果键未找到或者类型错误,该值不会发生改变。 - -```go -// ... -p := &Person{ - Name: "Joe", -} -// ... -``` - -这样玩 INI 真的好酷啊!然而,如果不能还给我原来的配置文件,有什么卵用? - -### 从结构反射 - -可是,我有说不能吗? - -```go -type Embeded struct { - Dates []time.Time `delim:"|" comment:"Time data"` - Places []string `ini:"places,omitempty"` - None []int `ini:",omitempty"` -} - -type Author struct { - Name string `ini:"NAME"` - Male bool - Age int `comment:"Author's age"` - GPA float64 - NeverMind string `ini:"-"` - *Embeded `comment:"Embeded section"` -} - -func main() { - a := &Author{"Unknwon", true, 21, 2.8, "", - &Embeded{ - []time.Time{time.Now(), time.Now()}, - []string{"HangZhou", "Boston"}, - []int{}, - }} - cfg := ini.Empty() - err = ini.ReflectFrom(cfg, a) - // ... -} -``` - -瞧瞧,奇迹发生了。 - -```ini -NAME = Unknwon -Male = true -; Author's age -Age = 21 -GPA = 2.8 - -; Embeded section -[Embeded] -; Time data -Dates = 2015-08-07T22:14:22+08:00|2015-08-07T22:14:22+08:00 -places = HangZhou,Boston -``` - -#### 名称映射器(Name Mapper) - -为了节省您的时间并简化代码,本库支持类型为 [`NameMapper`](https://gowalker.org/gopkg.in/ini.v1#NameMapper) 的名称映射器,该映射器负责结构字段名与分区名和键名之间的映射。 - -目前有 2 款内置的映射器: - -- `AllCapsUnderscore`:该映射器将字段名转换至格式 `ALL_CAPS_UNDERSCORE` 后再去匹配分区名和键名。 -- `TitleUnderscore`:该映射器将字段名转换至格式 `title_underscore` 后再去匹配分区名和键名。 - -使用方法: - -```go -type Info struct{ - PackageName string -} - -func main() { - err = ini.MapToWithMapper(&Info{}, ini.TitleUnderscore, []byte("package_name=ini")) - // ... - - cfg, err := ini.Load([]byte("PACKAGE_NAME=ini")) - // ... - info := new(Info) - cfg.NameMapper = ini.AllCapsUnderscore - err = cfg.MapTo(info) - // ... -} -``` - -使用函数 `ini.ReflectFromWithMapper` 时也可应用相同的规则。 - -#### 值映射器(Value Mapper) - -值映射器允许使用一个自定义函数自动展开值的具体内容,例如:运行时获取环境变量: - -```go -type Env struct { - Foo string `ini:"foo"` -} - -func main() { - cfg, err := ini.Load([]byte("[env]\nfoo = ${MY_VAR}\n") - cfg.ValueMapper = os.ExpandEnv - // ... - env := &Env{} - err = cfg.Section("env").MapTo(env) -} -``` - -本例中,`env.Foo` 将会是运行时所获取到环境变量 `MY_VAR` 的值。 - -#### 映射/反射的其它说明 - -任何嵌入的结构都会被默认认作一个不同的分区,并且不会自动产生所谓的父子分区关联: - -```go -type Child struct { - Age string -} - -type Parent struct { - Name string - Child -} - -type Config struct { - City string - Parent -} -``` - -示例配置文件: - -```ini -City = Boston - -[Parent] -Name = Unknwon - -[Child] -Age = 21 -``` - -很好,但是,我就是要嵌入结构也在同一个分区。好吧,你爹是李刚! - -```go -type Child struct { - Age string -} - -type Parent struct { - Name string - Child `ini:"Parent"` -} - -type Config struct { - City string - Parent -} -``` - -示例配置文件: - -```ini -City = Boston - -[Parent] -Name = Unknwon -Age = 21 -``` - -## 获取帮助 - -- [API 文档](https://gowalker.org/gopkg.in/ini.v1) -- [创建工单](https://github.com/go-ini/ini/issues/new) - -## 常见问题 - -### 字段 `BlockMode` 是什么? - -默认情况下,本库会在您进行读写操作时采用锁机制来确保数据时间。但在某些情况下,您非常确定只进行读操作。此时,您可以通过设置 `cfg.BlockMode = false` 来将读操作提升大约 **50-70%** 的性能。 - -### 为什么要写另一个 INI 解析库? - -许多人都在使用我的 [goconfig](https://github.com/Unknwon/goconfig) 来完成对 INI 文件的操作,但我希望使用更加 Go 风格的代码。并且当您设置 `cfg.BlockMode = false` 时,会有大约 **10-30%** 的性能提升。 - -为了做出这些改变,我必须对 API 进行破坏,所以新开一个仓库是最安全的做法。除此之外,本库直接使用 `gopkg.in` 来进行版本化发布。(其实真相是导入路径更短了) diff --git a/vendor/github.com/go-ini/ini/bench_test.go b/vendor/github.com/go-ini/ini/bench_test.go deleted file mode 100644 index fc1802469..000000000 --- a/vendor/github.com/go-ini/ini/bench_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2017 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini_test - -import ( - "testing" - - "gopkg.in/ini.v1" -) - -func newTestFile(block bool) *ini.File { - c, _ := ini.Load([]byte(_CONF_DATA)) - c.BlockMode = block - return c -} - -func Benchmark_Key_Value(b *testing.B) { - c := newTestFile(true) - for i := 0; i < b.N; i++ { - c.Section("").Key("NAME").Value() - } -} - -func Benchmark_Key_Value_NonBlock(b *testing.B) { - c := newTestFile(false) - for i := 0; i < b.N; i++ { - c.Section("").Key("NAME").Value() - } -} - -func Benchmark_Key_Value_ViaSection(b *testing.B) { - c := newTestFile(true) - sec := c.Section("") - for i := 0; i < b.N; i++ { - sec.Key("NAME").Value() - } -} - -func Benchmark_Key_Value_ViaSection_NonBlock(b *testing.B) { - c := newTestFile(false) - sec := c.Section("") - for i := 0; i < b.N; i++ { - sec.Key("NAME").Value() - } -} - -func Benchmark_Key_Value_Direct(b *testing.B) { - c := newTestFile(true) - key := c.Section("").Key("NAME") - for i := 0; i < b.N; i++ { - key.Value() - } -} - -func Benchmark_Key_Value_Direct_NonBlock(b *testing.B) { - c := newTestFile(false) - key := c.Section("").Key("NAME") - for i := 0; i < b.N; i++ { - key.Value() - } -} - -func Benchmark_Key_String(b *testing.B) { - c := newTestFile(true) - for i := 0; i < b.N; i++ { - _ = c.Section("").Key("NAME").String() - } -} - -func Benchmark_Key_String_NonBlock(b *testing.B) { - c := newTestFile(false) - for i := 0; i < b.N; i++ { - _ = c.Section("").Key("NAME").String() - } -} - -func Benchmark_Key_String_ViaSection(b *testing.B) { - c := newTestFile(true) - sec := c.Section("") - for i := 0; i < b.N; i++ { - _ = sec.Key("NAME").String() - } -} - -func Benchmark_Key_String_ViaSection_NonBlock(b *testing.B) { - c := newTestFile(false) - sec := c.Section("") - for i := 0; i < b.N; i++ { - _ = sec.Key("NAME").String() - } -} - -func Benchmark_Key_SetValue(b *testing.B) { - c := newTestFile(true) - for i := 0; i < b.N; i++ { - c.Section("").Key("NAME").SetValue("10") - } -} - -func Benchmark_Key_SetValue_VisSection(b *testing.B) { - c := newTestFile(true) - sec := c.Section("") - for i := 0; i < b.N; i++ { - sec.Key("NAME").SetValue("10") - } -} diff --git a/vendor/github.com/go-ini/ini/file.go b/vendor/github.com/go-ini/ini/file.go index ce26c3b31..61ef96362 100644 --- a/vendor/github.com/go-ini/ini/file.go +++ b/vendor/github.com/go-ini/ini/file.go @@ -45,6 +45,9 @@ type File struct { // newFile initializes File object with given data sources. func newFile(dataSources []dataSource, opts LoadOptions) *File { + if len(opts.KeyValueDelimiters) == 0 { + opts.KeyValueDelimiters = "=:" + } return &File{ BlockMode: true, dataSources: dataSources, @@ -140,9 +143,14 @@ func (f *File) Section(name string) *Section { // Section returns list of Section. func (f *File) Sections() []*Section { + if f.BlockMode { + f.lock.RLock() + defer f.lock.RUnlock() + } + sections := make([]*Section, len(f.sectionList)) - for i := range f.sectionList { - sections[i] = f.Section(f.sectionList[i]) + for i, name := range f.sectionList { + sections[i] = f.sections[name] } return sections } @@ -222,8 +230,9 @@ func (f *File) Append(source interface{}, others ...interface{}) error { } func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { - equalSign := "=" - if PrettyFormat { + equalSign := DefaultFormatLeft + "=" + DefaultFormatRight + + if PrettyFormat || PrettyEqual { equalSign = " = " } @@ -232,13 +241,18 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { for i, sname := range f.sectionList { sec := f.Section(sname) if len(sec.Comment) > 0 { - if sec.Comment[0] != '#' && sec.Comment[0] != ';' { - sec.Comment = "; " + sec.Comment - } else { - sec.Comment = sec.Comment[:1] + " " + strings.TrimSpace(sec.Comment[1:]) - } - if _, err := buf.WriteString(sec.Comment + LineBreak); err != nil { - return nil, err + // Support multiline comments + lines := strings.Split(sec.Comment, LineBreak) + for i := range lines { + if lines[i][0] != '#' && lines[i][0] != ';' { + lines[i] = "; " + lines[i] + } else { + lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:]) + } + + if _, err := buf.WriteString(lines[i] + LineBreak); err != nil { + return nil, err + } } } @@ -275,7 +289,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { for _, kname := range sec.keyList { keyLength := len(kname) // First case will surround key by ` and second by """ - if strings.ContainsAny(kname, "\"=:") { + if strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters) { keyLength += 2 } else if strings.Contains(kname, "`") { keyLength += 6 @@ -295,13 +309,19 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { if len(indent) > 0 && sname != DEFAULT_SECTION { buf.WriteString(indent) } - if key.Comment[0] != '#' && key.Comment[0] != ';' { - key.Comment = "; " + key.Comment - } else { - key.Comment = key.Comment[:1] + " " + strings.TrimSpace(key.Comment[1:]) - } - if _, err := buf.WriteString(key.Comment + LineBreak); err != nil { - return nil, err + + // Support multiline comments + lines := strings.Split(key.Comment, LineBreak) + for i := range lines { + if lines[i][0] != '#' && lines[i][0] != ';' { + lines[i] = "; " + lines[i] + } else { + lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:]) + } + + if _, err := buf.WriteString(lines[i] + LineBreak); err != nil { + return nil, err + } } } @@ -312,7 +332,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { switch { case key.isAutoIncrement: kname = "-" - case strings.ContainsAny(kname, "\"=:"): + case strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters): kname = "`" + kname + "`" case strings.Contains(kname, "`"): kname = `"""` + kname + `"""` diff --git a/vendor/github.com/go-ini/ini/file_test.go b/vendor/github.com/go-ini/ini/file_test.go deleted file mode 100644 index 11612eb9a..000000000 --- a/vendor/github.com/go-ini/ini/file_test.go +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright 2017 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini_test - -import ( - "bytes" - "testing" - - . "github.com/smartystreets/goconvey/convey" - "gopkg.in/ini.v1" -) - -func TestEmpty(t *testing.T) { - Convey("Create an empty object", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - // Should only have the default section - So(len(f.Sections()), ShouldEqual, 1) - - // Default section should not contain any key - So(len(f.Section("").Keys()), ShouldBeZeroValue) - }) -} - -func TestFile_NewSection(t *testing.T) { - Convey("Create a new section", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - sec, err := f.NewSection("author") - So(err, ShouldBeNil) - So(sec, ShouldNotBeNil) - So(sec.Name(), ShouldEqual, "author") - - So(f.SectionStrings(), ShouldResemble, []string{ini.DEFAULT_SECTION, "author"}) - - Convey("With duplicated name", func() { - sec, err := f.NewSection("author") - So(err, ShouldBeNil) - So(sec, ShouldNotBeNil) - - // Does nothing if section already exists - So(f.SectionStrings(), ShouldResemble, []string{ini.DEFAULT_SECTION, "author"}) - }) - - Convey("With empty string", func() { - _, err := f.NewSection("") - So(err, ShouldNotBeNil) - }) - }) -} - -func TestFile_NewRawSection(t *testing.T) { - Convey("Create a new raw section", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - sec, err := f.NewRawSection("comments", `1111111111111111111000000000000000001110000 -111111111111111111100000000000111000000000`) - So(err, ShouldBeNil) - So(sec, ShouldNotBeNil) - So(sec.Name(), ShouldEqual, "comments") - - So(f.SectionStrings(), ShouldResemble, []string{ini.DEFAULT_SECTION, "comments"}) - So(f.Section("comments").Body(), ShouldEqual, `1111111111111111111000000000000000001110000 -111111111111111111100000000000111000000000`) - - Convey("With duplicated name", func() { - sec, err := f.NewRawSection("comments", `1111111111111111111000000000000000001110000`) - So(err, ShouldBeNil) - So(sec, ShouldNotBeNil) - So(f.SectionStrings(), ShouldResemble, []string{ini.DEFAULT_SECTION, "comments"}) - - // Overwrite previous existed section - So(f.Section("comments").Body(), ShouldEqual, `1111111111111111111000000000000000001110000`) - }) - - Convey("With empty string", func() { - _, err := f.NewRawSection("", "") - So(err, ShouldNotBeNil) - }) - }) -} - -func TestFile_NewSections(t *testing.T) { - Convey("Create new sections", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - So(f.NewSections("package", "author"), ShouldBeNil) - So(f.SectionStrings(), ShouldResemble, []string{ini.DEFAULT_SECTION, "package", "author"}) - - Convey("With duplicated name", func() { - So(f.NewSections("author", "features"), ShouldBeNil) - - // Ignore section already exists - So(f.SectionStrings(), ShouldResemble, []string{ini.DEFAULT_SECTION, "package", "author", "features"}) - }) - - Convey("With empty string", func() { - So(f.NewSections("", ""), ShouldNotBeNil) - }) - }) -} - -func TestFile_GetSection(t *testing.T) { - Convey("Get a section", t, func() { - f, err := ini.Load(_FULL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - sec, err := f.GetSection("author") - So(err, ShouldBeNil) - So(sec, ShouldNotBeNil) - So(sec.Name(), ShouldEqual, "author") - - Convey("Section not exists", func() { - _, err := f.GetSection("404") - So(err, ShouldNotBeNil) - }) - }) -} - -func TestFile_Section(t *testing.T) { - Convey("Get a section", t, func() { - f, err := ini.Load(_FULL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - sec := f.Section("author") - So(sec, ShouldNotBeNil) - So(sec.Name(), ShouldEqual, "author") - - Convey("Section not exists", func() { - sec := f.Section("404") - So(sec, ShouldNotBeNil) - So(sec.Name(), ShouldEqual, "404") - }) - }) - - Convey("Get default section in lower case with insensitive load", t, func() { - f, err := ini.InsensitiveLoad([]byte(` -[default] -NAME = ini -VERSION = v1`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("name").String(), ShouldEqual, "ini") - So(f.Section("").Key("version").String(), ShouldEqual, "v1") - }) -} - -func TestFile_Sections(t *testing.T) { - Convey("Get all sections", t, func() { - f, err := ini.Load(_FULL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - secs := f.Sections() - names := []string{ini.DEFAULT_SECTION, "author", "package", "package.sub", "features", "types", "array", "note", "comments", "string escapes", "advance"} - So(len(secs), ShouldEqual, len(names)) - for i, name := range names { - So(secs[i].Name(), ShouldEqual, name) - } - }) -} - -func TestFile_ChildSections(t *testing.T) { - Convey("Get child sections by parent name", t, func() { - f, err := ini.Load([]byte(` -[node] -[node.biz1] -[node.biz2] -[node.biz3] -[node.bizN] -`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - children := f.ChildSections("node") - names := []string{"node.biz1", "node.biz2", "node.biz3", "node.bizN"} - So(len(children), ShouldEqual, len(names)) - for i, name := range names { - So(children[i].Name(), ShouldEqual, name) - } - }) -} - -func TestFile_SectionStrings(t *testing.T) { - Convey("Get all section names", t, func() { - f, err := ini.Load(_FULL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.SectionStrings(), ShouldResemble, []string{ini.DEFAULT_SECTION, "author", "package", "package.sub", "features", "types", "array", "note", "comments", "string escapes", "advance"}) - }) -} - -func TestFile_DeleteSection(t *testing.T) { - Convey("Delete a section", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - f.NewSections("author", "package", "features") - f.DeleteSection("features") - f.DeleteSection("") - So(f.SectionStrings(), ShouldResemble, []string{"author", "package"}) - }) -} - -func TestFile_Append(t *testing.T) { - Convey("Append a data source", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - So(f.Append(_MINIMAL_CONF, []byte(` -[author] -NAME = Unknwon`)), ShouldBeNil) - - Convey("With bad input", func() { - So(f.Append(123), ShouldNotBeNil) - So(f.Append(_MINIMAL_CONF, 123), ShouldNotBeNil) - }) - }) -} - -func TestFile_WriteTo(t *testing.T) { - Convey("Write content to somewhere", t, func() { - f, err := ini.Load(_FULL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - f.Section("author").Comment = `Information about package author -# Bio can be written in multiple lines.` - f.Section("author").Key("NAME").Comment = "This is author name" - f.Section("note").NewBooleanKey("boolean_key") - f.Section("note").NewKey("more", "notes") - - var buf bytes.Buffer - _, err = f.WriteTo(&buf) - So(err, ShouldBeNil) - So(buf.String(), ShouldEqual, `; Package name -NAME = ini -; Package version -VERSION = v1 -; Package import path -IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s - -; Information about package author -# Bio can be written in multiple lines. -[author] -; This is author name -NAME = Unknwon -E-MAIL = u@gogs.io -GITHUB = https://github.com/%(NAME)s -# Succeeding comment -BIO = """Gopher. -Coding addict. -Good man. -""" - -[package] -CLONE_URL = https://%(IMPORT_PATH)s - -[package.sub] -UNUSED_KEY = should be deleted - -[features] -- = Support read/write comments of keys and sections -- = Support auto-increment of key names -- = Support load multiple files to overwrite key values - -[types] -STRING = str -BOOL = true -BOOL_FALSE = false -FLOAT64 = 1.25 -INT = 10 -TIME = 2015-01-01T20:17:05Z -DURATION = 2h45m -UINT = 3 - -[array] -STRINGS = en, zh, de -FLOAT64S = 1.1, 2.2, 3.3 -INTS = 1, 2, 3 -UINTS = 1, 2, 3 -TIMES = 2015-01-01T20:17:05Z,2015-01-01T20:17:05Z,2015-01-01T20:17:05Z - -[note] -empty_lines = next line is empty -boolean_key -more = notes - -; Comment before the section -; This is a comment for the section too -[comments] -; Comment before key -key = value -; This is a comment for key2 -key2 = value2 -key3 = "one", "two", "three" - -[string escapes] -key1 = value1, value2, value3 -key2 = value1\, value2 -key3 = val\ue1, value2 -key4 = value1\\, value\\\\2 -key5 = value1\,, value2 -key6 = aaa bbb\ and\ space ccc - -[advance] -value with quotes = some value -value quote2 again = some value -includes comment sign = `+"`"+"my#password"+"`"+` -includes comment sign2 = `+"`"+"my;password"+"`"+` -true = 2+3=5 -`+"`"+`1+1=2`+"`"+` = true -`+"`"+`6+1=7`+"`"+` = true -"""`+"`"+`5+5`+"`"+`""" = 10 -`+"`"+`"6+6"`+"`"+` = 12 -`+"`"+`7-2=4`+"`"+` = false -ADDRESS = """404 road, -NotFound, State, 50000""" -two_lines = how about continuation lines? -lots_of_lines = 1 2 3 4 - -`) - }) -} - -func TestFile_SaveTo(t *testing.T) { - Convey("Write content to somewhere", t, func() { - f, err := ini.Load(_FULL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.SaveTo("testdata/conf_out.ini"), ShouldBeNil) - So(f.SaveToIndent("testdata/conf_out.ini", "\t"), ShouldBeNil) - }) -} diff --git a/vendor/github.com/go-ini/ini/ini.go b/vendor/github.com/go-ini/ini/ini.go index 535d3588a..b6505a94b 100644 --- a/vendor/github.com/go-ini/ini/ini.go +++ b/vendor/github.com/go-ini/ini/ini.go @@ -1,3 +1,5 @@ +// +build go1.6 + // Copyright 2014 Unknwon // // Licensed under the Apache License, Version 2.0 (the "License"): you may @@ -32,7 +34,7 @@ const ( // Maximum allowed depth when recursively substituing variable names. _DEPTH_VALUES = 99 - _VERSION = "1.32.0" + _VERSION = "1.39.0" ) // Version returns current package version literal. @@ -46,6 +48,10 @@ var ( // at package init time. LineBreak = "\n" + // Place custom spaces when PrettyFormat and PrettyEqual are both disabled + DefaultFormatLeft = "" + DefaultFormatRight = "" + // Variable regexp pattern: %(variable)s varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`) @@ -53,6 +59,9 @@ var ( // or reduce all possible spaces for compact format. PrettyFormat = true + // Place spaces around "=" sign even when PrettyFormat is false + PrettyEqual = false + // Explicitly write DEFAULT section header DefaultHeader = false @@ -129,6 +138,8 @@ type LoadOptions struct { IgnoreContinuation bool // IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value. IgnoreInlineComment bool + // SkipUnrecognizableLines indicates whether to skip unrecognizable lines that do not conform to key/value pairs. + SkipUnrecognizableLines bool // AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing. // This type of keys are mostly used in my.cnf. AllowBooleanKeys bool @@ -137,6 +148,16 @@ type LoadOptions struct { // AllowNestedValues indicates whether to allow AWS-like nested values. // Docs: http://docs.aws.amazon.com/cli/latest/topic/config-vars.html#nested-values AllowNestedValues bool + // AllowPythonMultilineValues indicates whether to allow Python-like multi-line values. + // Docs: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure + // Relevant quote: Values can also span multiple lines, as long as they are indented deeper + // than the first line of the value. + AllowPythonMultilineValues bool + // SpaceBeforeInlineComment indicates whether to allow comment symbols (\# and \;) inside value. + // Docs: https://docs.python.org/2/library/configparser.html + // Quote: Comments may appear on their own in an otherwise empty line, or may be entered in lines holding values or section names. + // In the latter case, they need to be preceded by a whitespace character to be recognized as a comment. + SpaceBeforeInlineComment bool // UnescapeValueDoubleQuotes indicates whether to unescape double quotes inside value to regular format // when value is surrounded by double quotes, e.g. key="a \"value\"" => key=a "value" UnescapeValueDoubleQuotes bool @@ -144,9 +165,11 @@ type LoadOptions struct { // when value is NOT surrounded by any quotes. // Note: UNSTABLE, behavior might change to only unescape inside double quotes but may noy necessary at all. UnescapeValueCommentSymbols bool - // Some INI formats allow group blocks that store a block of raw content that doesn't otherwise + // UnparseableSections stores a list of blocks that are allowed with raw content which do not otherwise // conform to key/value pairs. Specify the names of those blocks here. UnparseableSections []string + // KeyValueDelimiters is the sequence of delimiters that are used to separate key and value. By default, it is "=:". + KeyValueDelimiters string } func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) { @@ -187,7 +210,7 @@ func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) { return LoadSources(LoadOptions{Insensitive: true}, source, others...) } -// InsensitiveLoad has exactly same functionality as Load function +// ShadowLoad has exactly same functionality as Load function // except it allows have shadow keys. func ShadowLoad(source interface{}, others ...interface{}) (*File, error) { return LoadSources(LoadOptions{AllowShadows: true}, source, others...) diff --git a/vendor/github.com/go-ini/ini/ini_internal_test.go b/vendor/github.com/go-ini/ini/ini_internal_test.go deleted file mode 100644 index 257ef1ebb..000000000 --- a/vendor/github.com/go-ini/ini/ini_internal_test.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2017 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" -) - -func Test_Version(t *testing.T) { - Convey("Get version", t, func() { - So(Version(), ShouldEqual, _VERSION) - }) -} - -func Test_isSlice(t *testing.T) { - Convey("Check if a string is in the slice", t, func() { - ss := []string{"a", "b", "c"} - So(inSlice("a", ss), ShouldBeTrue) - So(inSlice("d", ss), ShouldBeFalse) - }) -} diff --git a/vendor/github.com/go-ini/ini/ini_test.go b/vendor/github.com/go-ini/ini/ini_test.go deleted file mode 100644 index 3e6992d3f..000000000 --- a/vendor/github.com/go-ini/ini/ini_test.go +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2014 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini_test - -import ( - "bytes" - "io/ioutil" - "testing" - - . "github.com/smartystreets/goconvey/convey" - "gopkg.in/ini.v1" -) - -const ( - _CONF_DATA = ` - ; Package name - NAME = ini - ; Package version - VERSION = v1 - ; Package import path - IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s - - # Information about package author - # Bio can be written in multiple lines. - [author] - NAME = Unknwon ; Succeeding comment - E-MAIL = fake@localhost - GITHUB = https://github.com/%(NAME)s - BIO = """Gopher. - Coding addict. - Good man. - """ # Succeeding comment` - _MINIMAL_CONF = "testdata/minimal.ini" - _FULL_CONF = "testdata/full.ini" - _NOT_FOUND_CONF = "testdata/404.ini" -) - -func TestLoad(t *testing.T) { - Convey("Load from good data sources", t, func() { - f, err := ini.Load([]byte(` -NAME = ini -VERSION = v1 -IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s`), - "testdata/minimal.ini", - ioutil.NopCloser(bytes.NewReader([]byte(` -[author] -NAME = Unknwon -`))), - ) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - // Vaildate values make sure all sources are loaded correctly - sec := f.Section("") - So(sec.Key("NAME").String(), ShouldEqual, "ini") - So(sec.Key("VERSION").String(), ShouldEqual, "v1") - So(sec.Key("IMPORT_PATH").String(), ShouldEqual, "gopkg.in/ini.v1") - - sec = f.Section("author") - So(sec.Key("NAME").String(), ShouldEqual, "Unknwon") - So(sec.Key("E-MAIL").String(), ShouldEqual, "u@gogs.io") - }) - - Convey("Load from bad data sources", t, func() { - Convey("Invalid input", func() { - _, err := ini.Load(_NOT_FOUND_CONF) - So(err, ShouldNotBeNil) - }) - - Convey("Unsupported type", func() { - _, err := ini.Load(123) - So(err, ShouldNotBeNil) - }) - }) -} - -func TestLoadSources(t *testing.T) { - Convey("Load from data sources with options", t, func() { - Convey("Ignore nonexistent files", func() { - f, err := ini.LooseLoad(_NOT_FOUND_CONF, _MINIMAL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - Convey("Inverse case", func() { - _, err = ini.Load(_NOT_FOUND_CONF) - So(err, ShouldNotBeNil) - }) - }) - - Convey("Insensitive to section and key names", func() { - f, err := ini.InsensitiveLoad(_MINIMAL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("Author").Key("e-mail").String(), ShouldEqual, "u@gogs.io") - - Convey("Write out", func() { - var buf bytes.Buffer - _, err := f.WriteTo(&buf) - So(err, ShouldBeNil) - So(buf.String(), ShouldEqual, `[author] -e-mail = u@gogs.io - -`) - }) - - Convey("Inverse case", func() { - f, err := ini.Load(_MINIMAL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("Author").Key("e-mail").String(), ShouldBeEmpty) - }) - }) - - Convey("Ignore continuation lines", func() { - f, err := ini.LoadSources(ini.LoadOptions{ - IgnoreContinuation: true, - }, []byte(` -key1=a\b\ -key2=c\d\ -key3=value`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("key1").String(), ShouldEqual, `a\b\`) - So(f.Section("").Key("key2").String(), ShouldEqual, `c\d\`) - So(f.Section("").Key("key3").String(), ShouldEqual, "value") - - Convey("Inverse case", func() { - f, err := ini.Load([]byte(` -key1=a\b\ -key2=c\d\`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("key1").String(), ShouldEqual, `a\bkey2=c\d`) - }) - }) - - Convey("Ignore inline comments", func() { - f, err := ini.LoadSources(ini.LoadOptions{ - IgnoreInlineComment: true, - }, []byte(` -key1=value ;comment -key2=value2 #comment2`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("key1").String(), ShouldEqual, `value ;comment`) - So(f.Section("").Key("key2").String(), ShouldEqual, `value2 #comment2`) - - Convey("Inverse case", func() { - f, err := ini.Load([]byte(` -key1=value ;comment -key2=value2 #comment2`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("key1").String(), ShouldEqual, `value`) - So(f.Section("").Key("key1").Comment, ShouldEqual, `;comment`) - So(f.Section("").Key("key2").String(), ShouldEqual, `value2`) - So(f.Section("").Key("key2").Comment, ShouldEqual, `#comment2`) - }) - }) - - Convey("Allow boolean type keys", func() { - f, err := ini.LoadSources(ini.LoadOptions{ - AllowBooleanKeys: true, - }, []byte(` -key1=hello -#key2 -key3`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").KeyStrings(), ShouldResemble, []string{"key1", "key3"}) - So(f.Section("").Key("key3").MustBool(false), ShouldBeTrue) - - Convey("Write out", func() { - var buf bytes.Buffer - _, err := f.WriteTo(&buf) - So(err, ShouldBeNil) - So(buf.String(), ShouldEqual, `key1 = hello -# key2 -key3 -`) - }) - - Convey("Inverse case", func() { - _, err := ini.Load([]byte(` -key1=hello -#key2 -key3`)) - So(err, ShouldNotBeNil) - }) - }) - - Convey("Allow shadow keys", func() { - f, err := ini.ShadowLoad([]byte(` -[remote "origin"] -url = https://github.com/Antergone/test1.git -url = https://github.com/Antergone/test2.git -fetch = +refs/heads/*:refs/remotes/origin/*`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section(`remote "origin"`).Key("url").String(), ShouldEqual, "https://github.com/Antergone/test1.git") - So(f.Section(`remote "origin"`).Key("url").ValueWithShadows(), ShouldResemble, []string{ - "https://github.com/Antergone/test1.git", - "https://github.com/Antergone/test2.git", - }) - So(f.Section(`remote "origin"`).Key("fetch").String(), ShouldEqual, "+refs/heads/*:refs/remotes/origin/*") - - Convey("Write out", func() { - var buf bytes.Buffer - _, err := f.WriteTo(&buf) - So(err, ShouldBeNil) - So(buf.String(), ShouldEqual, `[remote "origin"] -url = https://github.com/Antergone/test1.git -url = https://github.com/Antergone/test2.git -fetch = +refs/heads/*:refs/remotes/origin/* - -`) - }) - - Convey("Inverse case", func() { - f, err := ini.Load([]byte(` -[remote "origin"] -url = https://github.com/Antergone/test1.git -url = https://github.com/Antergone/test2.git`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section(`remote "origin"`).Key("url").String(), ShouldEqual, "https://github.com/Antergone/test2.git") - }) - }) - - Convey("Unescape double quotes inside value", func() { - f, err := ini.LoadSources(ini.LoadOptions{ - UnescapeValueDoubleQuotes: true, - }, []byte(` -create_repo="创建了仓库 %s"`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("create_repo").String(), ShouldEqual, `创建了仓库 %s`) - - Convey("Inverse case", func() { - f, err := ini.Load([]byte(` -create_repo="创建了仓库 %s"`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("create_repo").String(), ShouldEqual, `"创建了仓库 %s"`) - }) - }) - - Convey("Unescape comment symbols inside value", func() { - f, err := ini.LoadSources(ini.LoadOptions{ - IgnoreInlineComment: true, - UnescapeValueCommentSymbols: true, - }, []byte(` -key = test value more text -`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("key").String(), ShouldEqual, `test value more text`) - }) - - Convey("Allow unparseable sections", func() { - f, err := ini.LoadSources(ini.LoadOptions{ - Insensitive: true, - UnparseableSections: []string{"core_lesson", "comments"}, - }, []byte(` -Lesson_Location = 87 -Lesson_Status = C -Score = 3 -Time = 00:02:30 - -[CORE_LESSON] -my lesson state data – 1111111111111111111000000000000000001110000 -111111111111111111100000000000111000000000 – end my lesson state data - -[COMMENTS] -<1> This slide has the fuel listed in the wrong units `)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("score").String(), ShouldEqual, "3") - So(f.Section("").Body(), ShouldBeEmpty) - So(f.Section("core_lesson").Body(), ShouldEqual, `my lesson state data – 1111111111111111111000000000000000001110000 -111111111111111111100000000000111000000000 – end my lesson state data`) - So(f.Section("comments").Body(), ShouldEqual, `<1> This slide has the fuel listed in the wrong units `) - - Convey("Write out", func() { - var buf bytes.Buffer - _, err := f.WriteTo(&buf) - So(err, ShouldBeNil) - So(buf.String(), ShouldEqual, `lesson_location = 87 -lesson_status = C -score = 3 -time = 00:02:30 - -[core_lesson] -my lesson state data – 1111111111111111111000000000000000001110000 -111111111111111111100000000000111000000000 – end my lesson state data - -[comments] -<1> This slide has the fuel listed in the wrong units -`) - }) - - Convey("Inverse case", func() { - _, err := ini.Load([]byte(` -[CORE_LESSON] -my lesson state data – 1111111111111111111000000000000000001110000 -111111111111111111100000000000111000000000 – end my lesson state data`)) - So(err, ShouldNotBeNil) - }) - }) - }) -} diff --git a/vendor/github.com/go-ini/ini/key_test.go b/vendor/github.com/go-ini/ini/key_test.go deleted file mode 100644 index a13ad95fa..000000000 --- a/vendor/github.com/go-ini/ini/key_test.go +++ /dev/null @@ -1,523 +0,0 @@ -// Copyright 2014 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini_test - -import ( - "bytes" - "fmt" - "strings" - "testing" - "time" - - . "github.com/smartystreets/goconvey/convey" - "gopkg.in/ini.v1" -) - -func TestKey_AddShadow(t *testing.T) { - Convey("Add shadow to a key", t, func() { - f, err := ini.ShadowLoad([]byte(` -[notes] --: note1`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - So(k.AddShadow("ini.v1"), ShouldBeNil) - So(k.ValueWithShadows(), ShouldResemble, []string{"ini", "ini.v1"}) - - Convey("Add shadow to boolean key", func() { - k, err := f.Section("").NewBooleanKey("published") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - So(k.AddShadow("beta"), ShouldNotBeNil) - }) - - Convey("Add shadow to auto-increment key", func() { - So(f.Section("notes").Key("#1").AddShadow("beta"), ShouldNotBeNil) - }) - }) - - Convey("Shadow is not allowed", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - So(k.AddShadow("ini.v1"), ShouldNotBeNil) - }) -} - -// Helpers for slice tests. -func float64sEqual(values []float64, expected ...float64) { - So(values, ShouldHaveLength, len(expected)) - for i, v := range expected { - So(values[i], ShouldEqual, v) - } -} - -func intsEqual(values []int, expected ...int) { - So(values, ShouldHaveLength, len(expected)) - for i, v := range expected { - So(values[i], ShouldEqual, v) - } -} - -func int64sEqual(values []int64, expected ...int64) { - So(values, ShouldHaveLength, len(expected)) - for i, v := range expected { - So(values[i], ShouldEqual, v) - } -} - -func uintsEqual(values []uint, expected ...uint) { - So(values, ShouldHaveLength, len(expected)) - for i, v := range expected { - So(values[i], ShouldEqual, v) - } -} - -func uint64sEqual(values []uint64, expected ...uint64) { - So(values, ShouldHaveLength, len(expected)) - for i, v := range expected { - So(values[i], ShouldEqual, v) - } -} - -func timesEqual(values []time.Time, expected ...time.Time) { - So(values, ShouldHaveLength, len(expected)) - for i, v := range expected { - So(values[i].String(), ShouldEqual, v.String()) - } -} - -func TestKey_Helpers(t *testing.T) { - Convey("Getting and setting values", t, func() { - f, err := ini.Load(_FULL_CONF) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - Convey("Get string representation", func() { - sec := f.Section("") - So(sec, ShouldNotBeNil) - So(sec.Key("NAME").Value(), ShouldEqual, "ini") - So(sec.Key("NAME").String(), ShouldEqual, "ini") - So(sec.Key("NAME").Validate(func(in string) string { - return in - }), ShouldEqual, "ini") - So(sec.Key("NAME").Comment, ShouldEqual, "; Package name") - So(sec.Key("IMPORT_PATH").String(), ShouldEqual, "gopkg.in/ini.v1") - - Convey("With ValueMapper", func() { - f.ValueMapper = func(in string) string { - if in == "gopkg.in/%(NAME)s.%(VERSION)s" { - return "github.com/go-ini/ini" - } - return in - } - So(sec.Key("IMPORT_PATH").String(), ShouldEqual, "github.com/go-ini/ini") - }) - }) - - Convey("Get values in non-default section", func() { - sec := f.Section("author") - So(sec, ShouldNotBeNil) - So(sec.Key("NAME").String(), ShouldEqual, "Unknwon") - So(sec.Key("GITHUB").String(), ShouldEqual, "https://github.com/Unknwon") - - sec = f.Section("package") - So(sec, ShouldNotBeNil) - So(sec.Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1") - }) - - Convey("Get auto-increment key names", func() { - keys := f.Section("features").Keys() - for i, k := range keys { - So(k.Name(), ShouldEqual, fmt.Sprintf("#%d", i+1)) - } - }) - - Convey("Get parent-keys that are available to the child section", func() { - parentKeys := f.Section("package.sub").ParentKeys() - for _, k := range parentKeys { - So(k.Name(), ShouldEqual, "CLONE_URL") - } - }) - - Convey("Get overwrite value", func() { - So(f.Section("author").Key("E-MAIL").String(), ShouldEqual, "u@gogs.io") - }) - - Convey("Get sections", func() { - sections := f.Sections() - for i, name := range []string{ini.DEFAULT_SECTION, "author", "package", "package.sub", "features", "types", "array", "note", "comments", "string escapes", "advance"} { - So(sections[i].Name(), ShouldEqual, name) - } - }) - - Convey("Get parent section value", func() { - So(f.Section("package.sub").Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1") - So(f.Section("package.fake.sub").Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1") - }) - - Convey("Get multiple line value", func() { - So(f.Section("author").Key("BIO").String(), ShouldEqual, "Gopher.\nCoding addict.\nGood man.\n") - }) - - Convey("Get values with type", func() { - sec := f.Section("types") - v1, err := sec.Key("BOOL").Bool() - So(err, ShouldBeNil) - So(v1, ShouldBeTrue) - - v1, err = sec.Key("BOOL_FALSE").Bool() - So(err, ShouldBeNil) - So(v1, ShouldBeFalse) - - v2, err := sec.Key("FLOAT64").Float64() - So(err, ShouldBeNil) - So(v2, ShouldEqual, 1.25) - - v3, err := sec.Key("INT").Int() - So(err, ShouldBeNil) - So(v3, ShouldEqual, 10) - - v4, err := sec.Key("INT").Int64() - So(err, ShouldBeNil) - So(v4, ShouldEqual, 10) - - v5, err := sec.Key("UINT").Uint() - So(err, ShouldBeNil) - So(v5, ShouldEqual, 3) - - v6, err := sec.Key("UINT").Uint64() - So(err, ShouldBeNil) - So(v6, ShouldEqual, 3) - - t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") - So(err, ShouldBeNil) - v7, err := sec.Key("TIME").Time() - So(err, ShouldBeNil) - So(v7.String(), ShouldEqual, t.String()) - - Convey("Must get values with type", func() { - So(sec.Key("STRING").MustString("404"), ShouldEqual, "str") - So(sec.Key("BOOL").MustBool(), ShouldBeTrue) - So(sec.Key("FLOAT64").MustFloat64(), ShouldEqual, 1.25) - So(sec.Key("INT").MustInt(), ShouldEqual, 10) - So(sec.Key("INT").MustInt64(), ShouldEqual, 10) - So(sec.Key("UINT").MustUint(), ShouldEqual, 3) - So(sec.Key("UINT").MustUint64(), ShouldEqual, 3) - So(sec.Key("TIME").MustTime().String(), ShouldEqual, t.String()) - - dur, err := time.ParseDuration("2h45m") - So(err, ShouldBeNil) - So(sec.Key("DURATION").MustDuration().Seconds(), ShouldEqual, dur.Seconds()) - - Convey("Must get values with default value", func() { - So(sec.Key("STRING_404").MustString("404"), ShouldEqual, "404") - So(sec.Key("BOOL_404").MustBool(true), ShouldBeTrue) - So(sec.Key("FLOAT64_404").MustFloat64(2.5), ShouldEqual, 2.5) - So(sec.Key("INT_404").MustInt(15), ShouldEqual, 15) - So(sec.Key("INT64_404").MustInt64(15), ShouldEqual, 15) - So(sec.Key("UINT_404").MustUint(6), ShouldEqual, 6) - So(sec.Key("UINT64_404").MustUint64(6), ShouldEqual, 6) - - t, err := time.Parse(time.RFC3339, "2014-01-01T20:17:05Z") - So(err, ShouldBeNil) - So(sec.Key("TIME_404").MustTime(t).String(), ShouldEqual, t.String()) - - So(sec.Key("DURATION_404").MustDuration(dur).Seconds(), ShouldEqual, dur.Seconds()) - - Convey("Must should set default as key value", func() { - So(sec.Key("STRING_404").String(), ShouldEqual, "404") - So(sec.Key("BOOL_404").String(), ShouldEqual, "true") - So(sec.Key("FLOAT64_404").String(), ShouldEqual, "2.5") - So(sec.Key("INT_404").String(), ShouldEqual, "15") - So(sec.Key("INT64_404").String(), ShouldEqual, "15") - So(sec.Key("UINT_404").String(), ShouldEqual, "6") - So(sec.Key("UINT64_404").String(), ShouldEqual, "6") - So(sec.Key("TIME_404").String(), ShouldEqual, "2014-01-01T20:17:05Z") - So(sec.Key("DURATION_404").String(), ShouldEqual, "2h45m0s") - }) - }) - }) - }) - - Convey("Get value with candidates", func() { - sec := f.Section("types") - So(sec.Key("STRING").In("", []string{"str", "arr", "types"}), ShouldEqual, "str") - So(sec.Key("FLOAT64").InFloat64(0, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25) - So(sec.Key("INT").InInt(0, []int{10, 20, 30}), ShouldEqual, 10) - So(sec.Key("INT").InInt64(0, []int64{10, 20, 30}), ShouldEqual, 10) - So(sec.Key("UINT").InUint(0, []uint{3, 6, 9}), ShouldEqual, 3) - So(sec.Key("UINT").InUint64(0, []uint64{3, 6, 9}), ShouldEqual, 3) - - zt, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z") - So(err, ShouldBeNil) - t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") - So(err, ShouldBeNil) - So(sec.Key("TIME").InTime(zt, []time.Time{t, time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String()) - - Convey("Get value with candidates and default value", func() { - So(sec.Key("STRING_404").In("str", []string{"str", "arr", "types"}), ShouldEqual, "str") - So(sec.Key("FLOAT64_404").InFloat64(1.25, []float64{1.25, 2.5, 3.75}), ShouldEqual, 1.25) - So(sec.Key("INT_404").InInt(10, []int{10, 20, 30}), ShouldEqual, 10) - So(sec.Key("INT64_404").InInt64(10, []int64{10, 20, 30}), ShouldEqual, 10) - So(sec.Key("UINT_404").InUint(3, []uint{3, 6, 9}), ShouldEqual, 3) - So(sec.Key("UINT_404").InUint64(3, []uint64{3, 6, 9}), ShouldEqual, 3) - So(sec.Key("TIME_404").InTime(t, []time.Time{time.Now(), time.Now(), time.Now().Add(1 * time.Second)}).String(), ShouldEqual, t.String()) - }) - }) - - Convey("Get values in range", func() { - sec := f.Section("types") - So(sec.Key("FLOAT64").RangeFloat64(0, 1, 2), ShouldEqual, 1.25) - So(sec.Key("INT").RangeInt(0, 10, 20), ShouldEqual, 10) - So(sec.Key("INT").RangeInt64(0, 10, 20), ShouldEqual, 10) - - minT, err := time.Parse(time.RFC3339, "0001-01-01T01:00:00Z") - So(err, ShouldBeNil) - midT, err := time.Parse(time.RFC3339, "2013-01-01T01:00:00Z") - So(err, ShouldBeNil) - maxT, err := time.Parse(time.RFC3339, "9999-01-01T01:00:00Z") - So(err, ShouldBeNil) - t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") - So(err, ShouldBeNil) - So(sec.Key("TIME").RangeTime(t, minT, maxT).String(), ShouldEqual, t.String()) - - Convey("Get value in range with default value", func() { - So(sec.Key("FLOAT64").RangeFloat64(5, 0, 1), ShouldEqual, 5) - So(sec.Key("INT").RangeInt(7, 0, 5), ShouldEqual, 7) - So(sec.Key("INT").RangeInt64(7, 0, 5), ShouldEqual, 7) - So(sec.Key("TIME").RangeTime(t, minT, midT).String(), ShouldEqual, t.String()) - }) - }) - - Convey("Get values into slice", func() { - sec := f.Section("array") - So(strings.Join(sec.Key("STRINGS").Strings(","), ","), ShouldEqual, "en,zh,de") - So(len(sec.Key("STRINGS_404").Strings(",")), ShouldEqual, 0) - - vals1 := sec.Key("FLOAT64S").Float64s(",") - float64sEqual(vals1, 1.1, 2.2, 3.3) - - vals2 := sec.Key("INTS").Ints(",") - intsEqual(vals2, 1, 2, 3) - - vals3 := sec.Key("INTS").Int64s(",") - int64sEqual(vals3, 1, 2, 3) - - vals4 := sec.Key("UINTS").Uints(",") - uintsEqual(vals4, 1, 2, 3) - - vals5 := sec.Key("UINTS").Uint64s(",") - uint64sEqual(vals5, 1, 2, 3) - - t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") - So(err, ShouldBeNil) - vals6 := sec.Key("TIMES").Times(",") - timesEqual(vals6, t, t, t) - }) - - Convey("Test string slice escapes", func() { - sec := f.Section("string escapes") - So(sec.Key("key1").Strings(","), ShouldResemble, []string{"value1", "value2", "value3"}) - So(sec.Key("key2").Strings(","), ShouldResemble, []string{"value1, value2"}) - So(sec.Key("key3").Strings(","), ShouldResemble, []string{`val\ue1`, "value2"}) - So(sec.Key("key4").Strings(","), ShouldResemble, []string{`value1\`, `value\\2`}) - So(sec.Key("key5").Strings(",,"), ShouldResemble, []string{"value1,, value2"}) - So(sec.Key("key6").Strings(" "), ShouldResemble, []string{"aaa", "bbb and space", "ccc"}) - }) - - Convey("Get valid values into slice", func() { - sec := f.Section("array") - vals1 := sec.Key("FLOAT64S").ValidFloat64s(",") - float64sEqual(vals1, 1.1, 2.2, 3.3) - - vals2 := sec.Key("INTS").ValidInts(",") - intsEqual(vals2, 1, 2, 3) - - vals3 := sec.Key("INTS").ValidInt64s(",") - int64sEqual(vals3, 1, 2, 3) - - vals4 := sec.Key("UINTS").ValidUints(",") - uintsEqual(vals4, 1, 2, 3) - - vals5 := sec.Key("UINTS").ValidUint64s(",") - uint64sEqual(vals5, 1, 2, 3) - - t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") - So(err, ShouldBeNil) - vals6 := sec.Key("TIMES").ValidTimes(",") - timesEqual(vals6, t, t, t) - }) - - Convey("Get values one type into slice of another type", func() { - sec := f.Section("array") - vals1 := sec.Key("STRINGS").ValidFloat64s(",") - So(vals1, ShouldBeEmpty) - - vals2 := sec.Key("STRINGS").ValidInts(",") - So(vals2, ShouldBeEmpty) - - vals3 := sec.Key("STRINGS").ValidInt64s(",") - So(vals3, ShouldBeEmpty) - - vals4 := sec.Key("STRINGS").ValidUints(",") - So(vals4, ShouldBeEmpty) - - vals5 := sec.Key("STRINGS").ValidUint64s(",") - So(vals5, ShouldBeEmpty) - - vals6 := sec.Key("STRINGS").ValidTimes(",") - So(vals6, ShouldBeEmpty) - }) - - Convey("Get valid values into slice without errors", func() { - sec := f.Section("array") - vals1, err := sec.Key("FLOAT64S").StrictFloat64s(",") - So(err, ShouldBeNil) - float64sEqual(vals1, 1.1, 2.2, 3.3) - - vals2, err := sec.Key("INTS").StrictInts(",") - So(err, ShouldBeNil) - intsEqual(vals2, 1, 2, 3) - - vals3, err := sec.Key("INTS").StrictInt64s(",") - So(err, ShouldBeNil) - int64sEqual(vals3, 1, 2, 3) - - vals4, err := sec.Key("UINTS").StrictUints(",") - So(err, ShouldBeNil) - uintsEqual(vals4, 1, 2, 3) - - vals5, err := sec.Key("UINTS").StrictUint64s(",") - So(err, ShouldBeNil) - uint64sEqual(vals5, 1, 2, 3) - - t, err := time.Parse(time.RFC3339, "2015-01-01T20:17:05Z") - So(err, ShouldBeNil) - vals6, err := sec.Key("TIMES").StrictTimes(",") - So(err, ShouldBeNil) - timesEqual(vals6, t, t, t) - }) - - Convey("Get invalid values into slice", func() { - sec := f.Section("array") - vals1, err := sec.Key("STRINGS").StrictFloat64s(",") - So(vals1, ShouldBeEmpty) - So(err, ShouldNotBeNil) - - vals2, err := sec.Key("STRINGS").StrictInts(",") - So(vals2, ShouldBeEmpty) - So(err, ShouldNotBeNil) - - vals3, err := sec.Key("STRINGS").StrictInt64s(",") - So(vals3, ShouldBeEmpty) - So(err, ShouldNotBeNil) - - vals4, err := sec.Key("STRINGS").StrictUints(",") - So(vals4, ShouldBeEmpty) - So(err, ShouldNotBeNil) - - vals5, err := sec.Key("STRINGS").StrictUint64s(",") - So(vals5, ShouldBeEmpty) - So(err, ShouldNotBeNil) - - vals6, err := sec.Key("STRINGS").StrictTimes(",") - So(vals6, ShouldBeEmpty) - So(err, ShouldNotBeNil) - }) - }) -} - -func TestKey_StringsWithShadows(t *testing.T) { - Convey("Get strings of shadows of a key", t, func() { - f, err := ini.ShadowLoad([]byte("")) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NUMS", "1,2") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("").NewKey("NUMS", "4,5,6") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - So(k.StringsWithShadows(","), ShouldResemble, []string{"1", "2", "4", "5", "6"}) - }) -} - -func TestKey_SetValue(t *testing.T) { - Convey("Set value of key", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - So(k.Value(), ShouldEqual, "ini") - - k.SetValue("ini.v1") - So(k.Value(), ShouldEqual, "ini.v1") - }) -} - -func TestKey_NestedValues(t *testing.T) { - Convey("Read and write nested values", t, func() { - f, err := ini.LoadSources(ini.LoadOptions{ - AllowNestedValues: true, - }, []byte(` -aws_access_key_id = foo -aws_secret_access_key = bar -region = us-west-2 -s3 = - max_concurrent_requests=10 - max_queue_size=1000`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("").Key("s3").NestedValues(), ShouldResemble, []string{"max_concurrent_requests=10", "max_queue_size=1000"}) - - var buf bytes.Buffer - _, err = f.WriteTo(&buf) - So(err, ShouldBeNil) - So(buf.String(), ShouldEqual, `aws_access_key_id = foo -aws_secret_access_key = bar -region = us-west-2 -s3 = - max_concurrent_requests=10 - max_queue_size=1000 - -`) - }) -} - -func TestRecursiveValues(t *testing.T) { - Convey("Recursive values should not reflect on same key", t, func() { - f, err := ini.Load([]byte(` -NAME = ini -[package] -NAME = %(NAME)s`)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - So(f.Section("package").Key("NAME").String(), ShouldEqual, "ini") - }) -} diff --git a/vendor/github.com/go-ini/ini/parser.go b/vendor/github.com/go-ini/ini/parser.go index db3af8f00..36cb3dad8 100644 --- a/vendor/github.com/go-ini/ini/parser.go +++ b/vendor/github.com/go-ini/ini/parser.go @@ -19,11 +19,14 @@ import ( "bytes" "fmt" "io" + "regexp" "strconv" "strings" "unicode" ) +var pythonMultiline = regexp.MustCompile("^(\\s+)([^\n]+)") + type tokenType int const ( @@ -97,7 +100,7 @@ func cleanComment(in []byte) ([]byte, bool) { return in[i:], true } -func readKeyName(in []byte) (string, int, error) { +func readKeyName(delimiters string, in []byte) (string, int, error) { line := string(in) // Check if key name surrounded by quotes. @@ -124,7 +127,7 @@ func readKeyName(in []byte) (string, int, error) { pos += startIdx // Find key-value delimiter - i := strings.IndexAny(line[pos+startIdx:], "=:") + i := strings.IndexAny(line[pos+startIdx:], delimiters) if i < 0 { return "", -1, ErrDelimiterNotFound{line} } @@ -132,7 +135,7 @@ func readKeyName(in []byte) (string, int, error) { return strings.TrimSpace(line[startIdx:pos]), endIdx + startIdx + 1, nil } - endIdx = strings.IndexAny(line, "=:") + endIdx = strings.IndexAny(line, delimiters) if endIdx < 0 { return "", -1, ErrDelimiterNotFound{line} } @@ -194,7 +197,8 @@ func hasSurroundedQuote(in string, quote byte) bool { } func (p *parser) readValue(in []byte, - ignoreContinuation, ignoreInlineComment, unescapeValueDoubleQuotes, unescapeValueCommentSymbols bool) (string, error) { + parserBufferSize int, + ignoreContinuation, ignoreInlineComment, unescapeValueDoubleQuotes, unescapeValueCommentSymbols, allowPythonMultilines, spaceBeforeInlineComment bool) (string, error) { line := strings.TrimLeftFunc(string(in), unicode.IsSpace) if len(line) == 0 { @@ -224,21 +228,34 @@ func (p *parser) readValue(in []byte, return line[startIdx : pos+startIdx], nil } + lastChar := line[len(line)-1] // Won't be able to reach here if value only contains whitespace line = strings.TrimSpace(line) + trimmedLastChar := line[len(line)-1] // Check continuation lines when desired - if !ignoreContinuation && line[len(line)-1] == '\\' { + if !ignoreContinuation && trimmedLastChar == '\\' { return p.readContinuationLines(line[:len(line)-1]) } // Check if ignore inline comment if !ignoreInlineComment { - i := strings.IndexAny(line, "#;") + var i int + if spaceBeforeInlineComment { + i = strings.Index(line, " #") + if i == -1 { + i = strings.Index(line, " ;") + } + + } else { + i = strings.IndexAny(line, "#;") + } + if i > -1 { p.comment.WriteString(line[i:]) line = strings.TrimSpace(line[:i]) } + } // Trim single and double quotes @@ -252,7 +269,50 @@ func (p *parser) readValue(in []byte, if strings.Contains(line, `\#`) { line = strings.Replace(line, `\#`, "#", -1) } + } else if allowPythonMultilines && lastChar == '\n' { + parserBufferPeekResult, _ := p.buf.Peek(parserBufferSize) + peekBuffer := bytes.NewBuffer(parserBufferPeekResult) + + identSize := -1 + val := line + + for { + peekData, peekErr := peekBuffer.ReadBytes('\n') + if peekErr != nil { + if peekErr == io.EOF { + return val, nil + } + return "", peekErr + } + + peekMatches := pythonMultiline.FindStringSubmatch(string(peekData)) + if len(peekMatches) != 3 { + return val, nil + } + + currentIdentSize := len(peekMatches[1]) + // NOTE: Return if not a python-ini multi-line value. + if currentIdentSize < 0 { + return val, nil + } + identSize = currentIdentSize + + // NOTE: Just advance the parser reader (buffer) in-sync with the peek buffer. + _, err := p.readUntil('\n') + if err != nil { + return "", err + } + + val += fmt.Sprintf("\n%s", peekMatches[2]) + } + + // NOTE: If it was a Python multi-line value, + // return the appended value. + if identSize > 0 { + return val, nil + } } + return line, nil } @@ -276,6 +336,28 @@ func (f *File) parse(reader io.Reader) (err error) { var line []byte var inUnparseableSection bool + + // NOTE: Iterate and increase `currentPeekSize` until + // the size of the parser buffer is found. + // TODO(unknwon): When Golang 1.10 is the lowest version supported, replace with `parserBufferSize := p.buf.Size()`. + parserBufferSize := 0 + // NOTE: Peek 1kb at a time. + currentPeekSize := 1024 + + if f.options.AllowPythonMultilineValues { + for { + peekBytes, _ := p.buf.Peek(currentPeekSize) + peekBytesLength := len(peekBytes) + + if parserBufferSize >= peekBytesLength { + break + } + + currentPeekSize *= 2 + parserBufferSize = peekBytesLength + } + } + for !p.isEOF { line, err = p.readUntil('\n') if err != nil { @@ -307,8 +389,7 @@ func (f *File) parse(reader io.Reader) (err error) { // Section if line[0] == '[' { // Read to the next ']' (TODO: support quoted strings) - // TODO(unknwon): use LastIndexByte when stop supporting Go1.4 - closeIdx := bytes.LastIndex(line, []byte("]")) + closeIdx := bytes.LastIndexByte(line, ']') if closeIdx == -1 { return fmt.Errorf("unclosed section: %s", line) } @@ -347,25 +428,34 @@ func (f *File) parse(reader io.Reader) (err error) { continue } - kname, offset, err := readKeyName(line) + kname, offset, err := readKeyName(f.options.KeyValueDelimiters, line) if err != nil { // Treat as boolean key when desired, and whole line is key name. - if IsErrDelimiterNotFound(err) && f.options.AllowBooleanKeys { - kname, err := p.readValue(line, - f.options.IgnoreContinuation, - f.options.IgnoreInlineComment, - f.options.UnescapeValueDoubleQuotes, - f.options.UnescapeValueCommentSymbols) - if err != nil { - return err - } - key, err := section.NewBooleanKey(kname) - if err != nil { - return err + if IsErrDelimiterNotFound(err) { + switch { + case f.options.AllowBooleanKeys: + kname, err := p.readValue(line, + parserBufferSize, + f.options.IgnoreContinuation, + f.options.IgnoreInlineComment, + f.options.UnescapeValueDoubleQuotes, + f.options.UnescapeValueCommentSymbols, + f.options.AllowPythonMultilineValues, + f.options.SpaceBeforeInlineComment) + if err != nil { + return err + } + key, err := section.NewBooleanKey(kname) + if err != nil { + return err + } + key.Comment = strings.TrimSpace(p.comment.String()) + p.comment.Reset() + continue + + case f.options.SkipUnrecognizableLines: + continue } - key.Comment = strings.TrimSpace(p.comment.String()) - p.comment.Reset() - continue } return err } @@ -379,10 +469,13 @@ func (f *File) parse(reader io.Reader) (err error) { } value, err := p.readValue(line[offset:], + parserBufferSize, f.options.IgnoreContinuation, f.options.IgnoreInlineComment, f.options.UnescapeValueDoubleQuotes, - f.options.UnescapeValueCommentSymbols) + f.options.UnescapeValueCommentSymbols, + f.options.AllowPythonMultilineValues, + f.options.SpaceBeforeInlineComment) if err != nil { return err } diff --git a/vendor/github.com/go-ini/ini/parser_test.go b/vendor/github.com/go-ini/ini/parser_test.go deleted file mode 100644 index bb0f2665e..000000000 --- a/vendor/github.com/go-ini/ini/parser_test.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2016 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini_test - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" - "gopkg.in/ini.v1" -) - -func TestBOM(t *testing.T) { - Convey("Test handling BOM", t, func() { - Convey("UTF-8-BOM", func() { - f, err := ini.Load("testdata/UTF-8-BOM.ini") - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.Section("author").Key("E-MAIL").String(), ShouldEqual, "u@gogs.io") - }) - - Convey("UTF-16-LE-BOM", func() { - f, err := ini.Load("testdata/UTF-16-LE-BOM.ini") - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - }) - - Convey("UTF-16-BE-BOM", func() { - }) - }) -} - -func TestBadLoad(t *testing.T) { - Convey("Load with bad data", t, func() { - Convey("Bad section name", func() { - _, err := ini.Load([]byte("[]")) - So(err, ShouldNotBeNil) - - _, err = ini.Load([]byte("[")) - So(err, ShouldNotBeNil) - }) - - Convey("Bad keys", func() { - _, err := ini.Load([]byte(`"""name`)) - So(err, ShouldNotBeNil) - - _, err = ini.Load([]byte(`"""name"""`)) - So(err, ShouldNotBeNil) - - _, err = ini.Load([]byte(`""=1`)) - So(err, ShouldNotBeNil) - - _, err = ini.Load([]byte(`=`)) - So(err, ShouldNotBeNil) - - _, err = ini.Load([]byte(`name`)) - So(err, ShouldNotBeNil) - }) - - Convey("Bad values", func() { - _, err := ini.Load([]byte(`name="""Unknwon`)) - So(err, ShouldNotBeNil) - }) - }) -} diff --git a/vendor/github.com/go-ini/ini/section.go b/vendor/github.com/go-ini/ini/section.go index d8a402619..340a1efad 100644 --- a/vendor/github.com/go-ini/ini/section.go +++ b/vendor/github.com/go-ini/ini/section.go @@ -82,6 +82,7 @@ func (s *Section) NewKey(name, val string) (*Key, error) { } } else { s.keys[name].value = val + s.keysHash[name] = val } return s.keys[name], nil } diff --git a/vendor/github.com/go-ini/ini/section_test.go b/vendor/github.com/go-ini/ini/section_test.go deleted file mode 100644 index e9c347881..000000000 --- a/vendor/github.com/go-ini/ini/section_test.go +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright 2014 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini_test - -import ( - "testing" - - . "github.com/smartystreets/goconvey/convey" - "gopkg.in/ini.v1" -) - -func TestSection_SetBody(t *testing.T) { - Convey("Set body of raw section", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - sec, err := f.NewRawSection("comments", `1111111111111111111000000000000000001110000 -111111111111111111100000000000111000000000`) - So(err, ShouldBeNil) - So(sec, ShouldNotBeNil) - So(sec.Body(), ShouldEqual, `1111111111111111111000000000000000001110000 -111111111111111111100000000000111000000000`) - - sec.SetBody("1111111111111111111000000000000000001110000") - So(sec.Body(), ShouldEqual, `1111111111111111111000000000000000001110000`) - - Convey("Set for non-raw section", func() { - sec, err := f.NewSection("author") - So(err, ShouldBeNil) - So(sec, ShouldNotBeNil) - So(sec.Body(), ShouldBeEmpty) - - sec.SetBody("1111111111111111111000000000000000001110000") - So(sec.Body(), ShouldBeEmpty) - }) - }) -} - -func TestSection_NewKey(t *testing.T) { - Convey("Create a new key", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - So(k.Name(), ShouldEqual, "NAME") - So(k.Value(), ShouldEqual, "ini") - - Convey("With duplicated name", func() { - k, err := f.Section("").NewKey("NAME", "ini.v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - // Overwrite previous existed key - So(k.Value(), ShouldEqual, "ini.v1") - }) - - Convey("With empty string", func() { - _, err := f.Section("").NewKey("", "") - So(err, ShouldNotBeNil) - }) - }) - - Convey("Create keys with same name and allow shadow", t, func() { - f, err := ini.ShadowLoad([]byte("")) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("").NewKey("NAME", "ini.v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - So(k.ValueWithShadows(), ShouldResemble, []string{"ini", "ini.v1"}) - }) -} - -func TestSection_NewBooleanKey(t *testing.T) { - Convey("Create a new boolean key", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewBooleanKey("start-ssh-server") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - So(k.Name(), ShouldEqual, "start-ssh-server") - So(k.Value(), ShouldEqual, "true") - - Convey("With empty string", func() { - _, err := f.Section("").NewBooleanKey("") - So(err, ShouldNotBeNil) - }) - }) -} - -func TestSection_GetKey(t *testing.T) { - Convey("Get a key", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - k, err = f.Section("").GetKey("NAME") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - So(k.Name(), ShouldEqual, "NAME") - So(k.Value(), ShouldEqual, "ini") - - Convey("Key not exists", func() { - _, err := f.Section("").GetKey("404") - So(err, ShouldNotBeNil) - }) - - Convey("Key exists in parent section", func() { - k, err := f.Section("parent").NewKey("AGE", "18") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - k, err = f.Section("parent.child.son").GetKey("AGE") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - So(k.Value(), ShouldEqual, "18") - }) - }) -} - -func TestSection_HasKey(t *testing.T) { - Convey("Check if a key exists", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - So(f.Section("").HasKey("NAME"), ShouldBeTrue) - So(f.Section("").Haskey("NAME"), ShouldBeTrue) - So(f.Section("").HasKey("404"), ShouldBeFalse) - So(f.Section("").Haskey("404"), ShouldBeFalse) - }) -} - -func TestSection_HasValue(t *testing.T) { - Convey("Check if contains a value in any key", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - So(f.Section("").HasValue("ini"), ShouldBeTrue) - So(f.Section("").HasValue("404"), ShouldBeFalse) - }) -} - -func TestSection_Key(t *testing.T) { - Convey("Get a key", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - k = f.Section("").Key("NAME") - So(k, ShouldNotBeNil) - So(k.Name(), ShouldEqual, "NAME") - So(k.Value(), ShouldEqual, "ini") - - Convey("Key not exists", func() { - k := f.Section("").Key("404") - So(k, ShouldNotBeNil) - So(k.Name(), ShouldEqual, "404") - }) - - Convey("Key exists in parent section", func() { - k, err := f.Section("parent").NewKey("AGE", "18") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - k = f.Section("parent.child.son").Key("AGE") - So(k, ShouldNotBeNil) - So(k.Value(), ShouldEqual, "18") - }) - }) -} - -func TestSection_Keys(t *testing.T) { - Convey("Get all keys in a section", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("").NewKey("VERSION", "v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("").NewKey("IMPORT_PATH", "gopkg.in/ini.v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - keys := f.Section("").Keys() - names := []string{"NAME", "VERSION", "IMPORT_PATH"} - So(len(keys), ShouldEqual, len(names)) - for i, name := range names { - So(keys[i].Name(), ShouldEqual, name) - } - }) -} - -func TestSection_ParentKeys(t *testing.T) { - Convey("Get all keys of parent sections", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("package").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("package").NewKey("VERSION", "v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("package").NewKey("IMPORT_PATH", "gopkg.in/ini.v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - keys := f.Section("package.sub.sub2").ParentKeys() - names := []string{"NAME", "VERSION", "IMPORT_PATH"} - So(len(keys), ShouldEqual, len(names)) - for i, name := range names { - So(keys[i].Name(), ShouldEqual, name) - } - }) -} - -func TestSection_KeyStrings(t *testing.T) { - Convey("Get all key names in a section", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("").NewKey("VERSION", "v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("").NewKey("IMPORT_PATH", "gopkg.in/ini.v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - So(f.Section("").KeyStrings(), ShouldResemble, []string{"NAME", "VERSION", "IMPORT_PATH"}) - }) -} - -func TestSection_KeyHash(t *testing.T) { - Convey("Get clone of key hash", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("").NewKey("VERSION", "v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - k, err = f.Section("").NewKey("IMPORT_PATH", "gopkg.in/ini.v1") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - hash := f.Section("").KeysHash() - relation := map[string]string{ - "NAME": "ini", - "VERSION": "v1", - "IMPORT_PATH": "gopkg.in/ini.v1", - } - for k, v := range hash { - So(v, ShouldEqual, relation[k]) - } - }) -} - -func TestSection_DeleteKey(t *testing.T) { - Convey("Delete a key", t, func() { - f := ini.Empty() - So(f, ShouldNotBeNil) - - k, err := f.Section("").NewKey("NAME", "ini") - So(err, ShouldBeNil) - So(k, ShouldNotBeNil) - - So(f.Section("").HasKey("NAME"), ShouldBeTrue) - f.Section("").DeleteKey("NAME") - So(f.Section("").HasKey("NAME"), ShouldBeFalse) - }) -} diff --git a/vendor/github.com/go-ini/ini/struct_test.go b/vendor/github.com/go-ini/ini/struct_test.go deleted file mode 100644 index 75987ea99..000000000 --- a/vendor/github.com/go-ini/ini/struct_test.go +++ /dev/null @@ -1,387 +0,0 @@ -// Copyright 2014 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package ini_test - -import ( - "bytes" - "fmt" - "strings" - "testing" - "time" - - . "github.com/smartystreets/goconvey/convey" - "gopkg.in/ini.v1" -) - -type testNested struct { - Cities []string `delim:"|"` - Visits []time.Time - Years []int - Numbers []int64 - Ages []uint - Populations []uint64 - Coordinates []float64 - Note string - Unused int `ini:"-"` -} - -type testEmbeded struct { - GPA float64 -} - -type testStruct struct { - Name string `ini:"NAME"` - Age int - Male bool - Money float64 - Born time.Time - Time time.Duration `ini:"Duration"` - Others testNested - *testEmbeded `ini:"grade"` - Unused int `ini:"-"` - Unsigned uint - Omitted bool `ini:"omitthis,omitempty"` - Shadows []string `ini:",,allowshadow"` - ShadowInts []int `ini:"Shadows,,allowshadow"` -} - -const _CONF_DATA_STRUCT = ` -NAME = Unknwon -Age = 21 -Male = true -Money = 1.25 -Born = 1993-10-07T20:17:05Z -Duration = 2h45m -Unsigned = 3 -omitthis = true -Shadows = 1, 2 -Shadows = 3, 4 - -[Others] -Cities = HangZhou|Boston -Visits = 1993-10-07T20:17:05Z, 1993-10-07T20:17:05Z -Years = 1993,1994 -Numbers = 10010,10086 -Ages = 18,19 -Populations = 12345678,98765432 -Coordinates = 192.168,10.11 -Note = Hello world! - -[grade] -GPA = 2.8 - -[foo.bar] -Here = there -When = then -` - -type unsupport struct { - Byte byte -} - -type unsupport2 struct { - Others struct { - Cities byte - } -} - -type unsupport3 struct { - Cities byte -} - -type unsupport4 struct { - *unsupport3 `ini:"Others"` -} - -type defaultValue struct { - Name string - Age int - Male bool - Money float64 - Born time.Time - Cities []string -} - -type fooBar struct { - Here, When string -} - -const _INVALID_DATA_CONF_STRUCT = ` -Name = -Age = age -Male = 123 -Money = money -Born = nil -Cities = -` - -func Test_MapToStruct(t *testing.T) { - Convey("Map to struct", t, func() { - Convey("Map file to struct", func() { - ts := new(testStruct) - So(ini.MapTo(ts, []byte(_CONF_DATA_STRUCT)), ShouldBeNil) - - So(ts.Name, ShouldEqual, "Unknwon") - So(ts.Age, ShouldEqual, 21) - So(ts.Male, ShouldBeTrue) - So(ts.Money, ShouldEqual, 1.25) - So(ts.Unsigned, ShouldEqual, 3) - - t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") - So(err, ShouldBeNil) - So(ts.Born.String(), ShouldEqual, t.String()) - - dur, err := time.ParseDuration("2h45m") - So(err, ShouldBeNil) - So(ts.Time.Seconds(), ShouldEqual, dur.Seconds()) - - So(strings.Join(ts.Others.Cities, ","), ShouldEqual, "HangZhou,Boston") - So(ts.Others.Visits[0].String(), ShouldEqual, t.String()) - So(fmt.Sprint(ts.Others.Years), ShouldEqual, "[1993 1994]") - So(fmt.Sprint(ts.Others.Numbers), ShouldEqual, "[10010 10086]") - So(fmt.Sprint(ts.Others.Ages), ShouldEqual, "[18 19]") - So(fmt.Sprint(ts.Others.Populations), ShouldEqual, "[12345678 98765432]") - So(fmt.Sprint(ts.Others.Coordinates), ShouldEqual, "[192.168 10.11]") - So(ts.Others.Note, ShouldEqual, "Hello world!") - So(ts.testEmbeded.GPA, ShouldEqual, 2.8) - }) - - Convey("Map section to struct", func() { - foobar := new(fooBar) - f, err := ini.Load([]byte(_CONF_DATA_STRUCT)) - So(err, ShouldBeNil) - - So(f.Section("foo.bar").MapTo(foobar), ShouldBeNil) - So(foobar.Here, ShouldEqual, "there") - So(foobar.When, ShouldEqual, "then") - }) - - Convey("Map to non-pointer struct", func() { - f, err := ini.Load([]byte(_CONF_DATA_STRUCT)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - So(f.MapTo(testStruct{}), ShouldNotBeNil) - }) - - Convey("Map to unsupported type", func() { - f, err := ini.Load([]byte(_CONF_DATA_STRUCT)) - So(err, ShouldBeNil) - So(f, ShouldNotBeNil) - - f.NameMapper = func(raw string) string { - if raw == "Byte" { - return "NAME" - } - return raw - } - So(f.MapTo(&unsupport{}), ShouldNotBeNil) - So(f.MapTo(&unsupport2{}), ShouldNotBeNil) - So(f.MapTo(&unsupport4{}), ShouldNotBeNil) - }) - - Convey("Map to omitempty field", func() { - ts := new(testStruct) - So(ini.MapTo(ts, []byte(_CONF_DATA_STRUCT)), ShouldBeNil) - - So(ts.Omitted, ShouldEqual, true) - }) - - Convey("Map with shadows", func() { - f, err := ini.LoadSources(ini.LoadOptions{AllowShadows: true}, []byte(_CONF_DATA_STRUCT)) - So(err, ShouldBeNil) - ts := new(testStruct) - So(f.MapTo(ts), ShouldBeNil) - - So(strings.Join(ts.Shadows, " "), ShouldEqual, "1 2 3 4") - So(fmt.Sprintf("%v", ts.ShadowInts), ShouldEqual, "[1 2 3 4]") - }) - - Convey("Map from invalid data source", func() { - So(ini.MapTo(&testStruct{}, "hi"), ShouldNotBeNil) - }) - - Convey("Map to wrong types and gain default values", func() { - f, err := ini.Load([]byte(_INVALID_DATA_CONF_STRUCT)) - So(err, ShouldBeNil) - - t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") - So(err, ShouldBeNil) - dv := &defaultValue{"Joe", 10, true, 1.25, t, []string{"HangZhou", "Boston"}} - So(f.MapTo(dv), ShouldBeNil) - So(dv.Name, ShouldEqual, "Joe") - So(dv.Age, ShouldEqual, 10) - So(dv.Male, ShouldBeTrue) - So(dv.Money, ShouldEqual, 1.25) - So(dv.Born.String(), ShouldEqual, t.String()) - So(strings.Join(dv.Cities, ","), ShouldEqual, "HangZhou,Boston") - }) - }) - - Convey("Map to struct in strict mode", t, func() { - f, err := ini.Load([]byte(` -name=bruce -age=a30`)) - So(err, ShouldBeNil) - - type Strict struct { - Name string `ini:"name"` - Age int `ini:"age"` - } - s := new(Strict) - - So(f.Section("").StrictMapTo(s), ShouldNotBeNil) - }) - - Convey("Map slice in strict mode", t, func() { - f, err := ini.Load([]byte(` -names=alice, bruce`)) - So(err, ShouldBeNil) - - type Strict struct { - Names []string `ini:"names"` - } - s := new(Strict) - - So(f.Section("").StrictMapTo(s), ShouldBeNil) - So(fmt.Sprint(s.Names), ShouldEqual, "[alice bruce]") - }) -} - -func Test_ReflectFromStruct(t *testing.T) { - Convey("Reflect from struct", t, func() { - type Embeded struct { - Dates []time.Time `delim:"|" comment:"Time data"` - Places []string - Years []int - Numbers []int64 - Ages []uint - Populations []uint64 - Coordinates []float64 - None []int - } - type Author struct { - Name string `ini:"NAME"` - Male bool - Age int `comment:"Author's age"` - Height uint - GPA float64 - Date time.Time - NeverMind string `ini:"-"` - *Embeded `ini:"infos" comment:"Embeded section"` - } - - t, err := time.Parse(time.RFC3339, "1993-10-07T20:17:05Z") - So(err, ShouldBeNil) - a := &Author{"Unknwon", true, 21, 100, 2.8, t, "", - &Embeded{ - []time.Time{t, t}, - []string{"HangZhou", "Boston"}, - []int{1993, 1994}, - []int64{10010, 10086}, - []uint{18, 19}, - []uint64{12345678, 98765432}, - []float64{192.168, 10.11}, - []int{}, - }} - cfg := ini.Empty() - So(ini.ReflectFrom(cfg, a), ShouldBeNil) - - var buf bytes.Buffer - _, err = cfg.WriteTo(&buf) - So(err, ShouldBeNil) - So(buf.String(), ShouldEqual, `NAME = Unknwon -Male = true -; Author's age -Age = 21 -Height = 100 -GPA = 2.8 -Date = 1993-10-07T20:17:05Z - -; Embeded section -[infos] -; Time data -Dates = 1993-10-07T20:17:05Z|1993-10-07T20:17:05Z -Places = HangZhou,Boston -Years = 1993,1994 -Numbers = 10010,10086 -Ages = 18,19 -Populations = 12345678,98765432 -Coordinates = 192.168,10.11 -None = - -`) - - Convey("Reflect from non-point struct", func() { - So(ini.ReflectFrom(cfg, Author{}), ShouldNotBeNil) - }) - - Convey("Reflect from struct with omitempty", func() { - cfg := ini.Empty() - type SpecialStruct struct { - FirstName string `ini:"first_name"` - LastName string `ini:"last_name"` - JustOmitMe string `ini:"omitempty"` - LastLogin time.Time `ini:"last_login,omitempty"` - LastLogin2 time.Time `ini:",omitempty"` - NotEmpty int `ini:"omitempty"` - } - - So(ini.ReflectFrom(cfg, &SpecialStruct{FirstName: "John", LastName: "Doe", NotEmpty: 9}), ShouldBeNil) - - var buf bytes.Buffer - _, err = cfg.WriteTo(&buf) - So(buf.String(), ShouldEqual, `first_name = John -last_name = Doe -omitempty = 9 - -`) - }) - }) -} - -type testMapper struct { - PackageName string -} - -func Test_NameGetter(t *testing.T) { - Convey("Test name mappers", t, func() { - So(ini.MapToWithMapper(&testMapper{}, ini.TitleUnderscore, []byte("packag_name=ini")), ShouldBeNil) - - cfg, err := ini.Load([]byte("PACKAGE_NAME=ini")) - So(err, ShouldBeNil) - So(cfg, ShouldNotBeNil) - - cfg.NameMapper = ini.AllCapsUnderscore - tg := new(testMapper) - So(cfg.MapTo(tg), ShouldBeNil) - So(tg.PackageName, ShouldEqual, "ini") - }) -} - -type testDurationStruct struct { - Duration time.Duration `ini:"Duration"` -} - -func Test_Duration(t *testing.T) { - Convey("Duration less than 16m50s", t, func() { - ds := new(testDurationStruct) - So(ini.MapTo(ds, []byte("Duration=16m49s")), ShouldBeNil) - - dur, err := time.ParseDuration("16m49s") - So(err, ShouldBeNil) - So(ds.Duration.Seconds(), ShouldEqual, dur.Seconds()) - }) -} diff --git a/vendor/github.com/go-ini/ini/testdata/UTF-16-BE-BOM.ini b/vendor/github.com/go-ini/ini/testdata/UTF-16-BE-BOM.ini deleted file mode 100644 index c8bf82c8f..000000000 Binary files a/vendor/github.com/go-ini/ini/testdata/UTF-16-BE-BOM.ini and /dev/null differ diff --git a/vendor/github.com/go-ini/ini/testdata/UTF-16-LE-BOM.ini b/vendor/github.com/go-ini/ini/testdata/UTF-16-LE-BOM.ini deleted file mode 100644 index 27f62186e..000000000 Binary files a/vendor/github.com/go-ini/ini/testdata/UTF-16-LE-BOM.ini and /dev/null differ diff --git a/vendor/github.com/go-ini/ini/testdata/UTF-8-BOM.ini b/vendor/github.com/go-ini/ini/testdata/UTF-8-BOM.ini deleted file mode 100644 index 2ed0ac1d3..000000000 --- a/vendor/github.com/go-ini/ini/testdata/UTF-8-BOM.ini +++ /dev/null @@ -1,2 +0,0 @@ -[author] -E-MAIL = u@gogs.io \ No newline at end of file diff --git a/vendor/github.com/go-ini/ini/testdata/full.ini b/vendor/github.com/go-ini/ini/testdata/full.ini deleted file mode 100644 index 469b1f13e..000000000 --- a/vendor/github.com/go-ini/ini/testdata/full.ini +++ /dev/null @@ -1,83 +0,0 @@ -; Package name -NAME = ini -; Package version -VERSION = v1 -; Package import path -IMPORT_PATH = gopkg.in/%(NAME)s.%(VERSION)s - -# Information about package author -# Bio can be written in multiple lines. -[author] -NAME = Unknwon -E-MAIL = u@gogs.io -GITHUB = https://github.com/%(NAME)s -BIO = """Gopher. -Coding addict. -Good man. -""" # Succeeding comment - -[package] -CLONE_URL = https://%(IMPORT_PATH)s - -[package.sub] -UNUSED_KEY = should be deleted - -[features] --: Support read/write comments of keys and sections --: Support auto-increment of key names --: Support load multiple files to overwrite key values - -[types] -STRING = str -BOOL = true -BOOL_FALSE = false -FLOAT64 = 1.25 -INT = 10 -TIME = 2015-01-01T20:17:05Z -DURATION = 2h45m -UINT = 3 - -[array] -STRINGS = en, zh, de -FLOAT64S = 1.1, 2.2, 3.3 -INTS = 1, 2, 3 -UINTS = 1, 2, 3 -TIMES = 2015-01-01T20:17:05Z,2015-01-01T20:17:05Z,2015-01-01T20:17:05Z - -[note] -empty_lines = next line is empty\ - -; Comment before the section -[comments] ; This is a comment for the section too -; Comment before key -key = "value" -key2 = "value2" ; This is a comment for key2 -key3 = "one", "two", "three" - -[string escapes] -key1 = value1, value2, value3 -key2 = value1\, value2 -key3 = val\ue1, value2 -key4 = value1\\, value\\\\2 -key5 = value1\,, value2 -key6 = aaa bbb\ and\ space ccc - -[advance] -value with quotes = "some value" -value quote2 again = 'some value' -includes comment sign = `my#password` -includes comment sign2 = `my;password` -true = 2+3=5 -"1+1=2" = true -"""6+1=7""" = true -"""`5+5`""" = 10 -`"6+6"` = 12 -`7-2=4` = false -ADDRESS = `404 road, -NotFound, State, 50000` -two_lines = how about \ - continuation lines? -lots_of_lines = 1 \ - 2 \ - 3 \ - 4 \ diff --git a/vendor/github.com/go-ini/ini/testdata/minimal.ini b/vendor/github.com/go-ini/ini/testdata/minimal.ini deleted file mode 100644 index f8e7ec89f..000000000 --- a/vendor/github.com/go-ini/ini/testdata/minimal.ini +++ /dev/null @@ -1,2 +0,0 @@ -[author] -E-MAIL = u@gogs.io \ No newline at end of file diff --git a/vendor/github.com/go-ole/go-ole/LICENSE b/vendor/github.com/go-ole/go-ole/LICENSE new file mode 100644 index 000000000..623ec06f9 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright © 2013-2017 Yasuhiro Matsumoto, + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-ole/com.go b/vendor/github.com/go-ole/go-ole/com.go similarity index 50% rename from vendor/github.com/mattn/go-ole/com.go rename to vendor/github.com/go-ole/go-ole/com.go index e596b0c66..75ebbf13f 100644 --- a/vendor/github.com/mattn/go-ole/com.go +++ b/vendor/github.com/go-ole/go-ole/com.go @@ -3,38 +3,50 @@ package ole import ( + "errors" "syscall" + "time" "unicode/utf16" "unsafe" ) var ( - procCoInitialize, _ = modole32.FindProc("CoInitialize") - procCoInitializeEx, _ = modole32.FindProc("CoInitializeEx") - procCoUninitialize, _ = modole32.FindProc("CoUninitialize") - procCoCreateInstance, _ = modole32.FindProc("CoCreateInstance") - procCoTaskMemFree, _ = modole32.FindProc("CoTaskMemFree") - procCLSIDFromProgID, _ = modole32.FindProc("CLSIDFromProgID") - procCLSIDFromString, _ = modole32.FindProc("CLSIDFromString") - procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID") - procStringFromIID, _ = modole32.FindProc("StringFromIID") - procIIDFromString, _ = modole32.FindProc("IIDFromString") - procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID") - procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory") - procVariantInit, _ = modoleaut32.FindProc("VariantInit") - procVariantClear, _ = modoleaut32.FindProc("VariantClear") - procSysAllocString, _ = modoleaut32.FindProc("SysAllocString") - procSysAllocStringLen, _ = modoleaut32.FindProc("SysAllocStringLen") - procSysFreeString, _ = modoleaut32.FindProc("SysFreeString") - procSysStringLen, _ = modoleaut32.FindProc("SysStringLen") - procCreateDispTypeInfo, _ = modoleaut32.FindProc("CreateDispTypeInfo") - procCreateStdDispatch, _ = modoleaut32.FindProc("CreateStdDispatch") - procGetActiveObject, _ = modoleaut32.FindProc("GetActiveObject") + procCoInitialize, _ = modole32.FindProc("CoInitialize") + procCoInitializeEx, _ = modole32.FindProc("CoInitializeEx") + procCoUninitialize, _ = modole32.FindProc("CoUninitialize") + procCoCreateInstance, _ = modole32.FindProc("CoCreateInstance") + procCoTaskMemFree, _ = modole32.FindProc("CoTaskMemFree") + procCLSIDFromProgID, _ = modole32.FindProc("CLSIDFromProgID") + procCLSIDFromString, _ = modole32.FindProc("CLSIDFromString") + procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID") + procStringFromIID, _ = modole32.FindProc("StringFromIID") + procIIDFromString, _ = modole32.FindProc("IIDFromString") + procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID") + procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory") + procVariantInit, _ = modoleaut32.FindProc("VariantInit") + procVariantClear, _ = modoleaut32.FindProc("VariantClear") + procVariantTimeToSystemTime, _ = modoleaut32.FindProc("VariantTimeToSystemTime") + procSysAllocString, _ = modoleaut32.FindProc("SysAllocString") + procSysAllocStringLen, _ = modoleaut32.FindProc("SysAllocStringLen") + procSysFreeString, _ = modoleaut32.FindProc("SysFreeString") + procSysStringLen, _ = modoleaut32.FindProc("SysStringLen") + procCreateDispTypeInfo, _ = modoleaut32.FindProc("CreateDispTypeInfo") + procCreateStdDispatch, _ = modoleaut32.FindProc("CreateStdDispatch") + procGetActiveObject, _ = modoleaut32.FindProc("GetActiveObject") procGetMessageW, _ = moduser32.FindProc("GetMessageW") procDispatchMessageW, _ = moduser32.FindProc("DispatchMessageW") ) +// coInitialize initializes COM library on current thread. +// +// MSDN documentation suggests that this function should not be called. Call +// CoInitializeEx() instead. The reason has to do with threading and this +// function is only for single-threaded apartments. +// +// That said, most users of the library have gotten away with just this +// function. If you are experiencing threading issues, then use +// CoInitializeEx(). func coInitialize() (err error) { // http://msdn.microsoft.com/en-us/library/windows/desktop/ms678543(v=vs.85).aspx // Suggests that no value should be passed to CoInitialized. @@ -46,6 +58,7 @@ func coInitialize() (err error) { return } +// coInitializeEx initializes COM library with concurrency model. func coInitializeEx(coinit uint32) (err error) { // http://msdn.microsoft.com/en-us/library/windows/desktop/ms695279(v=vs.85).aspx // Suggests that the first parameter is not only optional but should always be NULL. @@ -56,6 +69,15 @@ func coInitializeEx(coinit uint32) (err error) { return } +// CoInitialize initializes COM library on current thread. +// +// MSDN documentation suggests that this function should not be called. Call +// CoInitializeEx() instead. The reason has to do with threading and this +// function is only for single-threaded apartments. +// +// That said, most users of the library have gotten away with just this +// function. If you are experiencing threading issues, then use +// CoInitializeEx(). func CoInitialize(p uintptr) (err error) { // p is ignored and won't be used. // Avoid any variable not used errors. @@ -63,20 +85,36 @@ func CoInitialize(p uintptr) (err error) { return coInitialize() } +// CoInitializeEx initializes COM library with concurrency model. func CoInitializeEx(p uintptr, coinit uint32) (err error) { // Avoid any variable not used errors. p = uintptr(0) return coInitializeEx(coinit) } +// CoUninitialize uninitializes COM Library. func CoUninitialize() { procCoUninitialize.Call() } +// CoTaskMemFree frees memory pointer. func CoTaskMemFree(memptr uintptr) { procCoTaskMemFree.Call(memptr) } +// CLSIDFromProgID retrieves Class Identifier with the given Program Identifier. +// +// The Programmatic Identifier must be registered, because it will be looked up +// in the Windows Registry. The registry entry has the following keys: CLSID, +// Insertable, Protocol and Shell +// (https://msdn.microsoft.com/en-us/library/dd542719(v=vs.85).aspx). +// +// programID identifies the class id with less precision and is not guaranteed +// to be unique. These are usually found in the registry under +// HKEY_LOCAL_MACHINE\SOFTWARE\Classes, usually with the format of +// "Program.Component.Version" with version being optional. +// +// CLSIDFromProgID in Windows API. func CLSIDFromProgID(progId string) (clsid *GUID, err error) { var guid GUID lpszProgID := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(progId))) @@ -88,6 +126,12 @@ func CLSIDFromProgID(progId string) (clsid *GUID, err error) { return } +// CLSIDFromString retrieves Class ID from string representation. +// +// This is technically the string version of the GUID and will convert the +// string to object. +// +// CLSIDFromString in Windows API. func CLSIDFromString(str string) (clsid *GUID, err error) { var guid GUID lpsz := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) @@ -99,6 +143,7 @@ func CLSIDFromString(str string) (clsid *GUID, err error) { return } +// StringFromCLSID returns GUID formated string from GUID object. func StringFromCLSID(clsid *GUID) (str string, err error) { var p *uint16 hr, _, _ := procStringFromCLSID.Call(uintptr(unsafe.Pointer(clsid)), uintptr(unsafe.Pointer(&p))) @@ -109,6 +154,7 @@ func StringFromCLSID(clsid *GUID) (str string, err error) { return } +// IIDFromString returns GUID from program ID. func IIDFromString(progId string) (clsid *GUID, err error) { var guid GUID lpsz := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(progId))) @@ -120,6 +166,7 @@ func IIDFromString(progId string) (clsid *GUID, err error) { return } +// StringFromIID returns GUID formatted string from GUID object. func StringFromIID(iid *GUID) (str string, err error) { var p *uint16 hr, _, _ := procStringFromIID.Call(uintptr(unsafe.Pointer(iid)), uintptr(unsafe.Pointer(&p))) @@ -130,6 +177,7 @@ func StringFromIID(iid *GUID) (str string, err error) { return } +// CreateInstance of single uninitialized object with GUID. func CreateInstance(clsid *GUID, iid *GUID) (unk *IUnknown, err error) { if iid == nil { iid = IID_IUnknown @@ -146,6 +194,7 @@ func CreateInstance(clsid *GUID, iid *GUID) (unk *IUnknown, err error) { return } +// GetActiveObject retrieves pointer to active object. func GetActiveObject(clsid *GUID, iid *GUID) (unk *IUnknown, err error) { if iid == nil { iid = IID_IUnknown @@ -160,6 +209,7 @@ func GetActiveObject(clsid *GUID, iid *GUID) (unk *IUnknown, err error) { return } +// VariantInit initializes variant. func VariantInit(v *VARIANT) (err error) { hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v))) if hr != 0 { @@ -168,6 +218,7 @@ func VariantInit(v *VARIANT) (err error) { return } +// VariantClear clears value in Variant settings to VT_EMPTY. func VariantClear(v *VARIANT) (err error) { hr, _, _ := procVariantClear.Call(uintptr(unsafe.Pointer(v))) if hr != 0 { @@ -176,12 +227,14 @@ func VariantClear(v *VARIANT) (err error) { return } +// SysAllocString allocates memory for string and copies string into memory. func SysAllocString(v string) (ss *int16) { pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v)))) ss = (*int16)(unsafe.Pointer(pss)) return } +// SysAllocStringLen copies up to length of given string returning pointer. func SysAllocStringLen(v string) (ss *int16) { utf16 := utf16.Encode([]rune(v + "\x00")) ptr := &utf16[0] @@ -191,6 +244,7 @@ func SysAllocStringLen(v string) (ss *int16) { return } +// SysFreeString frees string system memory. This must be called with SysAllocString. func SysFreeString(v *int16) (err error) { hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v))) if hr != 0 { @@ -199,11 +253,17 @@ func SysFreeString(v *int16) (err error) { return } +// SysStringLen is the length of the system allocated string. func SysStringLen(v *int16) uint32 { l, _, _ := procSysStringLen.Call(uintptr(unsafe.Pointer(v))) return uint32(l) } +// CreateStdDispatch provides default IDispatch implementation for IUnknown. +// +// This handles default IDispatch implementation for objects. It haves a few +// limitations with only supporting one language. It will also only return +// default exception codes. func CreateStdDispatch(unk *IUnknown, v uintptr, ptinfo *IUnknown) (disp *IDispatch, err error) { hr, _, _ := procCreateStdDispatch.Call( uintptr(unsafe.Pointer(unk)), @@ -216,6 +276,9 @@ func CreateStdDispatch(unk *IUnknown, v uintptr, ptinfo *IUnknown) (disp *IDispa return } +// CreateDispTypeInfo provides default ITypeInfo implementation for IDispatch. +// +// This will not handle the full implementation of the interface. func CreateDispTypeInfo(idata *INTERFACEDATA) (pptinfo *IUnknown, err error) { hr, _, _ := procCreateDispTypeInfo.Call( uintptr(unsafe.Pointer(idata)), @@ -227,24 +290,40 @@ func CreateDispTypeInfo(idata *INTERFACEDATA) (pptinfo *IUnknown, err error) { return } +// copyMemory moves location of a block of memory. func copyMemory(dest unsafe.Pointer, src unsafe.Pointer, length uint32) { procCopyMemory.Call(uintptr(dest), uintptr(src), uintptr(length)) } +// GetUserDefaultLCID retrieves current user default locale. func GetUserDefaultLCID() (lcid uint32) { ret, _, _ := procGetUserDefaultLCID.Call() lcid = uint32(ret) return } +// GetMessage in message queue from runtime. +// +// This function appears to block. PeekMessage does not block. func GetMessage(msg *Msg, hwnd uint32, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) { r0, _, err := procGetMessageW.Call(uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax)) ret = int32(r0) return } +// DispatchMessage to window procedure. func DispatchMessage(msg *Msg) (ret int32) { r0, _, _ := procDispatchMessageW.Call(uintptr(unsafe.Pointer(msg))) ret = int32(r0) return } + +// GetVariantDate converts COM Variant Time value to Go time.Time. +func GetVariantDate(value float64) (time.Time, error) { + var st syscall.Systemtime + r, _, _ := procVariantTimeToSystemTime.Call(uintptr(value), uintptr(unsafe.Pointer(&st))) + if r != 0 { + return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil + } + return time.Now(), errors.New("Could not convert to time, passing current time.") +} diff --git a/vendor/github.com/go-ole/go-ole/com_func.go b/vendor/github.com/go-ole/go-ole/com_func.go new file mode 100644 index 000000000..425aad323 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/com_func.go @@ -0,0 +1,174 @@ +// +build !windows + +package ole + +import ( + "time" + "unsafe" +) + +// coInitialize initializes COM library on current thread. +// +// MSDN documentation suggests that this function should not be called. Call +// CoInitializeEx() instead. The reason has to do with threading and this +// function is only for single-threaded apartments. +// +// That said, most users of the library have gotten away with just this +// function. If you are experiencing threading issues, then use +// CoInitializeEx(). +func coInitialize() error { + return NewError(E_NOTIMPL) +} + +// coInitializeEx initializes COM library with concurrency model. +func coInitializeEx(coinit uint32) error { + return NewError(E_NOTIMPL) +} + +// CoInitialize initializes COM library on current thread. +// +// MSDN documentation suggests that this function should not be called. Call +// CoInitializeEx() instead. The reason has to do with threading and this +// function is only for single-threaded apartments. +// +// That said, most users of the library have gotten away with just this +// function. If you are experiencing threading issues, then use +// CoInitializeEx(). +func CoInitialize(p uintptr) error { + return NewError(E_NOTIMPL) +} + +// CoInitializeEx initializes COM library with concurrency model. +func CoInitializeEx(p uintptr, coinit uint32) error { + return NewError(E_NOTIMPL) +} + +// CoUninitialize uninitializes COM Library. +func CoUninitialize() {} + +// CoTaskMemFree frees memory pointer. +func CoTaskMemFree(memptr uintptr) {} + +// CLSIDFromProgID retrieves Class Identifier with the given Program Identifier. +// +// The Programmatic Identifier must be registered, because it will be looked up +// in the Windows Registry. The registry entry has the following keys: CLSID, +// Insertable, Protocol and Shell +// (https://msdn.microsoft.com/en-us/library/dd542719(v=vs.85).aspx). +// +// programID identifies the class id with less precision and is not guaranteed +// to be unique. These are usually found in the registry under +// HKEY_LOCAL_MACHINE\SOFTWARE\Classes, usually with the format of +// "Program.Component.Version" with version being optional. +// +// CLSIDFromProgID in Windows API. +func CLSIDFromProgID(progId string) (*GUID, error) { + return nil, NewError(E_NOTIMPL) +} + +// CLSIDFromString retrieves Class ID from string representation. +// +// This is technically the string version of the GUID and will convert the +// string to object. +// +// CLSIDFromString in Windows API. +func CLSIDFromString(str string) (*GUID, error) { + return nil, NewError(E_NOTIMPL) +} + +// StringFromCLSID returns GUID formated string from GUID object. +func StringFromCLSID(clsid *GUID) (string, error) { + return "", NewError(E_NOTIMPL) +} + +// IIDFromString returns GUID from program ID. +func IIDFromString(progId string) (*GUID, error) { + return nil, NewError(E_NOTIMPL) +} + +// StringFromIID returns GUID formatted string from GUID object. +func StringFromIID(iid *GUID) (string, error) { + return "", NewError(E_NOTIMPL) +} + +// CreateInstance of single uninitialized object with GUID. +func CreateInstance(clsid *GUID, iid *GUID) (*IUnknown, error) { + return nil, NewError(E_NOTIMPL) +} + +// GetActiveObject retrieves pointer to active object. +func GetActiveObject(clsid *GUID, iid *GUID) (*IUnknown, error) { + return nil, NewError(E_NOTIMPL) +} + +// VariantInit initializes variant. +func VariantInit(v *VARIANT) error { + return NewError(E_NOTIMPL) +} + +// VariantClear clears value in Variant settings to VT_EMPTY. +func VariantClear(v *VARIANT) error { + return NewError(E_NOTIMPL) +} + +// SysAllocString allocates memory for string and copies string into memory. +func SysAllocString(v string) *int16 { + u := int16(0) + return &u +} + +// SysAllocStringLen copies up to length of given string returning pointer. +func SysAllocStringLen(v string) *int16 { + u := int16(0) + return &u +} + +// SysFreeString frees string system memory. This must be called with SysAllocString. +func SysFreeString(v *int16) error { + return NewError(E_NOTIMPL) +} + +// SysStringLen is the length of the system allocated string. +func SysStringLen(v *int16) uint32 { + return uint32(0) +} + +// CreateStdDispatch provides default IDispatch implementation for IUnknown. +// +// This handles default IDispatch implementation for objects. It haves a few +// limitations with only supporting one language. It will also only return +// default exception codes. +func CreateStdDispatch(unk *IUnknown, v uintptr, ptinfo *IUnknown) (*IDispatch, error) { + return nil, NewError(E_NOTIMPL) +} + +// CreateDispTypeInfo provides default ITypeInfo implementation for IDispatch. +// +// This will not handle the full implementation of the interface. +func CreateDispTypeInfo(idata *INTERFACEDATA) (*IUnknown, error) { + return nil, NewError(E_NOTIMPL) +} + +// copyMemory moves location of a block of memory. +func copyMemory(dest unsafe.Pointer, src unsafe.Pointer, length uint32) {} + +// GetUserDefaultLCID retrieves current user default locale. +func GetUserDefaultLCID() uint32 { + return uint32(0) +} + +// GetMessage in message queue from runtime. +// +// This function appears to block. PeekMessage does not block. +func GetMessage(msg *Msg, hwnd uint32, MsgFilterMin uint32, MsgFilterMax uint32) (int32, error) { + return int32(0), NewError(E_NOTIMPL) +} + +// DispatchMessage to window procedure. +func DispatchMessage(msg *Msg) int32 { + return int32(0) +} + +func GetVariantDate(value float64) (time.Time, error) { + return time.Now(), NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/mattn/go-ole/connect.go b/vendor/github.com/go-ole/go-ole/connect.go similarity index 77% rename from vendor/github.com/mattn/go-ole/connect.go rename to vendor/github.com/go-ole/go-ole/connect.go index 6a1979640..b2ac2ec67 100644 --- a/vendor/github.com/mattn/go-ole/connect.go +++ b/vendor/github.com/go-ole/go-ole/connect.go @@ -1,22 +1,23 @@ -// Helpers for COM -// -// +build windows - package ole +// Connection contains IUnknown for fluent interface interaction. +// +// Deprecated. Use oleutil package instead. type Connection struct { Object *IUnknown // Access COM } +// Initialize COM. func (*Connection) Initialize() (err error) { return coInitialize() } +// Uninitialize COM. func (*Connection) Uninitialize() { CoUninitialize() } -// Creates Unknown object based first on ProgId and then from String. +// Create IUnknown object based first on ProgId and then from String. func (c *Connection) Create(progId string) (err error) { var clsid *GUID clsid, err = CLSIDFromProgID(progId) @@ -36,11 +37,12 @@ func (c *Connection) Create(progId string) (err error) { return } +// Release IUnknown object. func (c *Connection) Release() { c.Object.Release() } -// Loads COM object if in list +// Load COM object from list of programIDs or strings. func (c *Connection) Load(names ...string) (errors []error) { var tempErrors []error = make([]error, len(names)) var numErrors int = 0 @@ -58,6 +60,7 @@ func (c *Connection) Load(names ...string) (errors []error) { return } +// Dispatch returns Dispatch object. func (c *Connection) Dispatch() (object *Dispatch, err error) { dispatch, err := c.Object.QueryInterface(IID_IDispatch) if err != nil { @@ -67,10 +70,12 @@ func (c *Connection) Dispatch() (object *Dispatch, err error) { return } +// Dispatch stores IDispatch object. type Dispatch struct { Object *IDispatch // Dispatch object. } +// Call method on IDispatch with parameters. func (d *Dispatch) Call(method string, params ...interface{}) (result *VARIANT, err error) { id, err := d.GetId(method) if err != nil { @@ -81,6 +86,7 @@ func (d *Dispatch) Call(method string, params ...interface{}) (result *VARIANT, return } +// MustCall method on IDispatch with parameters. func (d *Dispatch) MustCall(method string, params ...interface{}) (result *VARIANT) { id, err := d.GetId(method) if err != nil { @@ -95,6 +101,7 @@ func (d *Dispatch) MustCall(method string, params ...interface{}) (result *VARIA return } +// Get property on IDispatch with parameters. func (d *Dispatch) Get(name string, params ...interface{}) (result *VARIANT, err error) { id, err := d.GetId(name) if err != nil { @@ -104,6 +111,7 @@ func (d *Dispatch) Get(name string, params ...interface{}) (result *VARIANT, err return } +// MustGet property on IDispatch with parameters. func (d *Dispatch) MustGet(name string, params ...interface{}) (result *VARIANT) { id, err := d.GetId(name) if err != nil { @@ -117,6 +125,7 @@ func (d *Dispatch) MustGet(name string, params ...interface{}) (result *VARIANT) return } +// Set property on IDispatch with parameters. func (d *Dispatch) Set(name string, params ...interface{}) (result *VARIANT, err error) { id, err := d.GetId(name) if err != nil { @@ -126,6 +135,7 @@ func (d *Dispatch) Set(name string, params ...interface{}) (result *VARIANT, err return } +// MustSet property on IDispatch with parameters. func (d *Dispatch) MustSet(name string, params ...interface{}) (result *VARIANT) { id, err := d.GetId(name) if err != nil { @@ -139,6 +149,7 @@ func (d *Dispatch) MustSet(name string, params ...interface{}) (result *VARIANT) return } +// GetId retrieves ID of name on IDispatch. func (d *Dispatch) GetId(name string) (id int32, err error) { var dispid []int32 dispid, err = d.Object.GetIDsOfName([]string{name}) @@ -149,13 +160,16 @@ func (d *Dispatch) GetId(name string) (id int32, err error) { return } +// GetIds retrieves all IDs of names on IDispatch. func (d *Dispatch) GetIds(names ...string) (dispid []int32, err error) { dispid, err = d.Object.GetIDsOfName(names) return } -// There have been problems where if send cascading params..., it would error out because the -// parameters would be empty. +// Invoke IDispatch on DisplayID of dispatch type with parameters. +// +// There have been problems where if send cascading params..., it would error +// out because the parameters would be empty. func (d *Dispatch) Invoke(id int32, dispatch int16, params []interface{}) (result *VARIANT, err error) { if len(params) < 1 { result, err = d.Object.Invoke(id, dispatch) @@ -165,10 +179,12 @@ func (d *Dispatch) Invoke(id int32, dispatch int16, params []interface{}) (resul return } +// Release IDispatch object. func (d *Dispatch) Release() { d.Object.Release() } +// Connect initializes COM and attempts to load IUnknown based on given names. func Connect(names ...string) (connection *Connection) { connection.Initialize() connection.Load(names...) diff --git a/vendor/github.com/mattn/go-ole/constants.go b/vendor/github.com/go-ole/go-ole/constants.go similarity index 99% rename from vendor/github.com/mattn/go-ole/constants.go rename to vendor/github.com/go-ole/go-ole/constants.go index cc9dc2f2c..fd0c6d74b 100644 --- a/vendor/github.com/mattn/go-ole/constants.go +++ b/vendor/github.com/go-ole/go-ole/constants.go @@ -1,5 +1,3 @@ -// +build windows - package ole const ( diff --git a/vendor/github.com/go-ole/go-ole/error.go b/vendor/github.com/go-ole/go-ole/error.go new file mode 100644 index 000000000..096b456d3 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/error.go @@ -0,0 +1,51 @@ +package ole + +// OleError stores COM errors. +type OleError struct { + hr uintptr + description string + subError error +} + +// NewError creates new error with HResult. +func NewError(hr uintptr) *OleError { + return &OleError{hr: hr} +} + +// NewErrorWithDescription creates new COM error with HResult and description. +func NewErrorWithDescription(hr uintptr, description string) *OleError { + return &OleError{hr: hr, description: description} +} + +// NewErrorWithSubError creates new COM error with parent error. +func NewErrorWithSubError(hr uintptr, description string, err error) *OleError { + return &OleError{hr: hr, description: description, subError: err} +} + +// Code is the HResult. +func (v *OleError) Code() uintptr { + return uintptr(v.hr) +} + +// String description, either manually set or format message with error code. +func (v *OleError) String() string { + if v.description != "" { + return errstr(int(v.hr)) + " (" + v.description + ")" + } + return errstr(int(v.hr)) +} + +// Error implements error interface. +func (v *OleError) Error() string { + return v.String() +} + +// Description retrieves error summary, if there is one. +func (v *OleError) Description() string { + return v.description +} + +// SubError returns parent error, if there is one. +func (v *OleError) SubError() error { + return v.subError +} diff --git a/vendor/github.com/go-ole/go-ole/error_func.go b/vendor/github.com/go-ole/go-ole/error_func.go new file mode 100644 index 000000000..8a2ffaa27 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/error_func.go @@ -0,0 +1,8 @@ +// +build !windows + +package ole + +// errstr converts error code to string. +func errstr(errno int) string { + return "" +} diff --git a/vendor/github.com/go-ole/go-ole/error_windows.go b/vendor/github.com/go-ole/go-ole/error_windows.go new file mode 100644 index 000000000..d0e8e6859 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/error_windows.go @@ -0,0 +1,24 @@ +// +build windows + +package ole + +import ( + "fmt" + "syscall" + "unicode/utf16" +) + +// errstr converts error code to string. +func errstr(errno int) string { + // ask windows for the remaining errors + var flags uint32 = syscall.FORMAT_MESSAGE_FROM_SYSTEM | syscall.FORMAT_MESSAGE_ARGUMENT_ARRAY | syscall.FORMAT_MESSAGE_IGNORE_INSERTS + b := make([]uint16, 300) + n, err := syscall.FormatMessage(flags, 0, uint32(errno), 0, b, nil) + if err != nil { + return fmt.Sprintf("error %d (FormatMessage failed with: %v)", errno, err) + } + // trim terminating \r and \n + for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- { + } + return string(utf16.Decode(b[:n])) +} diff --git a/vendor/github.com/go-ole/go-ole/guid.go b/vendor/github.com/go-ole/go-ole/guid.go new file mode 100644 index 000000000..8d20f68fb --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/guid.go @@ -0,0 +1,284 @@ +package ole + +var ( + // IID_NULL is null Interface ID, used when no other Interface ID is known. + IID_NULL = NewGUID("{00000000-0000-0000-0000-000000000000}") + + // IID_IUnknown is for IUnknown interfaces. + IID_IUnknown = NewGUID("{00000000-0000-0000-C000-000000000046}") + + // IID_IDispatch is for IDispatch interfaces. + IID_IDispatch = NewGUID("{00020400-0000-0000-C000-000000000046}") + + // IID_IEnumVariant is for IEnumVariant interfaces + IID_IEnumVariant = NewGUID("{00020404-0000-0000-C000-000000000046}") + + // IID_IConnectionPointContainer is for IConnectionPointContainer interfaces. + IID_IConnectionPointContainer = NewGUID("{B196B284-BAB4-101A-B69C-00AA00341D07}") + + // IID_IConnectionPoint is for IConnectionPoint interfaces. + IID_IConnectionPoint = NewGUID("{B196B286-BAB4-101A-B69C-00AA00341D07}") + + // IID_IInspectable is for IInspectable interfaces. + IID_IInspectable = NewGUID("{AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90}") + + // IID_IProvideClassInfo is for IProvideClassInfo interfaces. + IID_IProvideClassInfo = NewGUID("{B196B283-BAB4-101A-B69C-00AA00341D07}") +) + +// These are for testing and not part of any library. +var ( + // IID_ICOMTestString is for ICOMTestString interfaces. + // + // {E0133EB4-C36F-469A-9D3D-C66B84BE19ED} + IID_ICOMTestString = NewGUID("{E0133EB4-C36F-469A-9D3D-C66B84BE19ED}") + + // IID_ICOMTestInt8 is for ICOMTestInt8 interfaces. + // + // {BEB06610-EB84-4155-AF58-E2BFF53680B4} + IID_ICOMTestInt8 = NewGUID("{BEB06610-EB84-4155-AF58-E2BFF53680B4}") + + // IID_ICOMTestInt16 is for ICOMTestInt16 interfaces. + // + // {DAA3F9FA-761E-4976-A860-8364CE55F6FC} + IID_ICOMTestInt16 = NewGUID("{DAA3F9FA-761E-4976-A860-8364CE55F6FC}") + + // IID_ICOMTestInt32 is for ICOMTestInt32 interfaces. + // + // {E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0} + IID_ICOMTestInt32 = NewGUID("{E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}") + + // IID_ICOMTestInt64 is for ICOMTestInt64 interfaces. + // + // {8D437CBC-B3ED-485C-BC32-C336432A1623} + IID_ICOMTestInt64 = NewGUID("{8D437CBC-B3ED-485C-BC32-C336432A1623}") + + // IID_ICOMTestFloat is for ICOMTestFloat interfaces. + // + // {BF1ED004-EA02-456A-AA55-2AC8AC6B054C} + IID_ICOMTestFloat = NewGUID("{BF1ED004-EA02-456A-AA55-2AC8AC6B054C}") + + // IID_ICOMTestDouble is for ICOMTestDouble interfaces. + // + // {BF908A81-8687-4E93-999F-D86FAB284BA0} + IID_ICOMTestDouble = NewGUID("{BF908A81-8687-4E93-999F-D86FAB284BA0}") + + // IID_ICOMTestBoolean is for ICOMTestBoolean interfaces. + // + // {D530E7A6-4EE8-40D1-8931-3D63B8605010} + IID_ICOMTestBoolean = NewGUID("{D530E7A6-4EE8-40D1-8931-3D63B8605010}") + + // IID_ICOMEchoTestObject is for ICOMEchoTestObject interfaces. + // + // {6485B1EF-D780-4834-A4FE-1EBB51746CA3} + IID_ICOMEchoTestObject = NewGUID("{6485B1EF-D780-4834-A4FE-1EBB51746CA3}") + + // IID_ICOMTestTypes is for ICOMTestTypes interfaces. + // + // {CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0} + IID_ICOMTestTypes = NewGUID("{CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}") + + // CLSID_COMEchoTestObject is for COMEchoTestObject class. + // + // {3C24506A-AE9E-4D50-9157-EF317281F1B0} + CLSID_COMEchoTestObject = NewGUID("{3C24506A-AE9E-4D50-9157-EF317281F1B0}") + + // CLSID_COMTestScalarClass is for COMTestScalarClass class. + // + // {865B85C5-0334-4AC6-9EF6-AACEC8FC5E86} + CLSID_COMTestScalarClass = NewGUID("{865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}") +) + +const hextable = "0123456789ABCDEF" +const emptyGUID = "{00000000-0000-0000-0000-000000000000}" + +// GUID is Windows API specific GUID type. +// +// This exists to match Windows GUID type for direct passing for COM. +// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx. +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} + +// NewGUID converts the given string into a globally unique identifier that is +// compliant with the Windows API. +// +// The supplied string may be in any of these formats: +// +// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX +// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} +// +// The conversion of the supplied string is not case-sensitive. +func NewGUID(guid string) *GUID { + d := []byte(guid) + var d1, d2, d3, d4a, d4b []byte + + switch len(d) { + case 38: + if d[0] != '{' || d[37] != '}' { + return nil + } + d = d[1:37] + fallthrough + case 36: + if d[8] != '-' || d[13] != '-' || d[18] != '-' || d[23] != '-' { + return nil + } + d1 = d[0:8] + d2 = d[9:13] + d3 = d[14:18] + d4a = d[19:23] + d4b = d[24:36] + case 32: + d1 = d[0:8] + d2 = d[8:12] + d3 = d[12:16] + d4a = d[16:20] + d4b = d[20:32] + default: + return nil + } + + var g GUID + var ok1, ok2, ok3, ok4 bool + g.Data1, ok1 = decodeHexUint32(d1) + g.Data2, ok2 = decodeHexUint16(d2) + g.Data3, ok3 = decodeHexUint16(d3) + g.Data4, ok4 = decodeHexByte64(d4a, d4b) + if ok1 && ok2 && ok3 && ok4 { + return &g + } + return nil +} + +func decodeHexUint32(src []byte) (value uint32, ok bool) { + var b1, b2, b3, b4 byte + var ok1, ok2, ok3, ok4 bool + b1, ok1 = decodeHexByte(src[0], src[1]) + b2, ok2 = decodeHexByte(src[2], src[3]) + b3, ok3 = decodeHexByte(src[4], src[5]) + b4, ok4 = decodeHexByte(src[6], src[7]) + value = (uint32(b1) << 24) | (uint32(b2) << 16) | (uint32(b3) << 8) | uint32(b4) + ok = ok1 && ok2 && ok3 && ok4 + return +} + +func decodeHexUint16(src []byte) (value uint16, ok bool) { + var b1, b2 byte + var ok1, ok2 bool + b1, ok1 = decodeHexByte(src[0], src[1]) + b2, ok2 = decodeHexByte(src[2], src[3]) + value = (uint16(b1) << 8) | uint16(b2) + ok = ok1 && ok2 + return +} + +func decodeHexByte64(s1 []byte, s2 []byte) (value [8]byte, ok bool) { + var ok1, ok2, ok3, ok4, ok5, ok6, ok7, ok8 bool + value[0], ok1 = decodeHexByte(s1[0], s1[1]) + value[1], ok2 = decodeHexByte(s1[2], s1[3]) + value[2], ok3 = decodeHexByte(s2[0], s2[1]) + value[3], ok4 = decodeHexByte(s2[2], s2[3]) + value[4], ok5 = decodeHexByte(s2[4], s2[5]) + value[5], ok6 = decodeHexByte(s2[6], s2[7]) + value[6], ok7 = decodeHexByte(s2[8], s2[9]) + value[7], ok8 = decodeHexByte(s2[10], s2[11]) + ok = ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8 + return +} + +func decodeHexByte(c1, c2 byte) (value byte, ok bool) { + var n1, n2 byte + var ok1, ok2 bool + n1, ok1 = decodeHexChar(c1) + n2, ok2 = decodeHexChar(c2) + value = (n1 << 4) | n2 + ok = ok1 && ok2 + return +} + +func decodeHexChar(c byte) (byte, bool) { + switch { + case '0' <= c && c <= '9': + return c - '0', true + case 'a' <= c && c <= 'f': + return c - 'a' + 10, true + case 'A' <= c && c <= 'F': + return c - 'A' + 10, true + } + + return 0, false +} + +// String converts the GUID to string form. It will adhere to this pattern: +// +// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} +// +// If the GUID is nil, the string representation of an empty GUID is returned: +// +// {00000000-0000-0000-0000-000000000000} +func (guid *GUID) String() string { + if guid == nil { + return emptyGUID + } + + var c [38]byte + c[0] = '{' + putUint32Hex(c[1:9], guid.Data1) + c[9] = '-' + putUint16Hex(c[10:14], guid.Data2) + c[14] = '-' + putUint16Hex(c[15:19], guid.Data3) + c[19] = '-' + putByteHex(c[20:24], guid.Data4[0:2]) + c[24] = '-' + putByteHex(c[25:37], guid.Data4[2:8]) + c[37] = '}' + return string(c[:]) +} + +func putUint32Hex(b []byte, v uint32) { + b[0] = hextable[byte(v>>24)>>4] + b[1] = hextable[byte(v>>24)&0x0f] + b[2] = hextable[byte(v>>16)>>4] + b[3] = hextable[byte(v>>16)&0x0f] + b[4] = hextable[byte(v>>8)>>4] + b[5] = hextable[byte(v>>8)&0x0f] + b[6] = hextable[byte(v)>>4] + b[7] = hextable[byte(v)&0x0f] +} + +func putUint16Hex(b []byte, v uint16) { + b[0] = hextable[byte(v>>8)>>4] + b[1] = hextable[byte(v>>8)&0x0f] + b[2] = hextable[byte(v)>>4] + b[3] = hextable[byte(v)&0x0f] +} + +func putByteHex(dst, src []byte) { + for i := 0; i < len(src); i++ { + dst[i*2] = hextable[src[i]>>4] + dst[i*2+1] = hextable[src[i]&0x0f] + } +} + +// IsEqualGUID compares two GUID. +// +// Not constant time comparison. +func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool { + return guid1.Data1 == guid2.Data1 && + guid1.Data2 == guid2.Data2 && + guid1.Data3 == guid2.Data3 && + guid1.Data4[0] == guid2.Data4[0] && + guid1.Data4[1] == guid2.Data4[1] && + guid1.Data4[2] == guid2.Data4[2] && + guid1.Data4[3] == guid2.Data4[3] && + guid1.Data4[4] == guid2.Data4[4] && + guid1.Data4[5] == guid2.Data4[5] && + guid1.Data4[6] == guid2.Data4[6] && + guid1.Data4[7] == guid2.Data4[7] +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpoint.go b/vendor/github.com/go-ole/go-ole/iconnectionpoint.go new file mode 100644 index 000000000..9e6c49f41 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpoint.go @@ -0,0 +1,20 @@ +package ole + +import "unsafe" + +type IConnectionPoint struct { + IUnknown +} + +type IConnectionPointVtbl struct { + IUnknownVtbl + GetConnectionInterface uintptr + GetConnectionPointContainer uintptr + Advise uintptr + Unadvise uintptr + EnumConnections uintptr +} + +func (v *IConnectionPoint) VTable() *IConnectionPointVtbl { + return (*IConnectionPointVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpoint_func.go b/vendor/github.com/go-ole/go-ole/iconnectionpoint_func.go new file mode 100644 index 000000000..5414dc3cd --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpoint_func.go @@ -0,0 +1,21 @@ +// +build !windows + +package ole + +import "unsafe" + +func (v *IConnectionPoint) GetConnectionInterface(piid **GUID) int32 { + return int32(0) +} + +func (v *IConnectionPoint) Advise(unknown *IUnknown) (uint32, error) { + return uint32(0), NewError(E_NOTIMPL) +} + +func (v *IConnectionPoint) Unadvise(cookie uint32) error { + return NewError(E_NOTIMPL) +} + +func (v *IConnectionPoint) EnumConnections(p *unsafe.Pointer) (err error) { + return NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/mattn/go-ole/iconnectionpoint.go b/vendor/github.com/go-ole/go-ole/iconnectionpoint_windows.go similarity index 62% rename from vendor/github.com/mattn/go-ole/iconnectionpoint.go rename to vendor/github.com/go-ole/go-ole/iconnectionpoint_windows.go index 40969b83c..32bc18324 100644 --- a/vendor/github.com/mattn/go-ole/iconnectionpoint.go +++ b/vendor/github.com/go-ole/go-ole/iconnectionpoint_windows.go @@ -7,23 +7,6 @@ import ( "unsafe" ) -type IConnectionPoint struct { - IUnknown -} - -type IConnectionPointVtbl struct { - IUnknownVtbl - GetConnectionInterface uintptr - GetConnectionPointContainer uintptr - Advise uintptr - Unadvise uintptr - EnumConnections uintptr -} - -func (v *IConnectionPoint) VTable() *IConnectionPointVtbl { - return (*IConnectionPointVtbl)(unsafe.Pointer(v.RawVTable)) -} - func (v *IConnectionPoint) GetConnectionInterface(piid **GUID) int32 { // XXX: This doesn't look like it does what it's supposed to return release((*IUnknown)(unsafe.Pointer(v))) @@ -55,6 +38,6 @@ func (v *IConnectionPoint) Unadvise(cookie uint32) (err error) { return } -func (v *IConnectionPoint) EnumConnections(p *unsafe.Pointer) (err error) { +func (v *IConnectionPoint) EnumConnections(p *unsafe.Pointer) error { return NewError(E_NOTIMPL) } diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer.go b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer.go new file mode 100644 index 000000000..165860d19 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer.go @@ -0,0 +1,17 @@ +package ole + +import "unsafe" + +type IConnectionPointContainer struct { + IUnknown +} + +type IConnectionPointContainerVtbl struct { + IUnknownVtbl + EnumConnectionPoints uintptr + FindConnectionPoint uintptr +} + +func (v *IConnectionPointContainer) VTable() *IConnectionPointContainerVtbl { + return (*IConnectionPointContainerVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_func.go b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_func.go new file mode 100644 index 000000000..5dfa42aae --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_func.go @@ -0,0 +1,11 @@ +// +build !windows + +package ole + +func (v *IConnectionPointContainer) EnumConnectionPoints(points interface{}) error { + return NewError(E_NOTIMPL) +} + +func (v *IConnectionPointContainer) FindConnectionPoint(iid *GUID, point **IConnectionPoint) error { + return NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/mattn/go-ole/iconnectionpointcontainer.go b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_windows.go similarity index 53% rename from vendor/github.com/mattn/go-ole/iconnectionpointcontainer.go rename to vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_windows.go index a24eea362..ad30d79ef 100644 --- a/vendor/github.com/mattn/go-ole/iconnectionpointcontainer.go +++ b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_windows.go @@ -7,23 +7,8 @@ import ( "unsafe" ) -type IConnectionPointContainer struct { - IUnknown -} - -type IConnectionPointContainerVtbl struct { - IUnknownVtbl - EnumConnectionPoints uintptr - FindConnectionPoint uintptr -} - -func (v *IConnectionPointContainer) VTable() *IConnectionPointContainerVtbl { - return (*IConnectionPointContainerVtbl)(unsafe.Pointer(v.RawVTable)) -} - -func (v *IConnectionPointContainer) EnumConnectionPoints(points interface{}) (err error) { - err = NewError(E_NOTIMPL) - return +func (v *IConnectionPointContainer) EnumConnectionPoints(points interface{}) error { + return NewError(E_NOTIMPL) } func (v *IConnectionPointContainer) FindConnectionPoint(iid *GUID, point **IConnectionPoint) (err error) { diff --git a/vendor/github.com/go-ole/go-ole/idispatch.go b/vendor/github.com/go-ole/go-ole/idispatch.go new file mode 100644 index 000000000..d4af12409 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/idispatch.go @@ -0,0 +1,94 @@ +package ole + +import "unsafe" + +type IDispatch struct { + IUnknown +} + +type IDispatchVtbl struct { + IUnknownVtbl + GetTypeInfoCount uintptr + GetTypeInfo uintptr + GetIDsOfNames uintptr + Invoke uintptr +} + +func (v *IDispatch) VTable() *IDispatchVtbl { + return (*IDispatchVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IDispatch) GetIDsOfName(names []string) (dispid []int32, err error) { + dispid, err = getIDsOfName(v, names) + return +} + +func (v *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) (result *VARIANT, err error) { + result, err = invoke(v, dispid, dispatch, params...) + return +} + +func (v *IDispatch) GetTypeInfoCount() (c uint32, err error) { + c, err = getTypeInfoCount(v) + return +} + +func (v *IDispatch) GetTypeInfo() (tinfo *ITypeInfo, err error) { + tinfo, err = getTypeInfo(v) + return +} + +// GetSingleIDOfName is a helper that returns single display ID for IDispatch name. +// +// This replaces the common pattern of attempting to get a single name from the list of available +// IDs. It gives the first ID, if it is available. +func (v *IDispatch) GetSingleIDOfName(name string) (displayID int32, err error) { + var displayIDs []int32 + displayIDs, err = v.GetIDsOfName([]string{name}) + if err != nil { + return + } + displayID = displayIDs[0] + return +} + +// InvokeWithOptionalArgs accepts arguments as an array, works like Invoke. +// +// Accepts name and will attempt to retrieve Display ID to pass to Invoke. +// +// Passing params as an array is a workaround that could be fixed in later versions of Go that +// prevent passing empty params. During testing it was discovered that this is an acceptable way of +// getting around not being able to pass params normally. +func (v *IDispatch) InvokeWithOptionalArgs(name string, dispatch int16, params []interface{}) (result *VARIANT, err error) { + displayID, err := v.GetSingleIDOfName(name) + if err != nil { + return + } + + if len(params) < 1 { + result, err = v.Invoke(displayID, dispatch) + } else { + result, err = v.Invoke(displayID, dispatch, params...) + } + + return +} + +// CallMethod invokes named function with arguments on object. +func (v *IDispatch) CallMethod(name string, params ...interface{}) (*VARIANT, error) { + return v.InvokeWithOptionalArgs(name, DISPATCH_METHOD, params) +} + +// GetProperty retrieves the property with the name with the ability to pass arguments. +// +// Most of the time you will not need to pass arguments as most objects do not allow for this +// feature. Or at least, should not allow for this feature. Some servers don't follow best practices +// and this is provided for those edge cases. +func (v *IDispatch) GetProperty(name string, params ...interface{}) (*VARIANT, error) { + return v.InvokeWithOptionalArgs(name, DISPATCH_PROPERTYGET, params) +} + +// PutProperty attempts to mutate a property in the object. +func (v *IDispatch) PutProperty(name string, params ...interface{}) (*VARIANT, error) { + return v.InvokeWithOptionalArgs(name, DISPATCH_PROPERTYPUT, params) +} diff --git a/vendor/github.com/go-ole/go-ole/idispatch_func.go b/vendor/github.com/go-ole/go-ole/idispatch_func.go new file mode 100644 index 000000000..b8fbbe319 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/idispatch_func.go @@ -0,0 +1,19 @@ +// +build !windows + +package ole + +func getIDsOfName(disp *IDispatch, names []string) ([]int32, error) { + return []int32{}, NewError(E_NOTIMPL) +} + +func getTypeInfoCount(disp *IDispatch) (uint32, error) { + return uint32(0), NewError(E_NOTIMPL) +} + +func getTypeInfo(disp *IDispatch) (*ITypeInfo, error) { + return nil, NewError(E_NOTIMPL) +} + +func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (*VARIANT, error) { + return nil, NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/mattn/go-ole/idispatch.go b/vendor/github.com/go-ole/go-ole/idispatch_windows.go similarity index 79% rename from vendor/github.com/mattn/go-ole/idispatch.go rename to vendor/github.com/go-ole/go-ole/idispatch_windows.go index 391a566ef..020e4f51b 100644 --- a/vendor/github.com/mattn/go-ole/idispatch.go +++ b/vendor/github.com/go-ole/go-ole/idispatch_windows.go @@ -8,42 +8,6 @@ import ( "unsafe" ) -type IDispatch struct { - IUnknown -} - -type IDispatchVtbl struct { - IUnknownVtbl - GetTypeInfoCount uintptr - GetTypeInfo uintptr - GetIDsOfNames uintptr - Invoke uintptr -} - -func (v *IDispatch) VTable() *IDispatchVtbl { - return (*IDispatchVtbl)(unsafe.Pointer(v.RawVTable)) -} - -func (v *IDispatch) GetIDsOfName(names []string) (dispid []int32, err error) { - dispid, err = getIDsOfName(v, names) - return -} - -func (v *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) (result *VARIANT, err error) { - result, err = invoke(v, dispid, dispatch, params...) - return -} - -func (v *IDispatch) GetTypeInfoCount() (c uint32, err error) { - c, err = getTypeInfoCount(v) - return -} - -func (v *IDispatch) GetTypeInfo() (tinfo *ITypeInfo, err error) { - tinfo, err = getTypeInfo(v) - return -} - func getIDsOfName(disp *IDispatch, names []string) (dispid []int32, err error) { wnames := make([]*uint16, len(names)) for i := 0; i < len(names); i++ { @@ -99,6 +63,10 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{} dispnames := [1]int32{DISPID_PROPERTYPUT} dispparams.rgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0])) dispparams.cNamedArgs = 1 + } else if dispatch&DISPATCH_PROPERTYPUTREF != 0 { + dispnames := [1]int32{DISPID_PROPERTYPUT} + dispparams.rgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0])) + dispparams.cNamedArgs = 1 } var vargs []VARIANT if len(params) > 0 { @@ -116,10 +84,14 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{} } case *bool: vargs[n] = NewVariant(VT_BOOL|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*bool))))) - case byte: - vargs[n] = NewVariant(VT_I1, int64(v.(byte))) - case *byte: - vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*byte))))) + case uint8: + vargs[n] = NewVariant(VT_I1, int64(v.(uint8))) + case *uint8: + vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint8))))) + case int8: + vargs[n] = NewVariant(VT_I1, int64(v.(int8))) + case *int8: + vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint8))))) case int16: vargs[n] = NewVariant(VT_I2, int64(v.(int16))) case *int16: @@ -128,22 +100,30 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{} vargs[n] = NewVariant(VT_UI2, int64(v.(uint16))) case *uint16: vargs[n] = NewVariant(VT_UI2|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint16))))) - case int, int32: - vargs[n] = NewVariant(VT_I4, int64(v.(int))) - case *int, *int32: - vargs[n] = NewVariant(VT_I4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int))))) - case uint, uint32: - vargs[n] = NewVariant(VT_UI4, int64(v.(uint))) - case *uint, *uint32: - vargs[n] = NewVariant(VT_UI4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint))))) + case int32: + vargs[n] = NewVariant(VT_I4, int64(v.(int32))) + case *int32: + vargs[n] = NewVariant(VT_I4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int32))))) + case uint32: + vargs[n] = NewVariant(VT_UI4, int64(v.(uint32))) + case *uint32: + vargs[n] = NewVariant(VT_UI4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint32))))) case int64: vargs[n] = NewVariant(VT_I8, int64(v.(int64))) case *int64: vargs[n] = NewVariant(VT_I8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int64))))) case uint64: - vargs[n] = NewVariant(VT_UI8, v.(int64)) + vargs[n] = NewVariant(VT_UI8, int64(uintptr(v.(uint64)))) case *uint64: vargs[n] = NewVariant(VT_UI8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint64))))) + case int: + vargs[n] = NewVariant(VT_I4, int64(v.(int))) + case *int: + vargs[n] = NewVariant(VT_I4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int))))) + case uint: + vargs[n] = NewVariant(VT_UI4, int64(v.(uint))) + case *uint: + vargs[n] = NewVariant(VT_UI4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint))))) case float32: vargs[n] = NewVariant(VT_R4, *(*int64)(unsafe.Pointer(&vv))) case *float32: @@ -174,6 +154,10 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{} safeByteArray := safeArrayFromByteSlice(v.([]byte)) vargs[n] = NewVariant(VT_ARRAY|VT_UI1, int64(uintptr(unsafe.Pointer(safeByteArray)))) defer VariantClear(&vargs[n]) + case []string: + safeByteArray := safeArrayFromStringSlice(v.([]string)) + vargs[n] = NewVariant(VT_ARRAY|VT_BSTR, int64(uintptr(unsafe.Pointer(safeByteArray)))) + defer VariantClear(&vargs[n]) default: panic("unknown type") } @@ -200,17 +184,14 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{} if hr != 0 { err = NewErrorWithSubError(hr, BstrToString(excepInfo.bstrDescription), excepInfo) } - for _, varg := range vargs { + for i, varg := range vargs { + n := len(params) - i - 1 if varg.VT == VT_BSTR && varg.Val != 0 { SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val))))) } - /* - if varg.VT == (VT_BSTR|VT_BYREF) && varg.Val != 0 { - *(params[n].(*string)) = LpOleStrToString((*uint16)(unsafe.Pointer(uintptr(varg.Val)))) - println(*(params[n].(*string))) - fmt.Fprintln(os.Stderr, *(params[n].(*string))) - } - */ + if varg.VT == (VT_BSTR|VT_BYREF) && varg.Val != 0 { + *(params[n].(*string)) = LpOleStrToString(*(**uint16)(unsafe.Pointer(uintptr(varg.Val)))) + } } return } diff --git a/vendor/github.com/go-ole/go-ole/ienumvariant.go b/vendor/github.com/go-ole/go-ole/ienumvariant.go new file mode 100644 index 000000000..243389754 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/ienumvariant.go @@ -0,0 +1,19 @@ +package ole + +import "unsafe" + +type IEnumVARIANT struct { + IUnknown +} + +type IEnumVARIANTVtbl struct { + IUnknownVtbl + Next uintptr + Skip uintptr + Reset uintptr + Clone uintptr +} + +func (v *IEnumVARIANT) VTable() *IEnumVARIANTVtbl { + return (*IEnumVARIANTVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/ienumvariant_func.go b/vendor/github.com/go-ole/go-ole/ienumvariant_func.go new file mode 100644 index 000000000..c14848199 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/ienumvariant_func.go @@ -0,0 +1,19 @@ +// +build !windows + +package ole + +func (enum *IEnumVARIANT) Clone() (*IEnumVARIANT, error) { + return nil, NewError(E_NOTIMPL) +} + +func (enum *IEnumVARIANT) Reset() error { + return NewError(E_NOTIMPL) +} + +func (enum *IEnumVARIANT) Skip(celt uint) error { + return NewError(E_NOTIMPL) +} + +func (enum *IEnumVARIANT) Next(celt uint) (VARIANT, uint, error) { + return NewVariant(VT_NULL, int64(0)), 0, NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/ienumvariant_windows.go b/vendor/github.com/go-ole/go-ole/ienumvariant_windows.go new file mode 100644 index 000000000..4781f3b8b --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/ienumvariant_windows.go @@ -0,0 +1,63 @@ +// +build windows + +package ole + +import ( + "syscall" + "unsafe" +) + +func (enum *IEnumVARIANT) Clone() (cloned *IEnumVARIANT, err error) { + hr, _, _ := syscall.Syscall( + enum.VTable().Clone, + 2, + uintptr(unsafe.Pointer(enum)), + uintptr(unsafe.Pointer(&cloned)), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} + +func (enum *IEnumVARIANT) Reset() (err error) { + hr, _, _ := syscall.Syscall( + enum.VTable().Reset, + 1, + uintptr(unsafe.Pointer(enum)), + 0, + 0) + if hr != 0 { + err = NewError(hr) + } + return +} + +func (enum *IEnumVARIANT) Skip(celt uint) (err error) { + hr, _, _ := syscall.Syscall( + enum.VTable().Skip, + 2, + uintptr(unsafe.Pointer(enum)), + uintptr(celt), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} + +func (enum *IEnumVARIANT) Next(celt uint) (array VARIANT, length uint, err error) { + hr, _, _ := syscall.Syscall6( + enum.VTable().Next, + 4, + uintptr(unsafe.Pointer(enum)), + uintptr(celt), + uintptr(unsafe.Pointer(&array)), + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/iinspectable.go b/vendor/github.com/go-ole/go-ole/iinspectable.go new file mode 100644 index 000000000..f4a19e253 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iinspectable.go @@ -0,0 +1,18 @@ +package ole + +import "unsafe" + +type IInspectable struct { + IUnknown +} + +type IInspectableVtbl struct { + IUnknownVtbl + GetIIds uintptr + GetRuntimeClassName uintptr + GetTrustLevel uintptr +} + +func (v *IInspectable) VTable() *IInspectableVtbl { + return (*IInspectableVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/iinspectable_func.go b/vendor/github.com/go-ole/go-ole/iinspectable_func.go new file mode 100644 index 000000000..348829bf0 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iinspectable_func.go @@ -0,0 +1,15 @@ +// +build !windows + +package ole + +func (v *IInspectable) GetIids() ([]*GUID, error) { + return []*GUID{}, NewError(E_NOTIMPL) +} + +func (v *IInspectable) GetRuntimeClassName() (string, error) { + return "", NewError(E_NOTIMPL) +} + +func (v *IInspectable) GetTrustLevel() (uint32, error) { + return uint32(0), NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/mattn/go-ole/iinspectable.go b/vendor/github.com/go-ole/go-ole/iinspectable_windows.go similarity index 81% rename from vendor/github.com/mattn/go-ole/iinspectable.go rename to vendor/github.com/go-ole/go-ole/iinspectable_windows.go index 531ebde01..4519a4aa4 100644 --- a/vendor/github.com/mattn/go-ole/iinspectable.go +++ b/vendor/github.com/go-ole/go-ole/iinspectable_windows.go @@ -10,21 +10,6 @@ import ( "unsafe" ) -type IInspectable struct { - IUnknown -} - -type IInspectableVtbl struct { - IUnknownVtbl - GetIIds uintptr - GetRuntimeClassName uintptr - GetTrustLevel uintptr -} - -func (v *IInspectable) VTable() *IInspectableVtbl { - return (*IInspectableVtbl)(unsafe.Pointer(v.RawVTable)) -} - func (v *IInspectable) GetIids() (iids []*GUID, err error) { var count uint32 var array uintptr @@ -45,7 +30,7 @@ func (v *IInspectable) GetIids() (iids []*GUID, err error) { slicehdr := reflect.SliceHeader{Data: array, Len: int(byteCount), Cap: int(byteCount)} byteSlice := *(*[]byte)(unsafe.Pointer(&slicehdr)) reader := bytes.NewReader(byteSlice) - for i, _ := range iids { + for i := range iids { guid := GUID{} err = binary.Read(reader, binary.LittleEndian, &guid) if err != nil { diff --git a/vendor/github.com/mattn/go-ole/iprovideclassinfo.go b/vendor/github.com/go-ole/go-ole/iprovideclassinfo.go similarity index 54% rename from vendor/github.com/mattn/go-ole/iprovideclassinfo.go rename to vendor/github.com/go-ole/go-ole/iprovideclassinfo.go index 38812c199..25f3a6f24 100644 --- a/vendor/github.com/mattn/go-ole/iprovideclassinfo.go +++ b/vendor/github.com/go-ole/go-ole/iprovideclassinfo.go @@ -1,11 +1,6 @@ -// +build windows - package ole -import ( - "syscall" - "unsafe" -) +import "unsafe" type IProvideClassInfo struct { IUnknown @@ -24,16 +19,3 @@ func (v *IProvideClassInfo) GetClassInfo() (cinfo *ITypeInfo, err error) { cinfo, err = getClassInfo(v) return } - -func getClassInfo(disp *IProvideClassInfo) (tinfo *ITypeInfo, err error) { - hr, _, _ := syscall.Syscall( - disp.VTable().GetClassInfo, - 2, - uintptr(unsafe.Pointer(disp)), - uintptr(unsafe.Pointer(&tinfo)), - 0) - if hr != 0 { - err = NewError(hr) - } - return -} diff --git a/vendor/github.com/go-ole/go-ole/iprovideclassinfo_func.go b/vendor/github.com/go-ole/go-ole/iprovideclassinfo_func.go new file mode 100644 index 000000000..7e3cb63ea --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iprovideclassinfo_func.go @@ -0,0 +1,7 @@ +// +build !windows + +package ole + +func getClassInfo(disp *IProvideClassInfo) (tinfo *ITypeInfo, err error) { + return nil, NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/iprovideclassinfo_windows.go b/vendor/github.com/go-ole/go-ole/iprovideclassinfo_windows.go new file mode 100644 index 000000000..2ad016394 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iprovideclassinfo_windows.go @@ -0,0 +1,21 @@ +// +build windows + +package ole + +import ( + "syscall" + "unsafe" +) + +func getClassInfo(disp *IProvideClassInfo) (tinfo *ITypeInfo, err error) { + hr, _, _ := syscall.Syscall( + disp.VTable().GetClassInfo, + 2, + uintptr(unsafe.Pointer(disp)), + uintptr(unsafe.Pointer(&tinfo)), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/mattn/go-ole/itypeinfo.go b/vendor/github.com/go-ole/go-ole/itypeinfo.go similarity index 71% rename from vendor/github.com/mattn/go-ole/itypeinfo.go rename to vendor/github.com/go-ole/go-ole/itypeinfo.go index efb089ab9..dd3c5e21b 100644 --- a/vendor/github.com/mattn/go-ole/itypeinfo.go +++ b/vendor/github.com/go-ole/go-ole/itypeinfo.go @@ -1,11 +1,6 @@ -// +build windows - package ole -import ( - "syscall" - "unsafe" -) +import "unsafe" type ITypeInfo struct { IUnknown @@ -37,16 +32,3 @@ type ITypeInfoVtbl struct { func (v *ITypeInfo) VTable() *ITypeInfoVtbl { return (*ITypeInfoVtbl)(unsafe.Pointer(v.RawVTable)) } - -func (v *ITypeInfo) GetTypeAttr() (tattr *TYPEATTR, err error) { - hr, _, _ := syscall.Syscall( - uintptr(v.VTable().GetTypeAttr), - 2, - uintptr(unsafe.Pointer(v)), - uintptr(unsafe.Pointer(&tattr)), - 0) - if hr != 0 { - err = NewError(hr) - } - return -} diff --git a/vendor/github.com/go-ole/go-ole/itypeinfo_func.go b/vendor/github.com/go-ole/go-ole/itypeinfo_func.go new file mode 100644 index 000000000..8364a659b --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/itypeinfo_func.go @@ -0,0 +1,7 @@ +// +build !windows + +package ole + +func (v *ITypeInfo) GetTypeAttr() (*TYPEATTR, error) { + return nil, NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/itypeinfo_windows.go b/vendor/github.com/go-ole/go-ole/itypeinfo_windows.go new file mode 100644 index 000000000..54782b3da --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/itypeinfo_windows.go @@ -0,0 +1,21 @@ +// +build windows + +package ole + +import ( + "syscall" + "unsafe" +) + +func (v *ITypeInfo) GetTypeAttr() (tattr *TYPEATTR, err error) { + hr, _, _ := syscall.Syscall( + uintptr(v.VTable().GetTypeAttr), + 2, + uintptr(unsafe.Pointer(v)), + uintptr(unsafe.Pointer(&tattr)), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/iunknown.go b/vendor/github.com/go-ole/go-ole/iunknown.go new file mode 100644 index 000000000..108f28ea6 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iunknown.go @@ -0,0 +1,57 @@ +package ole + +import "unsafe" + +type IUnknown struct { + RawVTable *interface{} +} + +type IUnknownVtbl struct { + QueryInterface uintptr + AddRef uintptr + Release uintptr +} + +type UnknownLike interface { + QueryInterface(iid *GUID) (disp *IDispatch, err error) + AddRef() int32 + Release() int32 +} + +func (v *IUnknown) VTable() *IUnknownVtbl { + return (*IUnknownVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IUnknown) PutQueryInterface(interfaceID *GUID, obj interface{}) error { + return reflectQueryInterface(v, v.VTable().QueryInterface, interfaceID, obj) +} + +func (v *IUnknown) IDispatch(interfaceID *GUID) (dispatch *IDispatch, err error) { + err = v.PutQueryInterface(interfaceID, &dispatch) + return +} + +func (v *IUnknown) IEnumVARIANT(interfaceID *GUID) (enum *IEnumVARIANT, err error) { + err = v.PutQueryInterface(interfaceID, &enum) + return +} + +func (v *IUnknown) QueryInterface(iid *GUID) (*IDispatch, error) { + return queryInterface(v, iid) +} + +func (v *IUnknown) MustQueryInterface(iid *GUID) (disp *IDispatch) { + unk, err := queryInterface(v, iid) + if err != nil { + panic(err) + } + return unk +} + +func (v *IUnknown) AddRef() int32 { + return addRef(v) +} + +func (v *IUnknown) Release() int32 { + return release(v) +} diff --git a/vendor/github.com/go-ole/go-ole/iunknown_func.go b/vendor/github.com/go-ole/go-ole/iunknown_func.go new file mode 100644 index 000000000..d0a62cfd7 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iunknown_func.go @@ -0,0 +1,19 @@ +// +build !windows + +package ole + +func reflectQueryInterface(self interface{}, method uintptr, interfaceID *GUID, obj interface{}) (err error) { + return NewError(E_NOTIMPL) +} + +func queryInterface(unk *IUnknown, iid *GUID) (disp *IDispatch, err error) { + return nil, NewError(E_NOTIMPL) +} + +func addRef(unk *IUnknown) int32 { + return 0 +} + +func release(unk *IUnknown) int32 { + return 0 +} diff --git a/vendor/github.com/go-ole/go-ole/iunknown_windows.go b/vendor/github.com/go-ole/go-ole/iunknown_windows.go new file mode 100644 index 000000000..ede5bb8c1 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iunknown_windows.go @@ -0,0 +1,58 @@ +// +build windows + +package ole + +import ( + "reflect" + "syscall" + "unsafe" +) + +func reflectQueryInterface(self interface{}, method uintptr, interfaceID *GUID, obj interface{}) (err error) { + selfValue := reflect.ValueOf(self).Elem() + objValue := reflect.ValueOf(obj).Elem() + + hr, _, _ := syscall.Syscall( + method, + 3, + selfValue.UnsafeAddr(), + uintptr(unsafe.Pointer(interfaceID)), + objValue.Addr().Pointer()) + if hr != 0 { + err = NewError(hr) + } + return +} + +func queryInterface(unk *IUnknown, iid *GUID) (disp *IDispatch, err error) { + hr, _, _ := syscall.Syscall( + unk.VTable().QueryInterface, + 3, + uintptr(unsafe.Pointer(unk)), + uintptr(unsafe.Pointer(iid)), + uintptr(unsafe.Pointer(&disp))) + if hr != 0 { + err = NewError(hr) + } + return +} + +func addRef(unk *IUnknown) int32 { + ret, _, _ := syscall.Syscall( + unk.VTable().AddRef, + 1, + uintptr(unsafe.Pointer(unk)), + 0, + 0) + return int32(ret) +} + +func release(unk *IUnknown) int32 { + ret, _, _ := syscall.Syscall( + unk.VTable().Release, + 1, + uintptr(unsafe.Pointer(unk)), + 0, + 0) + return int32(ret) +} diff --git a/vendor/github.com/mattn/go-ole/ole.go b/vendor/github.com/go-ole/go-ole/ole.go similarity index 62% rename from vendor/github.com/mattn/go-ole/ole.go rename to vendor/github.com/go-ole/go-ole/ole.go index d3a3dfaef..e2ae4f4bb 100644 --- a/vendor/github.com/mattn/go-ole/ole.go +++ b/vendor/github.com/go-ole/go-ole/ole.go @@ -1,69 +1,11 @@ -// +build windows - package ole import ( "fmt" "strings" - "syscall" - "unicode/utf16" ) -type OleError struct { - hr uintptr - description string - subError error -} - -func errstr(errno int) string { - // ask windows for the remaining errors - var flags uint32 = syscall.FORMAT_MESSAGE_FROM_SYSTEM | syscall.FORMAT_MESSAGE_ARGUMENT_ARRAY | syscall.FORMAT_MESSAGE_IGNORE_INSERTS - b := make([]uint16, 300) - n, err := syscall.FormatMessage(flags, 0, uint32(errno), 0, b, nil) - if err != nil { - return fmt.Sprintf("error %d (FormatMessage failed with: %v)", errno, err) - } - // trim terminating \r and \n - for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- { - } - return string(utf16.Decode(b[:n])) -} - -func NewError(hr uintptr) *OleError { - return &OleError{hr: hr} -} - -func NewErrorWithDescription(hr uintptr, description string) *OleError { - return &OleError{hr: hr, description: description} -} - -func NewErrorWithSubError(hr uintptr, description string, err error) *OleError { - return &OleError{hr: hr, description: description, subError: err} -} - -func (v *OleError) Code() uintptr { - return uintptr(v.hr) -} - -func (v *OleError) String() string { - if v.description != "" { - return errstr(int(v.hr)) + " (" + v.description + ")" - } - return errstr(int(v.hr)) -} - -func (v *OleError) Error() string { - return v.String() -} - -func (v *OleError) Description() string { - return v.description -} - -func (v *OleError) SubError() error { - return v.subError -} - +// DISPPARAMS are the arguments that passed to methods or property. type DISPPARAMS struct { rgvarg uintptr rgdispidNamedArgs uintptr @@ -71,6 +13,7 @@ type DISPPARAMS struct { cNamedArgs uint32 } +// EXCEPINFO defines exception info. type EXCEPINFO struct { wCode uint16 wReserved uint16 @@ -83,6 +26,17 @@ type EXCEPINFO struct { scode uint32 } +// WCode return wCode in EXCEPINFO. +func (e EXCEPINFO) WCode() uint16 { + return e.wCode +} + +// SCODE return scode in EXCEPINFO. +func (e EXCEPINFO) SCODE() uint32 { + return e.scode +} + +// String convert EXCEPINFO to string. func (e EXCEPINFO) String() string { var src, desc, hlp string if e.bstrSource == nil { @@ -109,6 +63,7 @@ func (e EXCEPINFO) String() string { ) } +// Error implements error interface and returns error string. func (e EXCEPINFO) Error() string { if e.bstrDescription != nil { return strings.TrimSpace(BstrToString(e.bstrDescription)) @@ -127,11 +82,13 @@ func (e EXCEPINFO) Error() string { return fmt.Sprintf("%v: %#x", src, code) } +// PARAMDATA defines parameter data type. type PARAMDATA struct { Name *int16 Vt uint16 } +// METHODDATA defines method info. type METHODDATA struct { Name *uint16 Data *PARAMDATA @@ -143,16 +100,19 @@ type METHODDATA struct { VtReturn uint32 } +// INTERFACEDATA defines interface info. type INTERFACEDATA struct { MethodData *METHODDATA CMembers uint32 } +// Point is 2D vector type. type Point struct { X int32 Y int32 } +// Msg is message between processes. type Msg struct { Hwnd uint32 Message uint32 @@ -162,16 +122,19 @@ type Msg struct { Pt Point } +// TYPEDESC defines data type. type TYPEDESC struct { Hreftype uint32 VT uint16 } +// IDLDESC defines IDL info. type IDLDESC struct { DwReserved uint32 WIDLFlags uint16 } +// TYPEATTR defines type info. type TYPEATTR struct { Guid GUID Lcid uint32 diff --git a/vendor/github.com/go-ole/go-ole/oleutil/connection.go b/vendor/github.com/go-ole/go-ole/oleutil/connection.go new file mode 100644 index 000000000..60df73cda --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/connection.go @@ -0,0 +1,100 @@ +// +build windows + +package oleutil + +import ( + "reflect" + "unsafe" + + ole "github.com/go-ole/go-ole" +) + +type stdDispatch struct { + lpVtbl *stdDispatchVtbl + ref int32 + iid *ole.GUID + iface interface{} + funcMap map[string]int32 +} + +type stdDispatchVtbl struct { + pQueryInterface uintptr + pAddRef uintptr + pRelease uintptr + pGetTypeInfoCount uintptr + pGetTypeInfo uintptr + pGetIDsOfNames uintptr + pInvoke uintptr +} + +func dispQueryInterface(this *ole.IUnknown, iid *ole.GUID, punk **ole.IUnknown) uint32 { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + *punk = nil + if ole.IsEqualGUID(iid, ole.IID_IUnknown) || + ole.IsEqualGUID(iid, ole.IID_IDispatch) { + dispAddRef(this) + *punk = this + return ole.S_OK + } + if ole.IsEqualGUID(iid, pthis.iid) { + dispAddRef(this) + *punk = this + return ole.S_OK + } + return ole.E_NOINTERFACE +} + +func dispAddRef(this *ole.IUnknown) int32 { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + pthis.ref++ + return pthis.ref +} + +func dispRelease(this *ole.IUnknown) int32 { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + pthis.ref-- + return pthis.ref +} + +func dispGetIDsOfNames(this *ole.IUnknown, iid *ole.GUID, wnames []*uint16, namelen int, lcid int, pdisp []int32) uintptr { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + names := make([]string, len(wnames)) + for i := 0; i < len(names); i++ { + names[i] = ole.LpOleStrToString(wnames[i]) + } + for n := 0; n < namelen; n++ { + if id, ok := pthis.funcMap[names[n]]; ok { + pdisp[n] = id + } + } + return ole.S_OK +} + +func dispGetTypeInfoCount(pcount *int) uintptr { + if pcount != nil { + *pcount = 0 + } + return ole.S_OK +} + +func dispGetTypeInfo(ptypeif *uintptr) uintptr { + return ole.E_NOTIMPL +} + +func dispInvoke(this *ole.IDispatch, dispid int32, riid *ole.GUID, lcid int, flags int16, dispparams *ole.DISPPARAMS, result *ole.VARIANT, pexcepinfo *ole.EXCEPINFO, nerr *uint) uintptr { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + found := "" + for name, id := range pthis.funcMap { + if id == dispid { + found = name + } + } + if found != "" { + rv := reflect.ValueOf(pthis.iface).Elem() + rm := rv.MethodByName(found) + rr := rm.Call([]reflect.Value{}) + println(len(rr)) + return ole.S_OK + } + return ole.E_NOTIMPL +} diff --git a/vendor/github.com/go-ole/go-ole/oleutil/connection_func.go b/vendor/github.com/go-ole/go-ole/oleutil/connection_func.go new file mode 100644 index 000000000..8818fb827 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/connection_func.go @@ -0,0 +1,10 @@ +// +build !windows + +package oleutil + +import ole "github.com/go-ole/go-ole" + +// ConnectObject creates a connection point between two services for communication. +func ConnectObject(disp *ole.IDispatch, iid *ole.GUID, idisp interface{}) (uint32, error) { + return 0, ole.NewError(ole.E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/oleutil/connection_windows.go b/vendor/github.com/go-ole/go-ole/oleutil/connection_windows.go new file mode 100644 index 000000000..ab9c0d8dc --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/connection_windows.go @@ -0,0 +1,58 @@ +// +build windows + +package oleutil + +import ( + "reflect" + "syscall" + "unsafe" + + ole "github.com/go-ole/go-ole" +) + +// ConnectObject creates a connection point between two services for communication. +func ConnectObject(disp *ole.IDispatch, iid *ole.GUID, idisp interface{}) (cookie uint32, err error) { + unknown, err := disp.QueryInterface(ole.IID_IConnectionPointContainer) + if err != nil { + return + } + + container := (*ole.IConnectionPointContainer)(unsafe.Pointer(unknown)) + var point *ole.IConnectionPoint + err = container.FindConnectionPoint(iid, &point) + if err != nil { + return + } + if edisp, ok := idisp.(*ole.IUnknown); ok { + cookie, err = point.Advise(edisp) + container.Release() + if err != nil { + return + } + } + rv := reflect.ValueOf(disp).Elem() + if rv.Type().Kind() == reflect.Struct { + dest := &stdDispatch{} + dest.lpVtbl = &stdDispatchVtbl{} + dest.lpVtbl.pQueryInterface = syscall.NewCallback(dispQueryInterface) + dest.lpVtbl.pAddRef = syscall.NewCallback(dispAddRef) + dest.lpVtbl.pRelease = syscall.NewCallback(dispRelease) + dest.lpVtbl.pGetTypeInfoCount = syscall.NewCallback(dispGetTypeInfoCount) + dest.lpVtbl.pGetTypeInfo = syscall.NewCallback(dispGetTypeInfo) + dest.lpVtbl.pGetIDsOfNames = syscall.NewCallback(dispGetIDsOfNames) + dest.lpVtbl.pInvoke = syscall.NewCallback(dispInvoke) + dest.iface = disp + dest.iid = iid + cookie, err = point.Advise((*ole.IUnknown)(unsafe.Pointer(dest))) + container.Release() + if err != nil { + point.Release() + return + } + return + } + + container.Release() + + return 0, ole.NewError(ole.E_INVALIDARG) +} diff --git a/vendor/github.com/mattn/go-ole/oleutil/go-get.go b/vendor/github.com/go-ole/go-ole/oleutil/go-get.go similarity index 100% rename from vendor/github.com/mattn/go-ole/oleutil/go-get.go rename to vendor/github.com/go-ole/go-ole/oleutil/go-get.go diff --git a/vendor/github.com/go-ole/go-ole/oleutil/oleutil.go b/vendor/github.com/go-ole/go-ole/oleutil/oleutil.go new file mode 100644 index 000000000..f7803c1e3 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/oleutil.go @@ -0,0 +1,127 @@ +package oleutil + +import ole "github.com/go-ole/go-ole" + +// ClassIDFrom retrieves class ID whether given is program ID or application string. +func ClassIDFrom(programID string) (classID *ole.GUID, err error) { + return ole.ClassIDFrom(programID) +} + +// CreateObject creates object from programID based on interface type. +// +// Only supports IUnknown. +// +// Program ID can be either program ID or application string. +func CreateObject(programID string) (unknown *ole.IUnknown, err error) { + classID, err := ole.ClassIDFrom(programID) + if err != nil { + return + } + + unknown, err = ole.CreateInstance(classID, ole.IID_IUnknown) + if err != nil { + return + } + + return +} + +// GetActiveObject retrieves active object for program ID and interface ID based +// on interface type. +// +// Only supports IUnknown. +// +// Program ID can be either program ID or application string. +func GetActiveObject(programID string) (unknown *ole.IUnknown, err error) { + classID, err := ole.ClassIDFrom(programID) + if err != nil { + return + } + + unknown, err = ole.GetActiveObject(classID, ole.IID_IUnknown) + if err != nil { + return + } + + return +} + +// CallMethod calls method on IDispatch with parameters. +func CallMethod(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) { + return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_METHOD, params) +} + +// MustCallMethod calls method on IDispatch with parameters or panics. +func MustCallMethod(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) { + r, err := CallMethod(disp, name, params...) + if err != nil { + panic(err.Error()) + } + return r +} + +// GetProperty retrieves property from IDispatch. +func GetProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) { + return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYGET, params) +} + +// MustGetProperty retrieves property from IDispatch or panics. +func MustGetProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) { + r, err := GetProperty(disp, name, params...) + if err != nil { + panic(err.Error()) + } + return r +} + +// PutProperty mutates property. +func PutProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) { + return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYPUT, params) +} + +// MustPutProperty mutates property or panics. +func MustPutProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) { + r, err := PutProperty(disp, name, params...) + if err != nil { + panic(err.Error()) + } + return r +} + +// PutPropertyRef mutates property reference. +func PutPropertyRef(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) { + return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYPUTREF, params) +} + +// MustPutPropertyRef mutates property reference or panics. +func MustPutPropertyRef(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) { + r, err := PutPropertyRef(disp, name, params...) + if err != nil { + panic(err.Error()) + } + return r +} + +func ForEach(disp *ole.IDispatch, f func(v *ole.VARIANT) error) error { + newEnum, err := disp.GetProperty("_NewEnum") + if err != nil { + return err + } + defer newEnum.Clear() + + enum, err := newEnum.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant) + if err != nil { + return err + } + defer enum.Release() + + for item, length, err := enum.Next(1); length > 0; item, length, err = enum.Next(1) { + if err != nil { + return err + } + if ferr := f(&item); ferr != nil { + return ferr + } + } + return nil +} diff --git a/vendor/github.com/go-ole/go-ole/safearray.go b/vendor/github.com/go-ole/go-ole/safearray.go new file mode 100644 index 000000000..a5201b56c --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearray.go @@ -0,0 +1,27 @@ +// Package is meant to retrieve and process safe array data returned from COM. + +package ole + +// SafeArrayBound defines the SafeArray boundaries. +type SafeArrayBound struct { + Elements uint32 + LowerBound int32 +} + +// SafeArray is how COM handles arrays. +type SafeArray struct { + Dimensions uint16 + FeaturesFlag uint16 + ElementsSize uint32 + LocksAmount uint32 + Data uint32 + Bounds [16]byte +} + +// SAFEARRAY is obsolete, exists for backwards compatibility. +// Use SafeArray +type SAFEARRAY SafeArray + +// SAFEARRAYBOUND is obsolete, exists for backwards compatibility. +// Use SafeArrayBound +type SAFEARRAYBOUND SafeArrayBound diff --git a/vendor/github.com/go-ole/go-ole/safearray_func.go b/vendor/github.com/go-ole/go-ole/safearray_func.go new file mode 100644 index 000000000..8ff0baa41 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearray_func.go @@ -0,0 +1,211 @@ +// +build !windows + +package ole + +import ( + "unsafe" +) + +// safeArrayAccessData returns raw array pointer. +// +// AKA: SafeArrayAccessData in Windows API. +func safeArrayAccessData(safearray *SafeArray) (uintptr, error) { + return uintptr(0), NewError(E_NOTIMPL) +} + +// safeArrayUnaccessData releases raw array. +// +// AKA: SafeArrayUnaccessData in Windows API. +func safeArrayUnaccessData(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayAllocData allocates SafeArray. +// +// AKA: SafeArrayAllocData in Windows API. +func safeArrayAllocData(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayAllocDescriptor allocates SafeArray. +// +// AKA: SafeArrayAllocDescriptor in Windows API. +func safeArrayAllocDescriptor(dimensions uint32) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayAllocDescriptorEx allocates SafeArray. +// +// AKA: SafeArrayAllocDescriptorEx in Windows API. +func safeArrayAllocDescriptorEx(variantType VT, dimensions uint32) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCopy returns copy of SafeArray. +// +// AKA: SafeArrayCopy in Windows API. +func safeArrayCopy(original *SafeArray) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCopyData duplicates SafeArray into another SafeArray object. +// +// AKA: SafeArrayCopyData in Windows API. +func safeArrayCopyData(original *SafeArray, duplicate *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayCreate creates SafeArray. +// +// AKA: SafeArrayCreate in Windows API. +func safeArrayCreate(variantType VT, dimensions uint32, bounds *SafeArrayBound) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCreateEx creates SafeArray. +// +// AKA: SafeArrayCreateEx in Windows API. +func safeArrayCreateEx(variantType VT, dimensions uint32, bounds *SafeArrayBound, extra uintptr) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCreateVector creates SafeArray. +// +// AKA: SafeArrayCreateVector in Windows API. +func safeArrayCreateVector(variantType VT, lowerBound int32, length uint32) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCreateVectorEx creates SafeArray. +// +// AKA: SafeArrayCreateVectorEx in Windows API. +func safeArrayCreateVectorEx(variantType VT, lowerBound int32, length uint32, extra uintptr) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayDestroy destroys SafeArray object. +// +// AKA: SafeArrayDestroy in Windows API. +func safeArrayDestroy(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayDestroyData destroys SafeArray object. +// +// AKA: SafeArrayDestroyData in Windows API. +func safeArrayDestroyData(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayDestroyDescriptor destroys SafeArray object. +// +// AKA: SafeArrayDestroyDescriptor in Windows API. +func safeArrayDestroyDescriptor(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayGetDim is the amount of dimensions in the SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetDim in Windows API. +func safeArrayGetDim(safearray *SafeArray) (*uint32, error) { + u := uint32(0) + return &u, NewError(E_NOTIMPL) +} + +// safeArrayGetElementSize is the element size in bytes. +// +// AKA: SafeArrayGetElemsize in Windows API. +func safeArrayGetElementSize(safearray *SafeArray) (*uint32, error) { + u := uint32(0) + return &u, NewError(E_NOTIMPL) +} + +// safeArrayGetElement retrieves element at given index. +func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) error { + return NewError(E_NOTIMPL) +} + +// safeArrayGetElement retrieves element at given index and converts to string. +func safeArrayGetElementString(safearray *SafeArray, index int64) (string, error) { + return "", NewError(E_NOTIMPL) +} + +// safeArrayGetIID is the InterfaceID of the elements in the SafeArray. +// +// AKA: SafeArrayGetIID in Windows API. +func safeArrayGetIID(safearray *SafeArray) (*GUID, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayGetLBound returns lower bounds of SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetLBound in Windows API. +func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int64, error) { + return int64(0), NewError(E_NOTIMPL) +} + +// safeArrayGetUBound returns upper bounds of SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetUBound in Windows API. +func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (int64, error) { + return int64(0), NewError(E_NOTIMPL) +} + +// safeArrayGetVartype returns data type of SafeArray. +// +// AKA: SafeArrayGetVartype in Windows API. +func safeArrayGetVartype(safearray *SafeArray) (uint16, error) { + return uint16(0), NewError(E_NOTIMPL) +} + +// safeArrayLock locks SafeArray for reading to modify SafeArray. +// +// This must be called during some calls to ensure that another process does not +// read or write to the SafeArray during editing. +// +// AKA: SafeArrayLock in Windows API. +func safeArrayLock(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayUnlock unlocks SafeArray for reading. +// +// AKA: SafeArrayUnlock in Windows API. +func safeArrayUnlock(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayPutElement stores the data element at the specified location in the +// array. +// +// AKA: SafeArrayPutElement in Windows API. +func safeArrayPutElement(safearray *SafeArray, index int64, element uintptr) error { + return NewError(E_NOTIMPL) +} + +// safeArrayGetRecordInfo accesses IRecordInfo info for custom types. +// +// AKA: SafeArrayGetRecordInfo in Windows API. +// +// XXX: Must implement IRecordInfo interface for this to return. +func safeArrayGetRecordInfo(safearray *SafeArray) (interface{}, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArraySetRecordInfo mutates IRecordInfo info for custom types. +// +// AKA: SafeArraySetRecordInfo in Windows API. +// +// XXX: Must implement IRecordInfo interface for this to return. +func safeArraySetRecordInfo(safearray *SafeArray, recordInfo interface{}) error { + return NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/mattn/go-ole/safearray.go b/vendor/github.com/go-ole/go-ole/safearray_windows.go similarity index 70% rename from vendor/github.com/mattn/go-ole/safearray.go rename to vendor/github.com/go-ole/go-ole/safearray_windows.go index c66ae70cc..b27936e24 100644 --- a/vendor/github.com/mattn/go-ole/safearray.go +++ b/vendor/github.com/go-ole/go-ole/safearray_windows.go @@ -1,12 +1,8 @@ -// Package is meant to retrieve and process safe array data returned from COM. -// // +build windows package ole import ( - _ "fmt" - _ "syscall" "unsafe" ) @@ -38,11 +34,13 @@ var ( procSafeArrayPutElement, _ = modoleaut32.FindProc("SafeArrayPutElement") //procSafeArrayRedim, _ = modoleaut32.FindProc("SafeArrayRedim") // TODO //procSafeArraySetIID, _ = modoleaut32.FindProc("SafeArraySetIID") // TODO - //procSafeArrayGetRecordInfo, _ = modoleaut32.FindProc("SafeArrayGetRecordInfo") // TODO - //procSafeArraySetRecordInfo, _ = modoleaut32.FindProc("SafeArraySetRecordInfo") // TODO + procSafeArrayGetRecordInfo, _ = modoleaut32.FindProc("SafeArrayGetRecordInfo") + procSafeArraySetRecordInfo, _ = modoleaut32.FindProc("SafeArraySetRecordInfo") ) -// Returns Raw Array +// safeArrayAccessData returns raw array pointer. +// +// AKA: SafeArrayAccessData in Windows API. // Todo: Test func safeArrayAccessData(safearray *SafeArray) (element uintptr, err error) { err = convertHresultToError( @@ -52,22 +50,34 @@ func safeArrayAccessData(safearray *SafeArray) (element uintptr, err error) { return } +// safeArrayUnaccessData releases raw array. +// +// AKA: SafeArrayUnaccessData in Windows API. func safeArrayUnaccessData(safearray *SafeArray) (err error) { err = convertHresultToError(procSafeArrayUnaccessData.Call(uintptr(unsafe.Pointer(safearray)))) return } +// safeArrayAllocData allocates SafeArray. +// +// AKA: SafeArrayAllocData in Windows API. func safeArrayAllocData(safearray *SafeArray) (err error) { err = convertHresultToError(procSafeArrayAllocData.Call(uintptr(unsafe.Pointer(safearray)))) return } +// safeArrayAllocDescriptor allocates SafeArray. +// +// AKA: SafeArrayAllocDescriptor in Windows API. func safeArrayAllocDescriptor(dimensions uint32) (safearray *SafeArray, err error) { err = convertHresultToError( procSafeArrayAllocDescriptor.Call(uintptr(dimensions), uintptr(unsafe.Pointer(&safearray)))) return } +// safeArrayAllocDescriptorEx allocates SafeArray. +// +// AKA: SafeArrayAllocDescriptorEx in Windows API. func safeArrayAllocDescriptorEx(variantType VT, dimensions uint32) (safearray *SafeArray, err error) { err = convertHresultToError( procSafeArrayAllocDescriptorEx.Call( @@ -77,6 +87,9 @@ func safeArrayAllocDescriptorEx(variantType VT, dimensions uint32) (safearray *S return } +// safeArrayCopy returns copy of SafeArray. +// +// AKA: SafeArrayCopy in Windows API. func safeArrayCopy(original *SafeArray) (safearray *SafeArray, err error) { err = convertHresultToError( procSafeArrayCopy.Call( @@ -85,6 +98,9 @@ func safeArrayCopy(original *SafeArray) (safearray *SafeArray, err error) { return } +// safeArrayCopyData duplicates SafeArray into another SafeArray object. +// +// AKA: SafeArrayCopyData in Windows API. func safeArrayCopyData(original *SafeArray, duplicate *SafeArray) (err error) { err = convertHresultToError( procSafeArrayCopyData.Call( @@ -93,6 +109,9 @@ func safeArrayCopyData(original *SafeArray, duplicate *SafeArray) (err error) { return } +// safeArrayCreate creates SafeArray. +// +// AKA: SafeArrayCreate in Windows API. func safeArrayCreate(variantType VT, dimensions uint32, bounds *SafeArrayBound) (safearray *SafeArray, err error) { sa, _, err := procSafeArrayCreate.Call( uintptr(variantType), @@ -102,6 +121,9 @@ func safeArrayCreate(variantType VT, dimensions uint32, bounds *SafeArrayBound) return } +// safeArrayCreateEx creates SafeArray. +// +// AKA: SafeArrayCreateEx in Windows API. func safeArrayCreateEx(variantType VT, dimensions uint32, bounds *SafeArrayBound, extra uintptr) (safearray *SafeArray, err error) { sa, _, err := procSafeArrayCreateEx.Call( uintptr(variantType), @@ -112,6 +134,9 @@ func safeArrayCreateEx(variantType VT, dimensions uint32, bounds *SafeArrayBound return } +// safeArrayCreateVector creates SafeArray. +// +// AKA: SafeArrayCreateVector in Windows API. func safeArrayCreateVector(variantType VT, lowerBound int32, length uint32) (safearray *SafeArray, err error) { sa, _, err := procSafeArrayCreateVector.Call( uintptr(variantType), @@ -121,6 +146,9 @@ func safeArrayCreateVector(variantType VT, lowerBound int32, length uint32) (saf return } +// safeArrayCreateVectorEx creates SafeArray. +// +// AKA: SafeArrayCreateVectorEx in Windows API. func safeArrayCreateVectorEx(variantType VT, lowerBound int32, length uint32, extra uintptr) (safearray *SafeArray, err error) { sa, _, err := procSafeArrayCreateVectorEx.Call( uintptr(variantType), @@ -131,42 +159,61 @@ func safeArrayCreateVectorEx(variantType VT, lowerBound int32, length uint32, ex return } +// safeArrayDestroy destroys SafeArray object. +// +// AKA: SafeArrayDestroy in Windows API. func safeArrayDestroy(safearray *SafeArray) (err error) { err = convertHresultToError(procSafeArrayDestroy.Call(uintptr(unsafe.Pointer(safearray)))) return } +// safeArrayDestroyData destroys SafeArray object. +// +// AKA: SafeArrayDestroyData in Windows API. func safeArrayDestroyData(safearray *SafeArray) (err error) { err = convertHresultToError(procSafeArrayDestroyData.Call(uintptr(unsafe.Pointer(safearray)))) return } +// safeArrayDestroyDescriptor destroys SafeArray object. +// +// AKA: SafeArrayDestroyDescriptor in Windows API. func safeArrayDestroyDescriptor(safearray *SafeArray) (err error) { err = convertHresultToError(procSafeArrayDestroyDescriptor.Call(uintptr(unsafe.Pointer(safearray)))) return } +// safeArrayGetDim is the amount of dimensions in the SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetDim in Windows API. func safeArrayGetDim(safearray *SafeArray) (dimensions *uint32, err error) { l, _, err := procSafeArrayGetDim.Call(uintptr(unsafe.Pointer(safearray))) dimensions = (*uint32)(unsafe.Pointer(l)) return } +// safeArrayGetElementSize is the element size in bytes. +// +// AKA: SafeArrayGetElemsize in Windows API. func safeArrayGetElementSize(safearray *SafeArray) (length *uint32, err error) { l, _, err := procSafeArrayGetElemsize.Call(uintptr(unsafe.Pointer(safearray))) length = (*uint32)(unsafe.Pointer(l)) return } -func safeArrayGetElement(safearray *SafeArray, index int64) (element uintptr, err error) { - err = convertHresultToError( +// safeArrayGetElement retrieves element at given index. +func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) error { + return convertHresultToError( procSafeArrayGetElement.Call( uintptr(unsafe.Pointer(safearray)), uintptr(unsafe.Pointer(&index)), - uintptr(unsafe.Pointer(&element)))) - return + uintptr(pv))) } +// safeArrayGetElementString retrieves element at given index and converts to string. func safeArrayGetElementString(safearray *SafeArray, index int64) (str string, err error) { var element *int16 err = convertHresultToError( @@ -179,6 +226,9 @@ func safeArrayGetElementString(safearray *SafeArray, index int64) (str string, e return } +// safeArrayGetIID is the InterfaceID of the elements in the SafeArray. +// +// AKA: SafeArrayGetIID in Windows API. func safeArrayGetIID(safearray *SafeArray) (guid *GUID, err error) { err = convertHresultToError( procSafeArrayGetIID.Call( @@ -187,6 +237,12 @@ func safeArrayGetIID(safearray *SafeArray) (guid *GUID, err error) { return } +// safeArrayGetLBound returns lower bounds of SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetLBound in Windows API. func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int64, err error) { err = convertHresultToError( procSafeArrayGetLBound.Call( @@ -196,6 +252,12 @@ func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int6 return } +// safeArrayGetUBound returns upper bounds of SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetUBound in Windows API. func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int64, err error) { err = convertHresultToError( procSafeArrayGetUBound.Call( @@ -205,6 +267,9 @@ func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int6 return } +// safeArrayGetVartype returns data type of SafeArray. +// +// AKA: SafeArrayGetVartype in Windows API. func safeArrayGetVartype(safearray *SafeArray) (varType uint16, err error) { err = convertHresultToError( procSafeArrayGetVartype.Call( @@ -213,16 +278,29 @@ func safeArrayGetVartype(safearray *SafeArray) (varType uint16, err error) { return } +// safeArrayLock locks SafeArray for reading to modify SafeArray. +// +// This must be called during some calls to ensure that another process does not +// read or write to the SafeArray during editing. +// +// AKA: SafeArrayLock in Windows API. func safeArrayLock(safearray *SafeArray) (err error) { err = convertHresultToError(procSafeArrayLock.Call(uintptr(unsafe.Pointer(safearray)))) return } +// safeArrayUnlock unlocks SafeArray for reading. +// +// AKA: SafeArrayUnlock in Windows API. func safeArrayUnlock(safearray *SafeArray) (err error) { err = convertHresultToError(procSafeArrayUnlock.Call(uintptr(unsafe.Pointer(safearray)))) return } +// safeArrayPutElement stores the data element at the specified location in the +// array. +// +// AKA: SafeArrayPutElement in Windows API. func safeArrayPutElement(safearray *SafeArray, index int64, element uintptr) (err error) { err = convertHresultToError( procSafeArrayPutElement.Call( @@ -232,8 +310,11 @@ func safeArrayPutElement(safearray *SafeArray, index int64, element uintptr) (er return } -/* -// TODO: Must implement IRecordInfo interface for this to return. +// safeArrayGetRecordInfo accesses IRecordInfo info for custom types. +// +// AKA: SafeArrayGetRecordInfo in Windows API. +// +// XXX: Must implement IRecordInfo interface for this to return. func safeArrayGetRecordInfo(safearray *SafeArray) (recordInfo interface{}, err error) { err = convertHresultToError( procSafeArrayGetRecordInfo.Call( @@ -242,34 +323,15 @@ func safeArrayGetRecordInfo(safearray *SafeArray) (recordInfo interface{}, err e return } -// TODO: Must implement IRecordInfo interface for this to work. +// safeArraySetRecordInfo mutates IRecordInfo info for custom types. +// +// AKA: SafeArraySetRecordInfo in Windows API. +// +// XXX: Must implement IRecordInfo interface for this to return. func safeArraySetRecordInfo(safearray *SafeArray, recordInfo interface{}) (err error) { err = convertHresultToError( procSafeArraySetRecordInfo.Call( uintptr(unsafe.Pointer(safearray)), - uintptr(unsafe.Pointer(recordInfo)))) + uintptr(unsafe.Pointer(&recordInfo)))) return } -*/ - -type SafeArrayBound struct { - Elements uint32 - LowerBound int32 -} - -type SafeArray struct { - Dimensions uint16 - FeaturesFlag uint16 - ElementsSize uint32 - LocksAmount uint32 - Data uint32 - Bounds SafeArrayBound -} - -// Obsolete, exists for backwards compatibility. -// Use SafeArray -type SAFEARRAY SafeArray - -// Obsolete, exists for backwards compatibility. -// Use SafeArrayBound -type SAFEARRAYBOUND SafeArrayBound diff --git a/vendor/github.com/go-ole/go-ole/safearrayconversion.go b/vendor/github.com/go-ole/go-ole/safearrayconversion.go new file mode 100644 index 000000000..ffeb2b97b --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearrayconversion.go @@ -0,0 +1,140 @@ +// Helper for converting SafeArray to array of objects. + +package ole + +import ( + "unsafe" +) + +type SafeArrayConversion struct { + Array *SafeArray +} + +func (sac *SafeArrayConversion) ToStringArray() (strings []string) { + totalElements, _ := sac.TotalElements(0) + strings = make([]string, totalElements) + + for i := int64(0); i < totalElements; i++ { + strings[int32(i)], _ = safeArrayGetElementString(sac.Array, i) + } + + return +} + +func (sac *SafeArrayConversion) ToByteArray() (bytes []byte) { + totalElements, _ := sac.TotalElements(0) + bytes = make([]byte, totalElements) + + for i := int64(0); i < totalElements; i++ { + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&bytes[int32(i)])) + } + + return +} + +func (sac *SafeArrayConversion) ToValueArray() (values []interface{}) { + totalElements, _ := sac.TotalElements(0) + values = make([]interface{}, totalElements) + vt, _ := safeArrayGetVartype(sac.Array) + + for i := 0; i < int(totalElements); i++ { + switch VT(vt) { + case VT_BOOL: + var v bool + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_I1: + var v int8 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_I2: + var v int16 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_I4: + var v int32 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_I8: + var v int64 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_UI1: + var v uint8 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_UI2: + var v uint16 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_UI4: + var v uint32 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_UI8: + var v uint64 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_R4: + var v float32 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_R8: + var v float64 + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_BSTR: + var v string + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v + case VT_VARIANT: + var v VARIANT + safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + values[i] = v.Value() + default: + // TODO + } + } + + return +} + +func (sac *SafeArrayConversion) GetType() (varType uint16, err error) { + return safeArrayGetVartype(sac.Array) +} + +func (sac *SafeArrayConversion) GetDimensions() (dimensions *uint32, err error) { + return safeArrayGetDim(sac.Array) +} + +func (sac *SafeArrayConversion) GetSize() (length *uint32, err error) { + return safeArrayGetElementSize(sac.Array) +} + +func (sac *SafeArrayConversion) TotalElements(index uint32) (totalElements int64, err error) { + if index < 1 { + index = 1 + } + + // Get array bounds + var LowerBounds int64 + var UpperBounds int64 + + LowerBounds, err = safeArrayGetLBound(sac.Array, index) + if err != nil { + return + } + + UpperBounds, err = safeArrayGetUBound(sac.Array, index) + if err != nil { + return + } + + totalElements = UpperBounds - LowerBounds + 1 + return +} + +// Release Safe Array memory +func (sac *SafeArrayConversion) Release() { + safeArrayDestroy(sac.Array) +} diff --git a/vendor/github.com/go-ole/go-ole/safearrayslices.go b/vendor/github.com/go-ole/go-ole/safearrayslices.go new file mode 100644 index 000000000..a9fa885f1 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearrayslices.go @@ -0,0 +1,33 @@ +// +build windows + +package ole + +import ( + "unsafe" +) + +func safeArrayFromByteSlice(slice []byte) *SafeArray { + array, _ := safeArrayCreateVector(VT_UI1, 0, uint32(len(slice))) + + if array == nil { + panic("Could not convert []byte to SAFEARRAY") + } + + for i, v := range slice { + safeArrayPutElement(array, int64(i), uintptr(unsafe.Pointer(&v))) + } + return array +} + +func safeArrayFromStringSlice(slice []string) *SafeArray { + array, _ := safeArrayCreateVector(VT_BSTR, 0, uint32(len(slice))) + + if array == nil { + panic("Could not convert []string to SAFEARRAY") + } + // SysAllocStringLen(s) + for i, v := range slice { + safeArrayPutElement(array, int64(i), uintptr(unsafe.Pointer(SysAllocStringLen(v)))) + } + return array +} diff --git a/vendor/github.com/mattn/go-ole/utility.go b/vendor/github.com/go-ole/go-ole/utility.go similarity index 57% rename from vendor/github.com/mattn/go-ole/utility.go rename to vendor/github.com/go-ole/go-ole/utility.go index 346a78236..99ee82dc3 100644 --- a/vendor/github.com/mattn/go-ole/utility.go +++ b/vendor/github.com/go-ole/go-ole/utility.go @@ -1,5 +1,3 @@ -// +build windows - package ole import ( @@ -7,20 +5,23 @@ import ( "unsafe" ) -func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool { - return guid1.Data1 == guid2.Data1 && - guid1.Data2 == guid2.Data2 && - guid1.Data3 == guid2.Data3 && - guid1.Data4[0] == guid2.Data4[0] && - guid1.Data4[1] == guid2.Data4[1] && - guid1.Data4[2] == guid2.Data4[2] && - guid1.Data4[3] == guid2.Data4[3] && - guid1.Data4[4] == guid2.Data4[4] && - guid1.Data4[5] == guid2.Data4[5] && - guid1.Data4[6] == guid2.Data4[6] && - guid1.Data4[7] == guid2.Data4[7] +// ClassIDFrom retrieves class ID whether given is program ID or application string. +// +// Helper that provides check against both Class ID from Program ID and Class ID from string. It is +// faster, if you know which you are using, to use the individual functions, but this will check +// against available functions for you. +func ClassIDFrom(programID string) (classID *GUID, err error) { + classID, err = CLSIDFromProgID(programID) + if err != nil { + classID, err = CLSIDFromString(programID) + if err != nil { + return + } + } + return } +// BytePtrToString converts byte pointer to a Go string. func BytePtrToString(p *byte) string { a := (*[10000]uint8)(unsafe.Pointer(p)) i := 0 @@ -30,11 +31,14 @@ func BytePtrToString(p *byte) string { return string(a[:i]) } -// Alias for LpOleStrToString - kept for compatibility reasons +// UTF16PtrToString is alias for LpOleStrToString. +// +// Kept for compatibility reasons. func UTF16PtrToString(p *uint16) string { return LpOleStrToString(p) } +// LpOleStrToString converts COM Unicode to Go string. func LpOleStrToString(p *uint16) string { if p == nil { return "" @@ -53,6 +57,7 @@ func LpOleStrToString(p *uint16) string { return string(utf16.Decode(a)) } +// BstrToString converts COM binary string to Go string. func BstrToString(p *uint16) string { if p == nil { return "" @@ -69,6 +74,7 @@ func BstrToString(p *uint16) string { return string(utf16.Decode(a)) } +// lpOleStrLen returns the length of Unicode string. func lpOleStrLen(p *uint16) (length int64) { if p == nil { return 0 @@ -86,6 +92,7 @@ func lpOleStrLen(p *uint16) (length int64) { return } +// convertHresultToError converts syscall to error, if call is unsuccessful. func convertHresultToError(hr uintptr, r2 uintptr, ignore error) (err error) { if hr != 0 { err = NewError(hr) diff --git a/vendor/github.com/go-ole/go-ole/variables.go b/vendor/github.com/go-ole/go-ole/variables.go new file mode 100644 index 000000000..ebe00f1cf --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variables.go @@ -0,0 +1,16 @@ +// +build windows + +package ole + +import ( + "syscall" +) + +var ( + modcombase = syscall.NewLazyDLL("combase.dll") + modkernel32, _ = syscall.LoadDLL("kernel32.dll") + modole32, _ = syscall.LoadDLL("ole32.dll") + modoleaut32, _ = syscall.LoadDLL("oleaut32.dll") + modmsvcrt, _ = syscall.LoadDLL("msvcrt.dll") + moduser32, _ = syscall.LoadDLL("user32.dll") +) diff --git a/vendor/github.com/mattn/go-ole/variant.go b/vendor/github.com/go-ole/go-ole/variant.go similarity index 67% rename from vendor/github.com/mattn/go-ole/variant.go rename to vendor/github.com/go-ole/go-ole/variant.go index 46000c7cc..36969725e 100644 --- a/vendor/github.com/mattn/go-ole/variant.go +++ b/vendor/github.com/go-ole/go-ole/variant.go @@ -1,13 +1,13 @@ -// +build windows - package ole import "unsafe" +// NewVariant returns new variant based on type and value. func NewVariant(vt VT, val int64) VARIANT { return VARIANT{VT: vt, Val: val} } +// ToIUnknown converts Variant to Unknown object. func (v *VARIANT) ToIUnknown() *IUnknown { if v.VT != VT_UNKNOWN { return nil @@ -15,6 +15,7 @@ func (v *VARIANT) ToIUnknown() *IUnknown { return (*IUnknown)(unsafe.Pointer(uintptr(v.Val))) } +// ToIDispatch converts variant to dispatch object. func (v *VARIANT) ToIDispatch() *IDispatch { if v.VT != VT_DISPATCH { return nil @@ -22,14 +23,18 @@ func (v *VARIANT) ToIDispatch() *IDispatch { return (*IDispatch)(unsafe.Pointer(uintptr(v.Val))) } +// ToArray converts variant to SafeArray helper. func (v *VARIANT) ToArray() *SafeArrayConversion { if v.VT != VT_SAFEARRAY { - return nil + if v.VT&VT_ARRAY == 0 { + return nil + } } var safeArray *SafeArray = (*SafeArray)(unsafe.Pointer(uintptr(v.Val))) return &SafeArrayConversion{safeArray} } +// ToString converts variant to Go string. func (v *VARIANT) ToString() string { if v.VT != VT_BSTR { return "" @@ -37,14 +42,18 @@ func (v *VARIANT) ToString() string { return BstrToString(*(**uint16)(unsafe.Pointer(&v.Val))) } +// Clear the memory of variant object. func (v *VARIANT) Clear() error { return VariantClear(v) } -// Returns v's value based on its VALTYPE. +// Value returns variant value based on its type. +// // Currently supported types: 2- and 4-byte integers, strings, bools. // Note that 64-bit integers, datetimes, and other types are stored as strings // and will be returned as strings. +// +// Needs to be further converted, because this returns an interface{}. func (v *VARIANT) Value() interface{} { switch v.VT { case VT_I1: @@ -57,26 +66,34 @@ func (v *VARIANT) Value() interface{} { return uint16(v.Val) case VT_I4: return int32(v.Val) - case VT_UINT: - return uint32(v.Val) - case VT_INT_PTR: - return uintptr(v.Val) // TODO - case VT_UINT_PTR: - return uintptr(v.Val) case VT_UI4: return uint32(v.Val) case VT_I8: return int64(v.Val) case VT_UI8: return uint64(v.Val) + case VT_INT: + return int(v.Val) + case VT_UINT: + return uint(v.Val) + case VT_INT_PTR: + return uintptr(v.Val) // TODO + case VT_UINT_PTR: + return uintptr(v.Val) case VT_R4: - return float32(v.Val) + return *(*float32)(unsafe.Pointer(&v.Val)) case VT_R8: - return float64(v.Val) + return *(*float64)(unsafe.Pointer(&v.Val)) case VT_BSTR: return v.ToString() - //case VT_DATE: - // return v.ToIDispatch() // TODO: use VariantTimeToSystemTime + case VT_DATE: + // VT_DATE type will either return float64 or time.Time. + d := float64(v.Val) + date, err := GetVariantDate(d) + if err != nil { + return d + } + return date case VT_UNKNOWN: return v.ToIUnknown() case VT_DISPATCH: diff --git a/vendor/github.com/mattn/go-ole/variant_386.go b/vendor/github.com/go-ole/go-ole/variant_386.go similarity index 90% rename from vendor/github.com/mattn/go-ole/variant_386.go rename to vendor/github.com/go-ole/go-ole/variant_386.go index fe66afe35..e73736bf3 100644 --- a/vendor/github.com/mattn/go-ole/variant_386.go +++ b/vendor/github.com/go-ole/go-ole/variant_386.go @@ -1,5 +1,4 @@ // +build 386 -// +build windows package ole diff --git a/vendor/github.com/mattn/go-ole/variant_amd64.go b/vendor/github.com/go-ole/go-ole/variant_amd64.go similarity index 92% rename from vendor/github.com/mattn/go-ole/variant_amd64.go rename to vendor/github.com/go-ole/go-ole/variant_amd64.go index c48f6ea59..dccdde132 100644 --- a/vendor/github.com/mattn/go-ole/variant_amd64.go +++ b/vendor/github.com/go-ole/go-ole/variant_amd64.go @@ -1,5 +1,4 @@ // +build amd64 -// +build windows package ole diff --git a/vendor/github.com/go-ole/go-ole/variant_s390x.go b/vendor/github.com/go-ole/go-ole/variant_s390x.go new file mode 100644 index 000000000..9874ca66b --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_s390x.go @@ -0,0 +1,12 @@ +// +build s390x + +package ole + +type VARIANT struct { + VT VT // 2 + wReserved1 uint16 // 4 + wReserved2 uint16 // 6 + wReserved3 uint16 // 8 + Val int64 // 16 + _ [8]byte // 24 +} diff --git a/vendor/github.com/mattn/go-ole/vt_string.go b/vendor/github.com/go-ole/go-ole/vt_string.go similarity index 100% rename from vendor/github.com/mattn/go-ole/vt_string.go rename to vendor/github.com/go-ole/go-ole/vt_string.go diff --git a/vendor/github.com/mattn/go-ole/winrt.go b/vendor/github.com/go-ole/go-ole/winrt.go similarity index 92% rename from vendor/github.com/mattn/go-ole/winrt.go rename to vendor/github.com/go-ole/go-ole/winrt.go index 7d3e5aefa..4e9eca732 100644 --- a/vendor/github.com/mattn/go-ole/winrt.go +++ b/vendor/github.com/go-ole/go-ole/winrt.go @@ -59,8 +59,10 @@ func RoGetActivationFactory(clsid string, iid *GUID) (ins *IInspectable, err err return } +// HString is handle string for pointers. type HString uintptr +// NewHString returns a new HString for Go string. func NewHString(s string) (hstring HString, err error) { u16 := syscall.StringToUTF16Ptr(s) len := uint32(utf8.RuneCountInString(s)) @@ -74,6 +76,7 @@ func NewHString(s string) (hstring HString, err error) { return } +// DeleteHString deletes HString. func DeleteHString(hstring HString) (err error) { hr, _, _ := procWindowsDeleteString.Call(uintptr(hstring)) if hr != 0 { @@ -82,6 +85,7 @@ func DeleteHString(hstring HString) (err error) { return } +// String returns Go string value of HString. func (h HString) String() string { var u16buf uintptr var u16len uint32 diff --git a/vendor/github.com/go-ole/go-ole/winrt_doc.go b/vendor/github.com/go-ole/go-ole/winrt_doc.go new file mode 100644 index 000000000..52e6d74c9 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/winrt_doc.go @@ -0,0 +1,36 @@ +// +build !windows + +package ole + +// RoInitialize +func RoInitialize(thread_type uint32) (err error) { + return NewError(E_NOTIMPL) +} + +// RoActivateInstance +func RoActivateInstance(clsid string) (ins *IInspectable, err error) { + return nil, NewError(E_NOTIMPL) +} + +// RoGetActivationFactory +func RoGetActivationFactory(clsid string, iid *GUID) (ins *IInspectable, err error) { + return nil, NewError(E_NOTIMPL) +} + +// HString is handle string for pointers. +type HString uintptr + +// NewHString returns a new HString for Go string. +func NewHString(s string) (hstring HString, err error) { + return HString(uintptr(0)), NewError(E_NOTIMPL) +} + +// DeleteHString deletes HString. +func DeleteHString(hstring HString) (err error) { + return NewError(E_NOTIMPL) +} + +// String returns Go string value of HString. +func (h HString) String() string { + return "" +} diff --git a/vendor/github.com/go-stack/stack/LICENSE.md b/vendor/github.com/go-stack/stack/LICENSE.md new file mode 100644 index 000000000..2abf98ea8 --- /dev/null +++ b/vendor/github.com/go-stack/stack/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Chris Hines + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/go-stack/stack/stack.go b/vendor/github.com/go-stack/stack/stack.go new file mode 100644 index 000000000..ac3b93b14 --- /dev/null +++ b/vendor/github.com/go-stack/stack/stack.go @@ -0,0 +1,400 @@ +// +build go1.7 + +// Package stack implements utilities to capture, manipulate, and format call +// stacks. It provides a simpler API than package runtime. +// +// The implementation takes care of the minutia and special cases of +// interpreting the program counter (pc) values returned by runtime.Callers. +// +// Package stack's types implement fmt.Formatter, which provides a simple and +// flexible way to declaratively configure formatting when used with logging +// or error tracking packages. +package stack + +import ( + "bytes" + "errors" + "fmt" + "io" + "runtime" + "strconv" + "strings" +) + +// Call records a single function invocation from a goroutine stack. +type Call struct { + frame runtime.Frame +} + +// Caller returns a Call from the stack of the current goroutine. The argument +// skip is the number of stack frames to ascend, with 0 identifying the +// calling function. +func Caller(skip int) Call { + // As of Go 1.9 we need room for up to three PC entries. + // + // 0. An entry for the stack frame prior to the target to check for + // special handling needed if that prior entry is runtime.sigpanic. + // 1. A possible second entry to hold metadata about skipped inlined + // functions. If inline functions were not skipped the target frame + // PC will be here. + // 2. A third entry for the target frame PC when the second entry + // is used for skipped inline functions. + var pcs [3]uintptr + n := runtime.Callers(skip+1, pcs[:]) + frames := runtime.CallersFrames(pcs[:n]) + frame, _ := frames.Next() + frame, _ = frames.Next() + + return Call{ + frame: frame, + } +} + +// String implements fmt.Stinger. It is equivalent to fmt.Sprintf("%v", c). +func (c Call) String() string { + return fmt.Sprint(c) +} + +// MarshalText implements encoding.TextMarshaler. It formats the Call the same +// as fmt.Sprintf("%v", c). +func (c Call) MarshalText() ([]byte, error) { + if c.frame == (runtime.Frame{}) { + return nil, ErrNoFunc + } + + buf := bytes.Buffer{} + fmt.Fprint(&buf, c) + return buf.Bytes(), nil +} + +// ErrNoFunc means that the Call has a nil *runtime.Func. The most likely +// cause is a Call with the zero value. +var ErrNoFunc = errors.New("no call stack information") + +// Format implements fmt.Formatter with support for the following verbs. +// +// %s source file +// %d line number +// %n function name +// %k last segment of the package path +// %v equivalent to %s:%d +// +// It accepts the '+' and '#' flags for most of the verbs as follows. +// +// %+s path of source file relative to the compile time GOPATH, +// or the module path joined to the path of source file relative +// to module root +// %#s full path of source file +// %+n import path qualified function name +// %+k full package path +// %+v equivalent to %+s:%d +// %#v equivalent to %#s:%d +func (c Call) Format(s fmt.State, verb rune) { + if c.frame == (runtime.Frame{}) { + fmt.Fprintf(s, "%%!%c(NOFUNC)", verb) + return + } + + switch verb { + case 's', 'v': + file := c.frame.File + switch { + case s.Flag('#'): + // done + case s.Flag('+'): + file = pkgFilePath(&c.frame) + default: + const sep = "/" + if i := strings.LastIndex(file, sep); i != -1 { + file = file[i+len(sep):] + } + } + io.WriteString(s, file) + if verb == 'v' { + buf := [7]byte{':'} + s.Write(strconv.AppendInt(buf[:1], int64(c.frame.Line), 10)) + } + + case 'd': + buf := [6]byte{} + s.Write(strconv.AppendInt(buf[:0], int64(c.frame.Line), 10)) + + case 'k': + name := c.frame.Function + const pathSep = "/" + start, end := 0, len(name) + if i := strings.LastIndex(name, pathSep); i != -1 { + start = i + len(pathSep) + } + const pkgSep = "." + if i := strings.Index(name[start:], pkgSep); i != -1 { + end = start + i + } + if s.Flag('+') { + start = 0 + } + io.WriteString(s, name[start:end]) + + case 'n': + name := c.frame.Function + if !s.Flag('+') { + const pathSep = "/" + if i := strings.LastIndex(name, pathSep); i != -1 { + name = name[i+len(pathSep):] + } + const pkgSep = "." + if i := strings.Index(name, pkgSep); i != -1 { + name = name[i+len(pkgSep):] + } + } + io.WriteString(s, name) + } +} + +// Frame returns the call frame infomation for the Call. +func (c Call) Frame() runtime.Frame { + return c.frame +} + +// PC returns the program counter for this call frame; multiple frames may +// have the same PC value. +// +// Deprecated: Use Call.Frame instead. +func (c Call) PC() uintptr { + return c.frame.PC +} + +// CallStack records a sequence of function invocations from a goroutine +// stack. +type CallStack []Call + +// String implements fmt.Stinger. It is equivalent to fmt.Sprintf("%v", cs). +func (cs CallStack) String() string { + return fmt.Sprint(cs) +} + +var ( + openBracketBytes = []byte("[") + closeBracketBytes = []byte("]") + spaceBytes = []byte(" ") +) + +// MarshalText implements encoding.TextMarshaler. It formats the CallStack the +// same as fmt.Sprintf("%v", cs). +func (cs CallStack) MarshalText() ([]byte, error) { + buf := bytes.Buffer{} + buf.Write(openBracketBytes) + for i, pc := range cs { + if i > 0 { + buf.Write(spaceBytes) + } + fmt.Fprint(&buf, pc) + } + buf.Write(closeBracketBytes) + return buf.Bytes(), nil +} + +// Format implements fmt.Formatter by printing the CallStack as square brackets +// ([, ]) surrounding a space separated list of Calls each formatted with the +// supplied verb and options. +func (cs CallStack) Format(s fmt.State, verb rune) { + s.Write(openBracketBytes) + for i, pc := range cs { + if i > 0 { + s.Write(spaceBytes) + } + pc.Format(s, verb) + } + s.Write(closeBracketBytes) +} + +// Trace returns a CallStack for the current goroutine with element 0 +// identifying the calling function. +func Trace() CallStack { + var pcs [512]uintptr + n := runtime.Callers(1, pcs[:]) + + frames := runtime.CallersFrames(pcs[:n]) + cs := make(CallStack, 0, n) + + // Skip extra frame retrieved just to make sure the runtime.sigpanic + // special case is handled. + frame, more := frames.Next() + + for more { + frame, more = frames.Next() + cs = append(cs, Call{frame: frame}) + } + + return cs +} + +// TrimBelow returns a slice of the CallStack with all entries below c +// removed. +func (cs CallStack) TrimBelow(c Call) CallStack { + for len(cs) > 0 && cs[0] != c { + cs = cs[1:] + } + return cs +} + +// TrimAbove returns a slice of the CallStack with all entries above c +// removed. +func (cs CallStack) TrimAbove(c Call) CallStack { + for len(cs) > 0 && cs[len(cs)-1] != c { + cs = cs[:len(cs)-1] + } + return cs +} + +// pkgIndex returns the index that results in file[index:] being the path of +// file relative to the compile time GOPATH, and file[:index] being the +// $GOPATH/src/ portion of file. funcName must be the name of a function in +// file as returned by runtime.Func.Name. +func pkgIndex(file, funcName string) int { + // As of Go 1.6.2 there is no direct way to know the compile time GOPATH + // at runtime, but we can infer the number of path segments in the GOPATH. + // We note that runtime.Func.Name() returns the function name qualified by + // the import path, which does not include the GOPATH. Thus we can trim + // segments from the beginning of the file path until the number of path + // separators remaining is one more than the number of path separators in + // the function name. For example, given: + // + // GOPATH /home/user + // file /home/user/src/pkg/sub/file.go + // fn.Name() pkg/sub.Type.Method + // + // We want to produce: + // + // file[:idx] == /home/user/src/ + // file[idx:] == pkg/sub/file.go + // + // From this we can easily see that fn.Name() has one less path separator + // than our desired result for file[idx:]. We count separators from the + // end of the file path until it finds two more than in the function name + // and then move one character forward to preserve the initial path + // segment without a leading separator. + const sep = "/" + i := len(file) + for n := strings.Count(funcName, sep) + 2; n > 0; n-- { + i = strings.LastIndex(file[:i], sep) + if i == -1 { + i = -len(sep) + break + } + } + // get back to 0 or trim the leading separator + return i + len(sep) +} + +// pkgFilePath returns the frame's filepath relative to the compile-time GOPATH, +// or its module path joined to its path relative to the module root. +// +// As of Go 1.11 there is no direct way to know the compile time GOPATH or +// module paths at runtime, but we can piece together the desired information +// from available information. We note that runtime.Frame.Function contains the +// function name qualified by the package path, which includes the module path +// but not the GOPATH. We can extract the package path from that and append the +// last segments of the file path to arrive at the desired package qualified +// file path. For example, given: +// +// GOPATH /home/user +// import path pkg/sub +// frame.File /home/user/src/pkg/sub/file.go +// frame.Function pkg/sub.Type.Method +// Desired return pkg/sub/file.go +// +// It appears that we simply need to trim ".Type.Method" from frame.Function and +// append "/" + path.Base(file). +// +// But there are other wrinkles. Although it is idiomatic to do so, the internal +// name of a package is not required to match the last segment of its import +// path. In addition, the introduction of modules in Go 1.11 allows working +// without a GOPATH. So we also must make these work right: +// +// GOPATH /home/user +// import path pkg/go-sub +// package name sub +// frame.File /home/user/src/pkg/go-sub/file.go +// frame.Function pkg/sub.Type.Method +// Desired return pkg/go-sub/file.go +// +// Module path pkg/v2 +// import path pkg/v2/go-sub +// package name sub +// frame.File /home/user/cloned-pkg/go-sub/file.go +// frame.Function pkg/v2/sub.Type.Method +// Desired return pkg/v2/go-sub/file.go +// +// We can handle all of these situations by using the package path extracted +// from frame.Function up to, but not including, the last segment as the prefix +// and the last two segments of frame.File as the suffix of the returned path. +// This preserves the existing behavior when working in a GOPATH without modules +// and a semantically equivalent behavior when used in module aware project. +func pkgFilePath(frame *runtime.Frame) string { + pre := pkgPrefix(frame.Function) + post := pathSuffix(frame.File) + if pre == "" { + return post + } + return pre + "/" + post +} + +// pkgPrefix returns the import path of the function's package with the final +// segment removed. +func pkgPrefix(funcName string) string { + const pathSep = "/" + end := strings.LastIndex(funcName, pathSep) + if end == -1 { + return "" + } + return funcName[:end] +} + +// pathSuffix returns the last two segments of path. +func pathSuffix(path string) string { + const pathSep = "/" + lastSep := strings.LastIndex(path, pathSep) + if lastSep == -1 { + return path + } + return path[strings.LastIndex(path[:lastSep], pathSep)+1:] +} + +var runtimePath string + +func init() { + var pcs [3]uintptr + runtime.Callers(0, pcs[:]) + frames := runtime.CallersFrames(pcs[:]) + frame, _ := frames.Next() + file := frame.File + + idx := pkgIndex(frame.File, frame.Function) + + runtimePath = file[:idx] + if runtime.GOOS == "windows" { + runtimePath = strings.ToLower(runtimePath) + } +} + +func inGoroot(c Call) bool { + file := c.frame.File + if len(file) == 0 || file[0] == '?' { + return true + } + if runtime.GOOS == "windows" { + file = strings.ToLower(file) + } + return strings.HasPrefix(file, runtimePath) || strings.HasSuffix(file, "/_testmain.go") +} + +// TrimRuntime returns a slice of the CallStack with the topmost entries from +// the go runtime removed. It considers any calls originating from unknown +// files, files under GOROOT, or _testmain.go as part of the runtime. +func (cs CallStack) TrimRuntime() CallStack { + for len(cs) > 0 && inGoroot(cs[len(cs)-1]) { + cs = cs[:len(cs)-1] + } + return cs +} diff --git a/vendor/github.com/golang/protobuf/AUTHORS b/vendor/github.com/golang/protobuf/AUTHORS new file mode 100644 index 000000000..15167cd74 --- /dev/null +++ b/vendor/github.com/golang/protobuf/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/github.com/golang/protobuf/CONTRIBUTORS b/vendor/github.com/golang/protobuf/CONTRIBUTORS new file mode 100644 index 000000000..1c4577e96 --- /dev/null +++ b/vendor/github.com/golang/protobuf/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/github.com/golang/protobuf/LICENSE b/vendor/github.com/golang/protobuf/LICENSE new file mode 100644 index 000000000..0f646931a --- /dev/null +++ b/vendor/github.com/golang/protobuf/LICENSE @@ -0,0 +1,28 @@ +Copyright 2010 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/vendor/github.com/golang/protobuf/proto/clone.go b/vendor/github.com/golang/protobuf/proto/clone.go new file mode 100644 index 000000000..3cd3249f7 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/clone.go @@ -0,0 +1,253 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Protocol buffer deep copy and merge. +// TODO: RawMessage. + +package proto + +import ( + "fmt" + "log" + "reflect" + "strings" +) + +// Clone returns a deep copy of a protocol buffer. +func Clone(src Message) Message { + in := reflect.ValueOf(src) + if in.IsNil() { + return src + } + out := reflect.New(in.Type().Elem()) + dst := out.Interface().(Message) + Merge(dst, src) + return dst +} + +// Merger is the interface representing objects that can merge messages of the same type. +type Merger interface { + // Merge merges src into this message. + // Required and optional fields that are set in src will be set to that value in dst. + // Elements of repeated fields will be appended. + // + // Merge may panic if called with a different argument type than the receiver. + Merge(src Message) +} + +// generatedMerger is the custom merge method that generated protos will have. +// We must add this method since a generate Merge method will conflict with +// many existing protos that have a Merge data field already defined. +type generatedMerger interface { + XXX_Merge(src Message) +} + +// Merge merges src into dst. +// Required and optional fields that are set in src will be set to that value in dst. +// Elements of repeated fields will be appended. +// Merge panics if src and dst are not the same type, or if dst is nil. +func Merge(dst, src Message) { + if m, ok := dst.(Merger); ok { + m.Merge(src) + return + } + + in := reflect.ValueOf(src) + out := reflect.ValueOf(dst) + if out.IsNil() { + panic("proto: nil destination") + } + if in.Type() != out.Type() { + panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src)) + } + if in.IsNil() { + return // Merge from nil src is a noop + } + if m, ok := dst.(generatedMerger); ok { + m.XXX_Merge(src) + return + } + mergeStruct(out.Elem(), in.Elem()) +} + +func mergeStruct(out, in reflect.Value) { + sprop := GetProperties(in.Type()) + for i := 0; i < in.NumField(); i++ { + f := in.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) + } + + if emIn, err := extendable(in.Addr().Interface()); err == nil { + emOut, _ := extendable(out.Addr().Interface()) + mIn, muIn := emIn.extensionsRead() + if mIn != nil { + mOut := emOut.extensionsWrite() + muIn.Lock() + mergeExtension(mOut, mIn) + muIn.Unlock() + } + } + + uf := in.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return + } + uin := uf.Bytes() + if len(uin) > 0 { + out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) + } +} + +// mergeAny performs a merge between two values of the same type. +// viaPtr indicates whether the values were indirected through a pointer (implying proto2). +// prop is set if this is a struct field (it may be nil). +func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { + if in.Type() == protoMessageType { + if !in.IsNil() { + if out.IsNil() { + out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) + } else { + Merge(out.Interface().(Message), in.Interface().(Message)) + } + } + return + } + switch in.Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, + reflect.String, reflect.Uint32, reflect.Uint64: + if !viaPtr && isProto3Zero(in) { + return + } + out.Set(in) + case reflect.Interface: + // Probably a oneof field; copy non-nil values. + if in.IsNil() { + return + } + // Allocate destination if it is not set, or set to a different type. + // Otherwise we will merge as normal. + if out.IsNil() || out.Elem().Type() != in.Elem().Type() { + out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) + } + mergeAny(out.Elem(), in.Elem(), false, nil) + case reflect.Map: + if in.Len() == 0 { + return + } + if out.IsNil() { + out.Set(reflect.MakeMap(in.Type())) + } + // For maps with value types of *T or []byte we need to deep copy each value. + elemKind := in.Type().Elem().Kind() + for _, key := range in.MapKeys() { + var val reflect.Value + switch elemKind { + case reflect.Ptr: + val = reflect.New(in.Type().Elem().Elem()) + mergeAny(val, in.MapIndex(key), false, nil) + case reflect.Slice: + val = in.MapIndex(key) + val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) + default: + val = in.MapIndex(key) + } + out.SetMapIndex(key, val) + } + case reflect.Ptr: + if in.IsNil() { + return + } + if out.IsNil() { + out.Set(reflect.New(in.Elem().Type())) + } + mergeAny(out.Elem(), in.Elem(), true, nil) + case reflect.Slice: + if in.IsNil() { + return + } + if in.Type().Elem().Kind() == reflect.Uint8 { + // []byte is a scalar bytes field, not a repeated field. + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value, and should not + // be merged. + if prop != nil && prop.proto3 && in.Len() == 0 { + return + } + + // Make a deep copy. + // Append to []byte{} instead of []byte(nil) so that we never end up + // with a nil result. + out.SetBytes(append([]byte{}, in.Bytes()...)) + return + } + n := in.Len() + if out.IsNil() { + out.Set(reflect.MakeSlice(in.Type(), 0, n)) + } + switch in.Type().Elem().Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, + reflect.String, reflect.Uint32, reflect.Uint64: + out.Set(reflect.AppendSlice(out, in)) + default: + for i := 0; i < n; i++ { + x := reflect.Indirect(reflect.New(in.Type().Elem())) + mergeAny(x, in.Index(i), false, nil) + out.Set(reflect.Append(out, x)) + } + } + case reflect.Struct: + mergeStruct(out, in) + default: + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to copy %v", in) + } +} + +func mergeExtension(out, in map[int32]Extension) { + for extNum, eIn := range in { + eOut := Extension{desc: eIn.desc} + if eIn.value != nil { + v := reflect.New(reflect.TypeOf(eIn.value)).Elem() + mergeAny(v, reflect.ValueOf(eIn.value), false, nil) + eOut.value = v.Interface() + } + if eIn.enc != nil { + eOut.enc = make([]byte, len(eIn.enc)) + copy(eOut.enc, eIn.enc) + } + + out[extNum] = eOut + } +} diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go new file mode 100644 index 000000000..d9aa3c42d --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/decode.go @@ -0,0 +1,428 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Routines for decoding protocol buffer data to construct in-memory representations. + */ + +import ( + "errors" + "fmt" + "io" +) + +// errOverflow is returned when an integer is too large to be represented. +var errOverflow = errors.New("proto: integer overflow") + +// ErrInternalBadWireType is returned by generated code when an incorrect +// wire type is encountered. It does not get returned to user code. +var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") + +// DecodeVarint reads a varint-encoded integer from the slice. +// It returns the integer and the number of bytes consumed, or +// zero if there is not enough. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func DecodeVarint(buf []byte) (x uint64, n int) { + for shift := uint(0); shift < 64; shift += 7 { + if n >= len(buf) { + return 0, 0 + } + b := uint64(buf[n]) + n++ + x |= (b & 0x7F) << shift + if (b & 0x80) == 0 { + return x, n + } + } + + // The number is too large to represent in a 64-bit value. + return 0, 0 +} + +func (p *Buffer) decodeVarintSlow() (x uint64, err error) { + i := p.index + l := len(p.buf) + + for shift := uint(0); shift < 64; shift += 7 { + if i >= l { + err = io.ErrUnexpectedEOF + return + } + b := p.buf[i] + i++ + x |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + p.index = i + return + } + } + + // The number is too large to represent in a 64-bit value. + err = errOverflow + return +} + +// DecodeVarint reads a varint-encoded integer from the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) DecodeVarint() (x uint64, err error) { + i := p.index + buf := p.buf + + if i >= len(buf) { + return 0, io.ErrUnexpectedEOF + } else if buf[i] < 0x80 { + p.index++ + return uint64(buf[i]), nil + } else if len(buf)-i < 10 { + return p.decodeVarintSlow() + } + + var b uint64 + // we already checked the first byte + x = uint64(buf[i]) - 0x80 + i++ + + b = uint64(buf[i]) + i++ + x += b << 7 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 7 + + b = uint64(buf[i]) + i++ + x += b << 14 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 14 + + b = uint64(buf[i]) + i++ + x += b << 21 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 21 + + b = uint64(buf[i]) + i++ + x += b << 28 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 28 + + b = uint64(buf[i]) + i++ + x += b << 35 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 35 + + b = uint64(buf[i]) + i++ + x += b << 42 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 42 + + b = uint64(buf[i]) + i++ + x += b << 49 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 49 + + b = uint64(buf[i]) + i++ + x += b << 56 + if b&0x80 == 0 { + goto done + } + x -= 0x80 << 56 + + b = uint64(buf[i]) + i++ + x += b << 63 + if b&0x80 == 0 { + goto done + } + // x -= 0x80 << 63 // Always zero. + + return 0, errOverflow + +done: + p.index = i + return x, nil +} + +// DecodeFixed64 reads a 64-bit integer from the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) DecodeFixed64() (x uint64, err error) { + // x, err already 0 + i := p.index + 8 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-8]) + x |= uint64(p.buf[i-7]) << 8 + x |= uint64(p.buf[i-6]) << 16 + x |= uint64(p.buf[i-5]) << 24 + x |= uint64(p.buf[i-4]) << 32 + x |= uint64(p.buf[i-3]) << 40 + x |= uint64(p.buf[i-2]) << 48 + x |= uint64(p.buf[i-1]) << 56 + return +} + +// DecodeFixed32 reads a 32-bit integer from the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) DecodeFixed32() (x uint64, err error) { + // x, err already 0 + i := p.index + 4 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-4]) + x |= uint64(p.buf[i-3]) << 8 + x |= uint64(p.buf[i-2]) << 16 + x |= uint64(p.buf[i-1]) << 24 + return +} + +// DecodeZigzag64 reads a zigzag-encoded 64-bit integer +// from the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) DecodeZigzag64() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) + return +} + +// DecodeZigzag32 reads a zigzag-encoded 32-bit integer +// from the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) DecodeZigzag32() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) + return +} + +// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { + n, err := p.DecodeVarint() + if err != nil { + return nil, err + } + + nb := int(n) + if nb < 0 { + return nil, fmt.Errorf("proto: bad byte length %d", nb) + } + end := p.index + nb + if end < p.index || end > len(p.buf) { + return nil, io.ErrUnexpectedEOF + } + + if !alloc { + // todo: check if can get more uses of alloc=false + buf = p.buf[p.index:end] + p.index += nb + return + } + + buf = make([]byte, nb) + copy(buf, p.buf[p.index:]) + p.index += nb + return +} + +// DecodeStringBytes reads an encoded string from the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) DecodeStringBytes() (s string, err error) { + buf, err := p.DecodeRawBytes(false) + if err != nil { + return + } + return string(buf), nil +} + +// Unmarshaler is the interface representing objects that can +// unmarshal themselves. The argument points to data that may be +// overwritten, so implementations should not keep references to the +// buffer. +// Unmarshal implementations should not clear the receiver. +// Any unmarshaled data should be merged into the receiver. +// Callers of Unmarshal that do not want to retain existing data +// should Reset the receiver before calling Unmarshal. +type Unmarshaler interface { + Unmarshal([]byte) error +} + +// newUnmarshaler is the interface representing objects that can +// unmarshal themselves. The semantics are identical to Unmarshaler. +// +// This exists to support protoc-gen-go generated messages. +// The proto package will stop type-asserting to this interface in the future. +// +// DO NOT DEPEND ON THIS. +type newUnmarshaler interface { + XXX_Unmarshal([]byte) error +} + +// Unmarshal parses the protocol buffer representation in buf and places the +// decoded result in pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// Unmarshal resets pb before starting to unmarshal, so any +// existing data in pb is always removed. Use UnmarshalMerge +// to preserve and append to existing data. +func Unmarshal(buf []byte, pb Message) error { + pb.Reset() + if u, ok := pb.(newUnmarshaler); ok { + return u.XXX_Unmarshal(buf) + } + if u, ok := pb.(Unmarshaler); ok { + return u.Unmarshal(buf) + } + return NewBuffer(buf).Unmarshal(pb) +} + +// UnmarshalMerge parses the protocol buffer representation in buf and +// writes the decoded result to pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// UnmarshalMerge merges into existing data in pb. +// Most code should use Unmarshal instead. +func UnmarshalMerge(buf []byte, pb Message) error { + if u, ok := pb.(newUnmarshaler); ok { + return u.XXX_Unmarshal(buf) + } + if u, ok := pb.(Unmarshaler); ok { + // NOTE: The history of proto have unfortunately been inconsistent + // whether Unmarshaler should or should not implicitly clear itself. + // Some implementations do, most do not. + // Thus, calling this here may or may not do what people want. + // + // See https://github.com/golang/protobuf/issues/424 + return u.Unmarshal(buf) + } + return NewBuffer(buf).Unmarshal(pb) +} + +// DecodeMessage reads a count-delimited message from the Buffer. +func (p *Buffer) DecodeMessage(pb Message) error { + enc, err := p.DecodeRawBytes(false) + if err != nil { + return err + } + return NewBuffer(enc).Unmarshal(pb) +} + +// DecodeGroup reads a tag-delimited group from the Buffer. +// StartGroup tag is already consumed. This function consumes +// EndGroup tag. +func (p *Buffer) DecodeGroup(pb Message) error { + b := p.buf[p.index:] + x, y := findEndGroup(b) + if x < 0 { + return io.ErrUnexpectedEOF + } + err := Unmarshal(b[:x], pb) + p.index += y + return err +} + +// Unmarshal parses the protocol buffer representation in the +// Buffer and places the decoded result in pb. If the struct +// underlying pb does not match the data in the buffer, the results can be +// unpredictable. +// +// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. +func (p *Buffer) Unmarshal(pb Message) error { + // If the object can unmarshal itself, let it. + if u, ok := pb.(newUnmarshaler); ok { + err := u.XXX_Unmarshal(p.buf[p.index:]) + p.index = len(p.buf) + return err + } + if u, ok := pb.(Unmarshaler); ok { + // NOTE: The history of proto have unfortunately been inconsistent + // whether Unmarshaler should or should not implicitly clear itself. + // Some implementations do, most do not. + // Thus, calling this here may or may not do what people want. + // + // See https://github.com/golang/protobuf/issues/424 + err := u.Unmarshal(p.buf[p.index:]) + p.index = len(p.buf) + return err + } + + // Slow workaround for messages that aren't Unmarshalers. + // This includes some hand-coded .pb.go files and + // bootstrap protos. + // TODO: fix all of those and then add Unmarshal to + // the Message interface. Then: + // The cast above and code below can be deleted. + // The old unmarshaler can be deleted. + // Clients can call Unmarshal directly (can already do that, actually). + var info InternalMessageInfo + err := info.Unmarshal(pb, p.buf[p.index:]) + p.index = len(p.buf) + return err +} diff --git a/vendor/github.com/golang/protobuf/proto/discard.go b/vendor/github.com/golang/protobuf/proto/discard.go new file mode 100644 index 000000000..dea2617ce --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/discard.go @@ -0,0 +1,350 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2017 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +import ( + "fmt" + "reflect" + "strings" + "sync" + "sync/atomic" +) + +type generatedDiscarder interface { + XXX_DiscardUnknown() +} + +// DiscardUnknown recursively discards all unknown fields from this message +// and all embedded messages. +// +// When unmarshaling a message with unrecognized fields, the tags and values +// of such fields are preserved in the Message. This allows a later call to +// marshal to be able to produce a message that continues to have those +// unrecognized fields. To avoid this, DiscardUnknown is used to +// explicitly clear the unknown fields after unmarshaling. +// +// For proto2 messages, the unknown fields of message extensions are only +// discarded from messages that have been accessed via GetExtension. +func DiscardUnknown(m Message) { + if m, ok := m.(generatedDiscarder); ok { + m.XXX_DiscardUnknown() + return + } + // TODO: Dynamically populate a InternalMessageInfo for legacy messages, + // but the master branch has no implementation for InternalMessageInfo, + // so it would be more work to replicate that approach. + discardLegacy(m) +} + +// DiscardUnknown recursively discards all unknown fields. +func (a *InternalMessageInfo) DiscardUnknown(m Message) { + di := atomicLoadDiscardInfo(&a.discard) + if di == nil { + di = getDiscardInfo(reflect.TypeOf(m).Elem()) + atomicStoreDiscardInfo(&a.discard, di) + } + di.discard(toPointer(&m)) +} + +type discardInfo struct { + typ reflect.Type + + initialized int32 // 0: only typ is valid, 1: everything is valid + lock sync.Mutex + + fields []discardFieldInfo + unrecognized field +} + +type discardFieldInfo struct { + field field // Offset of field, guaranteed to be valid + discard func(src pointer) +} + +var ( + discardInfoMap = map[reflect.Type]*discardInfo{} + discardInfoLock sync.Mutex +) + +func getDiscardInfo(t reflect.Type) *discardInfo { + discardInfoLock.Lock() + defer discardInfoLock.Unlock() + di := discardInfoMap[t] + if di == nil { + di = &discardInfo{typ: t} + discardInfoMap[t] = di + } + return di +} + +func (di *discardInfo) discard(src pointer) { + if src.isNil() { + return // Nothing to do. + } + + if atomic.LoadInt32(&di.initialized) == 0 { + di.computeDiscardInfo() + } + + for _, fi := range di.fields { + sfp := src.offset(fi.field) + fi.discard(sfp) + } + + // For proto2 messages, only discard unknown fields in message extensions + // that have been accessed via GetExtension. + if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil { + // Ignore lock since DiscardUnknown is not concurrency safe. + emm, _ := em.extensionsRead() + for _, mx := range emm { + if m, ok := mx.value.(Message); ok { + DiscardUnknown(m) + } + } + } + + if di.unrecognized.IsValid() { + *src.offset(di.unrecognized).toBytes() = nil + } +} + +func (di *discardInfo) computeDiscardInfo() { + di.lock.Lock() + defer di.lock.Unlock() + if di.initialized != 0 { + return + } + t := di.typ + n := t.NumField() + + for i := 0; i < n; i++ { + f := t.Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + + dfi := discardFieldInfo{field: toField(&f)} + tf := f.Type + + // Unwrap tf to get its most basic type. + var isPointer, isSlice bool + if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { + isSlice = true + tf = tf.Elem() + } + if tf.Kind() == reflect.Ptr { + isPointer = true + tf = tf.Elem() + } + if isPointer && isSlice && tf.Kind() != reflect.Struct { + panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name)) + } + + switch tf.Kind() { + case reflect.Struct: + switch { + case !isPointer: + panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name)) + case isSlice: // E.g., []*pb.T + di := getDiscardInfo(tf) + dfi.discard = func(src pointer) { + sps := src.getPointerSlice() + for _, sp := range sps { + if !sp.isNil() { + di.discard(sp) + } + } + } + default: // E.g., *pb.T + di := getDiscardInfo(tf) + dfi.discard = func(src pointer) { + sp := src.getPointer() + if !sp.isNil() { + di.discard(sp) + } + } + } + case reflect.Map: + switch { + case isPointer || isSlice: + panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name)) + default: // E.g., map[K]V + if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T) + dfi.discard = func(src pointer) { + sm := src.asPointerTo(tf).Elem() + if sm.Len() == 0 { + return + } + for _, key := range sm.MapKeys() { + val := sm.MapIndex(key) + DiscardUnknown(val.Interface().(Message)) + } + } + } else { + dfi.discard = func(pointer) {} // Noop + } + } + case reflect.Interface: + // Must be oneof field. + switch { + case isPointer || isSlice: + panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name)) + default: // E.g., interface{} + // TODO: Make this faster? + dfi.discard = func(src pointer) { + su := src.asPointerTo(tf).Elem() + if !su.IsNil() { + sv := su.Elem().Elem().Field(0) + if sv.Kind() == reflect.Ptr && sv.IsNil() { + return + } + switch sv.Type().Kind() { + case reflect.Ptr: // Proto struct (e.g., *T) + DiscardUnknown(sv.Interface().(Message)) + } + } + } + } + default: + continue + } + di.fields = append(di.fields, dfi) + } + + di.unrecognized = invalidField + if f, ok := t.FieldByName("XXX_unrecognized"); ok { + if f.Type != reflect.TypeOf([]byte{}) { + panic("expected XXX_unrecognized to be of type []byte") + } + di.unrecognized = toField(&f) + } + + atomic.StoreInt32(&di.initialized, 1) +} + +func discardLegacy(m Message) { + v := reflect.ValueOf(m) + if v.Kind() != reflect.Ptr || v.IsNil() { + return + } + v = v.Elem() + if v.Kind() != reflect.Struct { + return + } + t := v.Type() + + for i := 0; i < v.NumField(); i++ { + f := t.Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + vf := v.Field(i) + tf := f.Type + + // Unwrap tf to get its most basic type. + var isPointer, isSlice bool + if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { + isSlice = true + tf = tf.Elem() + } + if tf.Kind() == reflect.Ptr { + isPointer = true + tf = tf.Elem() + } + if isPointer && isSlice && tf.Kind() != reflect.Struct { + panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name)) + } + + switch tf.Kind() { + case reflect.Struct: + switch { + case !isPointer: + panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name)) + case isSlice: // E.g., []*pb.T + for j := 0; j < vf.Len(); j++ { + discardLegacy(vf.Index(j).Interface().(Message)) + } + default: // E.g., *pb.T + discardLegacy(vf.Interface().(Message)) + } + case reflect.Map: + switch { + case isPointer || isSlice: + panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name)) + default: // E.g., map[K]V + tv := vf.Type().Elem() + if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T) + for _, key := range vf.MapKeys() { + val := vf.MapIndex(key) + discardLegacy(val.Interface().(Message)) + } + } + } + case reflect.Interface: + // Must be oneof field. + switch { + case isPointer || isSlice: + panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name)) + default: // E.g., test_proto.isCommunique_Union interface + if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" { + vf = vf.Elem() // E.g., *test_proto.Communique_Msg + if !vf.IsNil() { + vf = vf.Elem() // E.g., test_proto.Communique_Msg + vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value + if vf.Kind() == reflect.Ptr { + discardLegacy(vf.Interface().(Message)) + } + } + } + } + } + } + + if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() { + if vf.Type() != reflect.TypeOf([]byte{}) { + panic("expected XXX_unrecognized to be of type []byte") + } + vf.Set(reflect.ValueOf([]byte(nil))) + } + + // For proto2 messages, only discard unknown fields in message extensions + // that have been accessed via GetExtension. + if em, err := extendable(m); err == nil { + // Ignore lock since discardLegacy is not concurrency safe. + emm, _ := em.extensionsRead() + for _, mx := range emm { + if m, ok := mx.value.(Message); ok { + discardLegacy(m) + } + } + } +} diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go new file mode 100644 index 000000000..3abfed2cf --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/encode.go @@ -0,0 +1,203 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "errors" + "reflect" +) + +var ( + // errRepeatedHasNil is the error returned if Marshal is called with + // a struct with a repeated field containing a nil element. + errRepeatedHasNil = errors.New("proto: repeated field has nil element") + + // errOneofHasNil is the error returned if Marshal is called with + // a struct with a oneof field containing a nil element. + errOneofHasNil = errors.New("proto: oneof field has nil value") + + // ErrNil is the error returned if Marshal is called with nil. + ErrNil = errors.New("proto: Marshal called with nil") + + // ErrTooLarge is the error returned if Marshal is called with a + // message that encodes to >2GB. + ErrTooLarge = errors.New("proto: message encodes to over 2 GB") +) + +// The fundamental encoders that put bytes on the wire. +// Those that take integer types all accept uint64 and are +// therefore of type valueEncoder. + +const maxVarintBytes = 10 // maximum length of a varint + +// EncodeVarint returns the varint encoding of x. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +// Not used by the package itself, but helpful to clients +// wishing to use the same encoding. +func EncodeVarint(x uint64) []byte { + var buf [maxVarintBytes]byte + var n int + for n = 0; x > 127; n++ { + buf[n] = 0x80 | uint8(x&0x7F) + x >>= 7 + } + buf[n] = uint8(x) + n++ + return buf[0:n] +} + +// EncodeVarint writes a varint-encoded integer to the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) EncodeVarint(x uint64) error { + for x >= 1<<7 { + p.buf = append(p.buf, uint8(x&0x7f|0x80)) + x >>= 7 + } + p.buf = append(p.buf, uint8(x)) + return nil +} + +// SizeVarint returns the varint encoding size of an integer. +func SizeVarint(x uint64) int { + switch { + case x < 1<<7: + return 1 + case x < 1<<14: + return 2 + case x < 1<<21: + return 3 + case x < 1<<28: + return 4 + case x < 1<<35: + return 5 + case x < 1<<42: + return 6 + case x < 1<<49: + return 7 + case x < 1<<56: + return 8 + case x < 1<<63: + return 9 + } + return 10 +} + +// EncodeFixed64 writes a 64-bit integer to the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) EncodeFixed64(x uint64) error { + p.buf = append(p.buf, + uint8(x), + uint8(x>>8), + uint8(x>>16), + uint8(x>>24), + uint8(x>>32), + uint8(x>>40), + uint8(x>>48), + uint8(x>>56)) + return nil +} + +// EncodeFixed32 writes a 32-bit integer to the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) EncodeFixed32(x uint64) error { + p.buf = append(p.buf, + uint8(x), + uint8(x>>8), + uint8(x>>16), + uint8(x>>24)) + return nil +} + +// EncodeZigzag64 writes a zigzag-encoded 64-bit integer +// to the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) EncodeZigzag64(x uint64) error { + // use signed number to get arithmetic right shift. + return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +// EncodeZigzag32 writes a zigzag-encoded 32-bit integer +// to the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) EncodeZigzag32(x uint64) error { + // use signed number to get arithmetic right shift. + return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) +} + +// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) EncodeRawBytes(b []byte) error { + p.EncodeVarint(uint64(len(b))) + p.buf = append(p.buf, b...) + return nil +} + +// EncodeStringBytes writes an encoded string to the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) EncodeStringBytes(s string) error { + p.EncodeVarint(uint64(len(s))) + p.buf = append(p.buf, s...) + return nil +} + +// Marshaler is the interface representing objects that can marshal themselves. +type Marshaler interface { + Marshal() ([]byte, error) +} + +// EncodeMessage writes the protocol buffer to the Buffer, +// prefixed by a varint-encoded length. +func (p *Buffer) EncodeMessage(pb Message) error { + siz := Size(pb) + p.EncodeVarint(uint64(siz)) + return p.Marshal(pb) +} + +// All protocol buffer fields are nillable, but be careful. +func isNil(v reflect.Value) bool { + switch v.Kind() { + case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return v.IsNil() + } + return false +} diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go new file mode 100644 index 000000000..d4db5a1c1 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/equal.go @@ -0,0 +1,300 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Protocol buffer comparison. + +package proto + +import ( + "bytes" + "log" + "reflect" + "strings" +) + +/* +Equal returns true iff protocol buffers a and b are equal. +The arguments must both be pointers to protocol buffer structs. + +Equality is defined in this way: + - Two messages are equal iff they are the same type, + corresponding fields are equal, unknown field sets + are equal, and extensions sets are equal. + - Two set scalar fields are equal iff their values are equal. + If the fields are of a floating-point type, remember that + NaN != x for all x, including NaN. If the message is defined + in a proto3 .proto file, fields are not "set"; specifically, + zero length proto3 "bytes" fields are equal (nil == {}). + - Two repeated fields are equal iff their lengths are the same, + and their corresponding elements are equal. Note a "bytes" field, + although represented by []byte, is not a repeated field and the + rule for the scalar fields described above applies. + - Two unset fields are equal. + - Two unknown field sets are equal if their current + encoded state is equal. + - Two extension sets are equal iff they have corresponding + elements that are pairwise equal. + - Two map fields are equal iff their lengths are the same, + and they contain the same set of elements. Zero-length map + fields are equal. + - Every other combination of things are not equal. + +The return value is undefined if a and b are not protocol buffers. +*/ +func Equal(a, b Message) bool { + if a == nil || b == nil { + return a == b + } + v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) + if v1.Type() != v2.Type() { + return false + } + if v1.Kind() == reflect.Ptr { + if v1.IsNil() { + return v2.IsNil() + } + if v2.IsNil() { + return false + } + v1, v2 = v1.Elem(), v2.Elem() + } + if v1.Kind() != reflect.Struct { + return false + } + return equalStruct(v1, v2) +} + +// v1 and v2 are known to have the same type. +func equalStruct(v1, v2 reflect.Value) bool { + sprop := GetProperties(v1.Type()) + for i := 0; i < v1.NumField(); i++ { + f := v1.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + f1, f2 := v1.Field(i), v2.Field(i) + if f.Type.Kind() == reflect.Ptr { + if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { + // both unset + continue + } else if n1 != n2 { + // set/unset mismatch + return false + } + f1, f2 = f1.Elem(), f2.Elem() + } + if !equalAny(f1, f2, sprop.Prop[i]) { + return false + } + } + + if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_InternalExtensions") + if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { + return false + } + } + + if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_extensions") + if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { + return false + } + } + + uf := v1.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return true + } + + u1 := uf.Bytes() + u2 := v2.FieldByName("XXX_unrecognized").Bytes() + return bytes.Equal(u1, u2) +} + +// v1 and v2 are known to have the same type. +// prop may be nil. +func equalAny(v1, v2 reflect.Value, prop *Properties) bool { + if v1.Type() == protoMessageType { + m1, _ := v1.Interface().(Message) + m2, _ := v2.Interface().(Message) + return Equal(m1, m2) + } + switch v1.Kind() { + case reflect.Bool: + return v1.Bool() == v2.Bool() + case reflect.Float32, reflect.Float64: + return v1.Float() == v2.Float() + case reflect.Int32, reflect.Int64: + return v1.Int() == v2.Int() + case reflect.Interface: + // Probably a oneof field; compare the inner values. + n1, n2 := v1.IsNil(), v2.IsNil() + if n1 || n2 { + return n1 == n2 + } + e1, e2 := v1.Elem(), v2.Elem() + if e1.Type() != e2.Type() { + return false + } + return equalAny(e1, e2, nil) + case reflect.Map: + if v1.Len() != v2.Len() { + return false + } + for _, key := range v1.MapKeys() { + val2 := v2.MapIndex(key) + if !val2.IsValid() { + // This key was not found in the second map. + return false + } + if !equalAny(v1.MapIndex(key), val2, nil) { + return false + } + } + return true + case reflect.Ptr: + // Maps may have nil values in them, so check for nil. + if v1.IsNil() && v2.IsNil() { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } + return equalAny(v1.Elem(), v2.Elem(), prop) + case reflect.Slice: + if v1.Type().Elem().Kind() == reflect.Uint8 { + // short circuit: []byte + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value. + if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } + return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) + } + + if v1.Len() != v2.Len() { + return false + } + for i := 0; i < v1.Len(); i++ { + if !equalAny(v1.Index(i), v2.Index(i), prop) { + return false + } + } + return true + case reflect.String: + return v1.Interface().(string) == v2.Interface().(string) + case reflect.Struct: + return equalStruct(v1, v2) + case reflect.Uint32, reflect.Uint64: + return v1.Uint() == v2.Uint() + } + + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to compare %v", v1) + return false +} + +// base is the struct type that the extensions are based on. +// x1 and x2 are InternalExtensions. +func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { + em1, _ := x1.extensionsRead() + em2, _ := x2.extensionsRead() + return equalExtMap(base, em1, em2) +} + +func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { + if len(em1) != len(em2) { + return false + } + + for extNum, e1 := range em1 { + e2, ok := em2[extNum] + if !ok { + return false + } + + m1, m2 := e1.value, e2.value + + if m1 == nil && m2 == nil { + // Both have only encoded form. + if bytes.Equal(e1.enc, e2.enc) { + continue + } + // The bytes are different, but the extensions might still be + // equal. We need to decode them to compare. + } + + if m1 != nil && m2 != nil { + // Both are unencoded. + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + continue + } + + // At least one is encoded. To do a semantically correct comparison + // we need to unmarshal them first. + var desc *ExtensionDesc + if m := extensionMaps[base]; m != nil { + desc = m[extNum] + } + if desc == nil { + // If both have only encoded form and the bytes are the same, + // it is handled above. We get here when the bytes are different. + // We don't know how to decode it, so just compare them as byte + // slices. + log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) + return false + } + var err error + if m1 == nil { + m1, err = decodeExtension(e1.enc, desc) + } + if m2 == nil && err == nil { + m2, err = decodeExtension(e2.enc, desc) + } + if err != nil { + // The encoded form is invalid. + log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) + return false + } + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + } + + return true +} diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go new file mode 100644 index 000000000..816a3b9d6 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -0,0 +1,543 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Types and routines for supporting protocol buffer extensions. + */ + +import ( + "errors" + "fmt" + "io" + "reflect" + "strconv" + "sync" +) + +// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. +var ErrMissingExtension = errors.New("proto: missing extension") + +// ExtensionRange represents a range of message extensions for a protocol buffer. +// Used in code generated by the protocol compiler. +type ExtensionRange struct { + Start, End int32 // both inclusive +} + +// extendableProto is an interface implemented by any protocol buffer generated by the current +// proto compiler that may be extended. +type extendableProto interface { + Message + ExtensionRangeArray() []ExtensionRange + extensionsWrite() map[int32]Extension + extensionsRead() (map[int32]Extension, sync.Locker) +} + +// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous +// version of the proto compiler that may be extended. +type extendableProtoV1 interface { + Message + ExtensionRangeArray() []ExtensionRange + ExtensionMap() map[int32]Extension +} + +// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. +type extensionAdapter struct { + extendableProtoV1 +} + +func (e extensionAdapter) extensionsWrite() map[int32]Extension { + return e.ExtensionMap() +} + +func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { + return e.ExtensionMap(), notLocker{} +} + +// notLocker is a sync.Locker whose Lock and Unlock methods are nops. +type notLocker struct{} + +func (n notLocker) Lock() {} +func (n notLocker) Unlock() {} + +// extendable returns the extendableProto interface for the given generated proto message. +// If the proto message has the old extension format, it returns a wrapper that implements +// the extendableProto interface. +func extendable(p interface{}) (extendableProto, error) { + switch p := p.(type) { + case extendableProto: + if isNilPtr(p) { + return nil, fmt.Errorf("proto: nil %T is not extendable", p) + } + return p, nil + case extendableProtoV1: + if isNilPtr(p) { + return nil, fmt.Errorf("proto: nil %T is not extendable", p) + } + return extensionAdapter{p}, nil + } + // Don't allocate a specific error containing %T: + // this is the hot path for Clone and MarshalText. + return nil, errNotExtendable +} + +var errNotExtendable = errors.New("proto: not an extendable proto.Message") + +func isNilPtr(x interface{}) bool { + v := reflect.ValueOf(x) + return v.Kind() == reflect.Ptr && v.IsNil() +} + +// XXX_InternalExtensions is an internal representation of proto extensions. +// +// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, +// thus gaining the unexported 'extensions' method, which can be called only from the proto package. +// +// The methods of XXX_InternalExtensions are not concurrency safe in general, +// but calls to logically read-only methods such as has and get may be executed concurrently. +type XXX_InternalExtensions struct { + // The struct must be indirect so that if a user inadvertently copies a + // generated message and its embedded XXX_InternalExtensions, they + // avoid the mayhem of a copied mutex. + // + // The mutex serializes all logically read-only operations to p.extensionMap. + // It is up to the client to ensure that write operations to p.extensionMap are + // mutually exclusive with other accesses. + p *struct { + mu sync.Mutex + extensionMap map[int32]Extension + } +} + +// extensionsWrite returns the extension map, creating it on first use. +func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { + if e.p == nil { + e.p = new(struct { + mu sync.Mutex + extensionMap map[int32]Extension + }) + e.p.extensionMap = make(map[int32]Extension) + } + return e.p.extensionMap +} + +// extensionsRead returns the extensions map for read-only use. It may be nil. +// The caller must hold the returned mutex's lock when accessing Elements within the map. +func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { + if e.p == nil { + return nil, nil + } + return e.p.extensionMap, &e.p.mu +} + +// ExtensionDesc represents an extension specification. +// Used in generated code from the protocol compiler. +type ExtensionDesc struct { + ExtendedType Message // nil pointer to the type that is being extended + ExtensionType interface{} // nil pointer to the extension type + Field int32 // field number + Name string // fully-qualified name of extension, for text formatting + Tag string // protobuf tag style + Filename string // name of the file in which the extension is defined +} + +func (ed *ExtensionDesc) repeated() bool { + t := reflect.TypeOf(ed.ExtensionType) + return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 +} + +// Extension represents an extension in a message. +type Extension struct { + // When an extension is stored in a message using SetExtension + // only desc and value are set. When the message is marshaled + // enc will be set to the encoded form of the message. + // + // When a message is unmarshaled and contains extensions, each + // extension will have only enc set. When such an extension is + // accessed using GetExtension (or GetExtensions) desc and value + // will be set. + desc *ExtensionDesc + value interface{} + enc []byte +} + +// SetRawExtension is for testing only. +func SetRawExtension(base Message, id int32, b []byte) { + epb, err := extendable(base) + if err != nil { + return + } + extmap := epb.extensionsWrite() + extmap[id] = Extension{enc: b} +} + +// isExtensionField returns true iff the given field number is in an extension range. +func isExtensionField(pb extendableProto, field int32) bool { + for _, er := range pb.ExtensionRangeArray() { + if er.Start <= field && field <= er.End { + return true + } + } + return false +} + +// checkExtensionTypes checks that the given extension is valid for pb. +func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { + var pbi interface{} = pb + // Check the extended type. + if ea, ok := pbi.(extensionAdapter); ok { + pbi = ea.extendableProtoV1 + } + if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { + return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a) + } + // Check the range. + if !isExtensionField(pb, extension.Field) { + return errors.New("proto: bad extension number; not in declared ranges") + } + return nil +} + +// extPropKey is sufficient to uniquely identify an extension. +type extPropKey struct { + base reflect.Type + field int32 +} + +var extProp = struct { + sync.RWMutex + m map[extPropKey]*Properties +}{ + m: make(map[extPropKey]*Properties), +} + +func extensionProperties(ed *ExtensionDesc) *Properties { + key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} + + extProp.RLock() + if prop, ok := extProp.m[key]; ok { + extProp.RUnlock() + return prop + } + extProp.RUnlock() + + extProp.Lock() + defer extProp.Unlock() + // Check again. + if prop, ok := extProp.m[key]; ok { + return prop + } + + prop := new(Properties) + prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) + extProp.m[key] = prop + return prop +} + +// HasExtension returns whether the given extension is present in pb. +func HasExtension(pb Message, extension *ExtensionDesc) bool { + // TODO: Check types, field numbers, etc.? + epb, err := extendable(pb) + if err != nil { + return false + } + extmap, mu := epb.extensionsRead() + if extmap == nil { + return false + } + mu.Lock() + _, ok := extmap[extension.Field] + mu.Unlock() + return ok +} + +// ClearExtension removes the given extension from pb. +func ClearExtension(pb Message, extension *ExtensionDesc) { + epb, err := extendable(pb) + if err != nil { + return + } + // TODO: Check types, field numbers, etc.? + extmap := epb.extensionsWrite() + delete(extmap, extension.Field) +} + +// GetExtension retrieves a proto2 extended field from pb. +// +// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), +// then GetExtension parses the encoded field and returns a Go value of the specified type. +// If the field is not present, then the default value is returned (if one is specified), +// otherwise ErrMissingExtension is reported. +// +// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil), +// then GetExtension returns the raw encoded bytes of the field extension. +func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { + epb, err := extendable(pb) + if err != nil { + return nil, err + } + + if extension.ExtendedType != nil { + // can only check type if this is a complete descriptor + if err := checkExtensionTypes(epb, extension); err != nil { + return nil, err + } + } + + emap, mu := epb.extensionsRead() + if emap == nil { + return defaultExtensionValue(extension) + } + mu.Lock() + defer mu.Unlock() + e, ok := emap[extension.Field] + if !ok { + // defaultExtensionValue returns the default value or + // ErrMissingExtension if there is no default. + return defaultExtensionValue(extension) + } + + if e.value != nil { + // Already decoded. Check the descriptor, though. + if e.desc != extension { + // This shouldn't happen. If it does, it means that + // GetExtension was called twice with two different + // descriptors with the same field number. + return nil, errors.New("proto: descriptor conflict") + } + return e.value, nil + } + + if extension.ExtensionType == nil { + // incomplete descriptor + return e.enc, nil + } + + v, err := decodeExtension(e.enc, extension) + if err != nil { + return nil, err + } + + // Remember the decoded version and drop the encoded version. + // That way it is safe to mutate what we return. + e.value = v + e.desc = extension + e.enc = nil + emap[extension.Field] = e + return e.value, nil +} + +// defaultExtensionValue returns the default value for extension. +// If no default for an extension is defined ErrMissingExtension is returned. +func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { + if extension.ExtensionType == nil { + // incomplete descriptor, so no default + return nil, ErrMissingExtension + } + + t := reflect.TypeOf(extension.ExtensionType) + props := extensionProperties(extension) + + sf, _, err := fieldDefault(t, props) + if err != nil { + return nil, err + } + + if sf == nil || sf.value == nil { + // There is no default value. + return nil, ErrMissingExtension + } + + if t.Kind() != reflect.Ptr { + // We do not need to return a Ptr, we can directly return sf.value. + return sf.value, nil + } + + // We need to return an interface{} that is a pointer to sf.value. + value := reflect.New(t).Elem() + value.Set(reflect.New(value.Type().Elem())) + if sf.kind == reflect.Int32 { + // We may have an int32 or an enum, but the underlying data is int32. + // Since we can't set an int32 into a non int32 reflect.value directly + // set it as a int32. + value.Elem().SetInt(int64(sf.value.(int32))) + } else { + value.Elem().Set(reflect.ValueOf(sf.value)) + } + return value.Interface(), nil +} + +// decodeExtension decodes an extension encoded in b. +func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { + t := reflect.TypeOf(extension.ExtensionType) + unmarshal := typeUnmarshaler(t, extension.Tag) + + // t is a pointer to a struct, pointer to basic type or a slice. + // Allocate space to store the pointer/slice. + value := reflect.New(t).Elem() + + var err error + for { + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + wire := int(x) & 7 + + b, err = unmarshal(b, valToPointer(value.Addr()), wire) + if err != nil { + return nil, err + } + + if len(b) == 0 { + break + } + } + return value.Interface(), nil +} + +// GetExtensions returns a slice of the extensions present in pb that are also listed in es. +// The returned slice has the same length as es; missing extensions will appear as nil elements. +func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { + epb, err := extendable(pb) + if err != nil { + return nil, err + } + extensions = make([]interface{}, len(es)) + for i, e := range es { + extensions[i], err = GetExtension(epb, e) + if err == ErrMissingExtension { + err = nil + } + if err != nil { + return + } + } + return +} + +// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. +// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing +// just the Field field, which defines the extension's field number. +func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { + epb, err := extendable(pb) + if err != nil { + return nil, err + } + registeredExtensions := RegisteredExtensions(pb) + + emap, mu := epb.extensionsRead() + if emap == nil { + return nil, nil + } + mu.Lock() + defer mu.Unlock() + extensions := make([]*ExtensionDesc, 0, len(emap)) + for extid, e := range emap { + desc := e.desc + if desc == nil { + desc = registeredExtensions[extid] + if desc == nil { + desc = &ExtensionDesc{Field: extid} + } + } + + extensions = append(extensions, desc) + } + return extensions, nil +} + +// SetExtension sets the specified extension of pb to the specified value. +func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { + epb, err := extendable(pb) + if err != nil { + return err + } + if err := checkExtensionTypes(epb, extension); err != nil { + return err + } + typ := reflect.TypeOf(extension.ExtensionType) + if typ != reflect.TypeOf(value) { + return errors.New("proto: bad extension value type") + } + // nil extension values need to be caught early, because the + // encoder can't distinguish an ErrNil due to a nil extension + // from an ErrNil due to a missing field. Extensions are + // always optional, so the encoder would just swallow the error + // and drop all the extensions from the encoded message. + if reflect.ValueOf(value).IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) + } + + extmap := epb.extensionsWrite() + extmap[extension.Field] = Extension{desc: extension, value: value} + return nil +} + +// ClearAllExtensions clears all extensions from pb. +func ClearAllExtensions(pb Message) { + epb, err := extendable(pb) + if err != nil { + return + } + m := epb.extensionsWrite() + for k := range m { + delete(m, k) + } +} + +// A global registry of extensions. +// The generated code will register the generated descriptors by calling RegisterExtension. + +var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) + +// RegisterExtension is called from the generated code. +func RegisterExtension(desc *ExtensionDesc) { + st := reflect.TypeOf(desc.ExtendedType).Elem() + m := extensionMaps[st] + if m == nil { + m = make(map[int32]*ExtensionDesc) + extensionMaps[st] = m + } + if _, ok := m[desc.Field]; ok { + panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) + } + m[desc.Field] = desc +} + +// RegisteredExtensions returns a map of the registered extensions of a +// protocol buffer struct, indexed by the extension number. +// The argument pb should be a nil pointer to the struct type. +func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { + return extensionMaps[reflect.TypeOf(pb).Elem()] +} diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go new file mode 100644 index 000000000..75565cc6d --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/lib.go @@ -0,0 +1,979 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/* +Package proto converts data structures to and from the wire format of +protocol buffers. It works in concert with the Go source code generated +for .proto files by the protocol compiler. + +A summary of the properties of the protocol buffer interface +for a protocol buffer variable v: + + - Names are turned from camel_case to CamelCase for export. + - There are no methods on v to set fields; just treat + them as structure fields. + - There are getters that return a field's value if set, + and return the field's default value if unset. + The getters work even if the receiver is a nil message. + - The zero value for a struct is its correct initialization state. + All desired fields must be set before marshaling. + - A Reset() method will restore a protobuf struct to its zero state. + - Non-repeated fields are pointers to the values; nil means unset. + That is, optional or required field int32 f becomes F *int32. + - Repeated fields are slices. + - Helper functions are available to aid the setting of fields. + msg.Foo = proto.String("hello") // set field + - Constants are defined to hold the default values of all fields that + have them. They have the form Default_StructName_FieldName. + Because the getter methods handle defaulted values, + direct use of these constants should be rare. + - Enums are given type names and maps from names to values. + Enum values are prefixed by the enclosing message's name, or by the + enum's type name if it is a top-level enum. Enum types have a String + method, and a Enum method to assist in message construction. + - Nested messages, groups and enums have type names prefixed with the name of + the surrounding message type. + - Extensions are given descriptor names that start with E_, + followed by an underscore-delimited list of the nested messages + that contain it (if any) followed by the CamelCased name of the + extension field itself. HasExtension, ClearExtension, GetExtension + and SetExtension are functions for manipulating extensions. + - Oneof field sets are given a single field in their message, + with distinguished wrapper types for each possible field value. + - Marshal and Unmarshal are functions to encode and decode the wire format. + +When the .proto file specifies `syntax="proto3"`, there are some differences: + + - Non-repeated fields of non-message type are values instead of pointers. + - Enum types do not get an Enum method. + +The simplest way to describe this is to see an example. +Given file test.proto, containing + + package example; + + enum FOO { X = 17; } + + message Test { + required string label = 1; + optional int32 type = 2 [default=77]; + repeated int64 reps = 3; + optional group OptionalGroup = 4 { + required string RequiredField = 5; + } + oneof union { + int32 number = 6; + string name = 7; + } + } + +The resulting file, test.pb.go, is: + + package example + + import proto "github.com/golang/protobuf/proto" + import math "math" + + type FOO int32 + const ( + FOO_X FOO = 17 + ) + var FOO_name = map[int32]string{ + 17: "X", + } + var FOO_value = map[string]int32{ + "X": 17, + } + + func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p + } + func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) + } + func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data) + if err != nil { + return err + } + *x = FOO(value) + return nil + } + + type Test struct { + Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` + Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` + Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` + Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + // Types that are valid to be assigned to Union: + // *Test_Number + // *Test_Name + Union isTest_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` + } + func (m *Test) Reset() { *m = Test{} } + func (m *Test) String() string { return proto.CompactTextString(m) } + func (*Test) ProtoMessage() {} + + type isTest_Union interface { + isTest_Union() + } + + type Test_Number struct { + Number int32 `protobuf:"varint,6,opt,name=number"` + } + type Test_Name struct { + Name string `protobuf:"bytes,7,opt,name=name"` + } + + func (*Test_Number) isTest_Union() {} + func (*Test_Name) isTest_Union() {} + + func (m *Test) GetUnion() isTest_Union { + if m != nil { + return m.Union + } + return nil + } + const Default_Test_Type int32 = 77 + + func (m *Test) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" + } + + func (m *Test) GetType() int32 { + if m != nil && m.Type != nil { + return *m.Type + } + return Default_Test_Type + } + + func (m *Test) GetOptionalgroup() *Test_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil + } + + type Test_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` + } + func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } + func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } + + func (m *Test_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" + } + + func (m *Test) GetNumber() int32 { + if x, ok := m.GetUnion().(*Test_Number); ok { + return x.Number + } + return 0 + } + + func (m *Test) GetName() string { + if x, ok := m.GetUnion().(*Test_Name); ok { + return x.Name + } + return "" + } + + func init() { + proto.RegisterEnum("example.FOO", FOO_name, FOO_value) + } + +To create and play with a Test object: + + package main + + import ( + "log" + + "github.com/golang/protobuf/proto" + pb "./example.pb" + ) + + func main() { + test := &pb.Test{ + Label: proto.String("hello"), + Type: proto.Int32(17), + Reps: []int64{1, 2, 3}, + Optionalgroup: &pb.Test_OptionalGroup{ + RequiredField: proto.String("good bye"), + }, + Union: &pb.Test_Name{"fred"}, + } + data, err := proto.Marshal(test) + if err != nil { + log.Fatal("marshaling error: ", err) + } + newTest := &pb.Test{} + err = proto.Unmarshal(data, newTest) + if err != nil { + log.Fatal("unmarshaling error: ", err) + } + // Now test and newTest contain the same data. + if test.GetLabel() != newTest.GetLabel() { + log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) + } + // Use a type switch to determine which oneof was set. + switch u := test.Union.(type) { + case *pb.Test_Number: // u.Number contains the number. + case *pb.Test_Name: // u.Name contains the string. + } + // etc. + } +*/ +package proto + +import ( + "encoding/json" + "fmt" + "log" + "reflect" + "sort" + "strconv" + "sync" +) + +// RequiredNotSetError is an error type returned by either Marshal or Unmarshal. +// Marshal reports this when a required field is not initialized. +// Unmarshal reports this when a required field is missing from the wire data. +type RequiredNotSetError struct{ field string } + +func (e *RequiredNotSetError) Error() string { + if e.field == "" { + return fmt.Sprintf("proto: required field not set") + } + return fmt.Sprintf("proto: required field %q not set", e.field) +} +func (e *RequiredNotSetError) RequiredNotSet() bool { + return true +} + +type invalidUTF8Error struct{ field string } + +func (e *invalidUTF8Error) Error() string { + if e.field == "" { + return "proto: invalid UTF-8 detected" + } + return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field) +} +func (e *invalidUTF8Error) InvalidUTF8() bool { + return true +} + +// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8. +// This error should not be exposed to the external API as such errors should +// be recreated with the field information. +var errInvalidUTF8 = &invalidUTF8Error{} + +// isNonFatal reports whether the error is either a RequiredNotSet error +// or a InvalidUTF8 error. +func isNonFatal(err error) bool { + if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() { + return true + } + if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() { + return true + } + return false +} + +type nonFatal struct{ E error } + +// Merge merges err into nf and reports whether it was successful. +// Otherwise it returns false for any fatal non-nil errors. +func (nf *nonFatal) Merge(err error) (ok bool) { + if err == nil { + return true // not an error + } + if !isNonFatal(err) { + return false // fatal error + } + if nf.E == nil { + nf.E = err // store first instance of non-fatal error + } + return true +} + +// Message is implemented by generated protocol buffer messages. +type Message interface { + Reset() + String() string + ProtoMessage() +} + +// Stats records allocation details about the protocol buffer encoders +// and decoders. Useful for tuning the library itself. +type Stats struct { + Emalloc uint64 // mallocs in encode + Dmalloc uint64 // mallocs in decode + Encode uint64 // number of encodes + Decode uint64 // number of decodes + Chit uint64 // number of cache hits + Cmiss uint64 // number of cache misses + Size uint64 // number of sizes +} + +// Set to true to enable stats collection. +const collectStats = false + +var stats Stats + +// GetStats returns a copy of the global Stats structure. +func GetStats() Stats { return stats } + +// A Buffer is a buffer manager for marshaling and unmarshaling +// protocol buffers. It may be reused between invocations to +// reduce memory usage. It is not necessary to use a Buffer; +// the global functions Marshal and Unmarshal create a +// temporary Buffer and are fine for most applications. +type Buffer struct { + buf []byte // encode/decode byte stream + index int // read point + + deterministic bool +} + +// NewBuffer allocates a new Buffer and initializes its internal data to +// the contents of the argument slice. +func NewBuffer(e []byte) *Buffer { + return &Buffer{buf: e} +} + +// Reset resets the Buffer, ready for marshaling a new protocol buffer. +func (p *Buffer) Reset() { + p.buf = p.buf[0:0] // for reading/writing + p.index = 0 // for reading +} + +// SetBuf replaces the internal buffer with the slice, +// ready for unmarshaling the contents of the slice. +func (p *Buffer) SetBuf(s []byte) { + p.buf = s + p.index = 0 +} + +// Bytes returns the contents of the Buffer. +func (p *Buffer) Bytes() []byte { return p.buf } + +// SetDeterministic sets whether to use deterministic serialization. +// +// Deterministic serialization guarantees that for a given binary, equal +// messages will always be serialized to the same bytes. This implies: +// +// - Repeated serialization of a message will return the same bytes. +// - Different processes of the same binary (which may be executing on +// different machines) will serialize equal messages to the same bytes. +// +// Note that the deterministic serialization is NOT canonical across +// languages. It is not guaranteed to remain stable over time. It is unstable +// across different builds with schema changes due to unknown fields. +// Users who need canonical serialization (e.g., persistent storage in a +// canonical form, fingerprinting, etc.) should define their own +// canonicalization specification and implement their own serializer rather +// than relying on this API. +// +// If deterministic serialization is requested, map entries will be sorted +// by keys in lexographical order. This is an implementation detail and +// subject to change. +func (p *Buffer) SetDeterministic(deterministic bool) { + p.deterministic = deterministic +} + +/* + * Helper routines for simplifying the creation of optional fields of basic type. + */ + +// Bool is a helper routine that allocates a new bool value +// to store v and returns a pointer to it. +func Bool(v bool) *bool { + return &v +} + +// Int32 is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it. +func Int32(v int32) *int32 { + return &v +} + +// Int is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it, but unlike Int32 +// its argument value is an int. +func Int(v int) *int32 { + p := new(int32) + *p = int32(v) + return p +} + +// Int64 is a helper routine that allocates a new int64 value +// to store v and returns a pointer to it. +func Int64(v int64) *int64 { + return &v +} + +// Float32 is a helper routine that allocates a new float32 value +// to store v and returns a pointer to it. +func Float32(v float32) *float32 { + return &v +} + +// Float64 is a helper routine that allocates a new float64 value +// to store v and returns a pointer to it. +func Float64(v float64) *float64 { + return &v +} + +// Uint32 is a helper routine that allocates a new uint32 value +// to store v and returns a pointer to it. +func Uint32(v uint32) *uint32 { + return &v +} + +// Uint64 is a helper routine that allocates a new uint64 value +// to store v and returns a pointer to it. +func Uint64(v uint64) *uint64 { + return &v +} + +// String is a helper routine that allocates a new string value +// to store v and returns a pointer to it. +func String(v string) *string { + return &v +} + +// EnumName is a helper function to simplify printing protocol buffer enums +// by name. Given an enum map and a value, it returns a useful string. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// UnmarshalJSONEnum is a helper function to simplify recovering enum int values +// from their JSON-encoded representation. Given a map from the enum's symbolic +// names to its int values, and a byte buffer containing the JSON-encoded +// value, it returns an int32 that can be cast to the enum type by the caller. +// +// The function can deal with both JSON representations, numeric and symbolic. +func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { + if data[0] == '"' { + // New style: enums are strings. + var repr string + if err := json.Unmarshal(data, &repr); err != nil { + return -1, err + } + val, ok := m[repr] + if !ok { + return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) + } + return val, nil + } + // Old style: enums are ints. + var val int32 + if err := json.Unmarshal(data, &val); err != nil { + return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) + } + return val, nil +} + +// DebugPrint dumps the encoded data in b in a debugging format with a header +// including the string s. Used in testing but made available for general debugging. +func (p *Buffer) DebugPrint(s string, b []byte) { + var u uint64 + + obuf := p.buf + index := p.index + p.buf = b + p.index = 0 + depth := 0 + + fmt.Printf("\n--- %s ---\n", s) + +out: + for { + for i := 0; i < depth; i++ { + fmt.Print(" ") + } + + index := p.index + if index == len(p.buf) { + break + } + + op, err := p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: fetching op err %v\n", index, err) + break out + } + tag := op >> 3 + wire := op & 7 + + switch wire { + default: + fmt.Printf("%3d: t=%3d unknown wire=%d\n", + index, tag, wire) + break out + + case WireBytes: + var r []byte + + r, err = p.DecodeRawBytes(false) + if err != nil { + break out + } + fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) + if len(r) <= 6 { + for i := 0; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } else { + for i := 0; i < 3; i++ { + fmt.Printf(" %.2x", r[i]) + } + fmt.Printf(" ..") + for i := len(r) - 3; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } + fmt.Printf("\n") + + case WireFixed32: + u, err = p.DecodeFixed32() + if err != nil { + fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) + + case WireFixed64: + u, err = p.DecodeFixed64() + if err != nil { + fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) + + case WireVarint: + u, err = p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) + + case WireStartGroup: + fmt.Printf("%3d: t=%3d start\n", index, tag) + depth++ + + case WireEndGroup: + depth-- + fmt.Printf("%3d: t=%3d end\n", index, tag) + } + } + + if depth != 0 { + fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) + } + fmt.Printf("\n") + + p.buf = obuf + p.index = index +} + +// SetDefaults sets unset protocol buffer fields to their default values. +// It only modifies fields that are both unset and have defined defaults. +// It recursively sets default values in any non-nil sub-messages. +func SetDefaults(pb Message) { + setDefaults(reflect.ValueOf(pb), true, false) +} + +// v is a pointer to a struct. +func setDefaults(v reflect.Value, recur, zeros bool) { + v = v.Elem() + + defaultMu.RLock() + dm, ok := defaults[v.Type()] + defaultMu.RUnlock() + if !ok { + dm = buildDefaultMessage(v.Type()) + defaultMu.Lock() + defaults[v.Type()] = dm + defaultMu.Unlock() + } + + for _, sf := range dm.scalars { + f := v.Field(sf.index) + if !f.IsNil() { + // field already set + continue + } + dv := sf.value + if dv == nil && !zeros { + // no explicit default, and don't want to set zeros + continue + } + fptr := f.Addr().Interface() // **T + // TODO: Consider batching the allocations we do here. + switch sf.kind { + case reflect.Bool: + b := new(bool) + if dv != nil { + *b = dv.(bool) + } + *(fptr.(**bool)) = b + case reflect.Float32: + f := new(float32) + if dv != nil { + *f = dv.(float32) + } + *(fptr.(**float32)) = f + case reflect.Float64: + f := new(float64) + if dv != nil { + *f = dv.(float64) + } + *(fptr.(**float64)) = f + case reflect.Int32: + // might be an enum + if ft := f.Type(); ft != int32PtrType { + // enum + f.Set(reflect.New(ft.Elem())) + if dv != nil { + f.Elem().SetInt(int64(dv.(int32))) + } + } else { + // int32 field + i := new(int32) + if dv != nil { + *i = dv.(int32) + } + *(fptr.(**int32)) = i + } + case reflect.Int64: + i := new(int64) + if dv != nil { + *i = dv.(int64) + } + *(fptr.(**int64)) = i + case reflect.String: + s := new(string) + if dv != nil { + *s = dv.(string) + } + *(fptr.(**string)) = s + case reflect.Uint8: + // exceptional case: []byte + var b []byte + if dv != nil { + db := dv.([]byte) + b = make([]byte, len(db)) + copy(b, db) + } else { + b = []byte{} + } + *(fptr.(*[]byte)) = b + case reflect.Uint32: + u := new(uint32) + if dv != nil { + *u = dv.(uint32) + } + *(fptr.(**uint32)) = u + case reflect.Uint64: + u := new(uint64) + if dv != nil { + *u = dv.(uint64) + } + *(fptr.(**uint64)) = u + default: + log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) + } + } + + for _, ni := range dm.nested { + f := v.Field(ni) + // f is *T or []*T or map[T]*T + switch f.Kind() { + case reflect.Ptr: + if f.IsNil() { + continue + } + setDefaults(f, recur, zeros) + + case reflect.Slice: + for i := 0; i < f.Len(); i++ { + e := f.Index(i) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + + case reflect.Map: + for _, k := range f.MapKeys() { + e := f.MapIndex(k) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + } + } +} + +var ( + // defaults maps a protocol buffer struct type to a slice of the fields, + // with its scalar fields set to their proto-declared non-zero default values. + defaultMu sync.RWMutex + defaults = make(map[reflect.Type]defaultMessage) + + int32PtrType = reflect.TypeOf((*int32)(nil)) +) + +// defaultMessage represents information about the default values of a message. +type defaultMessage struct { + scalars []scalarField + nested []int // struct field index of nested messages +} + +type scalarField struct { + index int // struct field index + kind reflect.Kind // element type (the T in *T or []T) + value interface{} // the proto-declared default value, or nil +} + +// t is a struct type. +func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { + sprop := GetProperties(t) + for _, prop := range sprop.Prop { + fi, ok := sprop.decoderTags.get(prop.Tag) + if !ok { + // XXX_unrecognized + continue + } + ft := t.Field(fi).Type + + sf, nested, err := fieldDefault(ft, prop) + switch { + case err != nil: + log.Print(err) + case nested: + dm.nested = append(dm.nested, fi) + case sf != nil: + sf.index = fi + dm.scalars = append(dm.scalars, *sf) + } + } + + return dm +} + +// fieldDefault returns the scalarField for field type ft. +// sf will be nil if the field can not have a default. +// nestedMessage will be true if this is a nested message. +// Note that sf.index is not set on return. +func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { + var canHaveDefault bool + switch ft.Kind() { + case reflect.Ptr: + if ft.Elem().Kind() == reflect.Struct { + nestedMessage = true + } else { + canHaveDefault = true // proto2 scalar field + } + + case reflect.Slice: + switch ft.Elem().Kind() { + case reflect.Ptr: + nestedMessage = true // repeated message + case reflect.Uint8: + canHaveDefault = true // bytes field + } + + case reflect.Map: + if ft.Elem().Kind() == reflect.Ptr { + nestedMessage = true // map with message values + } + } + + if !canHaveDefault { + if nestedMessage { + return nil, true, nil + } + return nil, false, nil + } + + // We now know that ft is a pointer or slice. + sf = &scalarField{kind: ft.Elem().Kind()} + + // scalar fields without defaults + if !prop.HasDefault { + return sf, false, nil + } + + // a scalar field: either *T or []byte + switch ft.Elem().Kind() { + case reflect.Bool: + x, err := strconv.ParseBool(prop.Default) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Float32: + x, err := strconv.ParseFloat(prop.Default, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) + } + sf.value = float32(x) + case reflect.Float64: + x, err := strconv.ParseFloat(prop.Default, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Int32: + x, err := strconv.ParseInt(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) + } + sf.value = int32(x) + case reflect.Int64: + x, err := strconv.ParseInt(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.String: + sf.value = prop.Default + case reflect.Uint8: + // []byte (not *uint8) + sf.value = []byte(prop.Default) + case reflect.Uint32: + x, err := strconv.ParseUint(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) + } + sf.value = uint32(x) + case reflect.Uint64: + x, err := strconv.ParseUint(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) + } + sf.value = x + default: + return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) + } + + return sf, false, nil +} + +// mapKeys returns a sort.Interface to be used for sorting the map keys. +// Map fields may have key types of non-float scalars, strings and enums. +func mapKeys(vs []reflect.Value) sort.Interface { + s := mapKeySorter{vs: vs} + + // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps. + if len(vs) == 0 { + return s + } + switch vs[0].Kind() { + case reflect.Int32, reflect.Int64: + s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } + case reflect.Uint32, reflect.Uint64: + s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } + case reflect.Bool: + s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true + case reflect.String: + s.less = func(a, b reflect.Value) bool { return a.String() < b.String() } + default: + panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind())) + } + + return s +} + +type mapKeySorter struct { + vs []reflect.Value + less func(a, b reflect.Value) bool +} + +func (s mapKeySorter) Len() int { return len(s.vs) } +func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } +func (s mapKeySorter) Less(i, j int) bool { + return s.less(s.vs[i], s.vs[j]) +} + +// isProto3Zero reports whether v is a zero proto3 value. +func isProto3Zero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return !v.Bool() + case reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint32, reflect.Uint64: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.String: + return v.String() == "" + } + return false +} + +// ProtoPackageIsVersion2 is referenced from generated protocol buffer files +// to assert that that code is compatible with this version of the proto package. +const ProtoPackageIsVersion2 = true + +// ProtoPackageIsVersion1 is referenced from generated protocol buffer files +// to assert that that code is compatible with this version of the proto package. +const ProtoPackageIsVersion1 = true + +// InternalMessageInfo is a type used internally by generated .pb.go files. +// This type is not intended to be used by non-generated code. +// This type is not subject to any compatibility guarantee. +type InternalMessageInfo struct { + marshal *marshalInfo + unmarshal *unmarshalInfo + merge *mergeInfo + discard *discardInfo +} diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go new file mode 100644 index 000000000..3b6ca41d5 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/message_set.go @@ -0,0 +1,314 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Support for message sets. + */ + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "reflect" + "sort" + "sync" +) + +// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. +// A message type ID is required for storing a protocol buffer in a message set. +var errNoMessageTypeID = errors.New("proto does not have a message type ID") + +// The first two types (_MessageSet_Item and messageSet) +// model what the protocol compiler produces for the following protocol message: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required string message = 3; +// }; +// } +// That is the MessageSet wire format. We can't use a proto to generate these +// because that would introduce a circular dependency between it and this package. + +type _MessageSet_Item struct { + TypeId *int32 `protobuf:"varint,2,req,name=type_id"` + Message []byte `protobuf:"bytes,3,req,name=message"` +} + +type messageSet struct { + Item []*_MessageSet_Item `protobuf:"group,1,rep"` + XXX_unrecognized []byte + // TODO: caching? +} + +// Make sure messageSet is a Message. +var _ Message = (*messageSet)(nil) + +// messageTypeIder is an interface satisfied by a protocol buffer type +// that may be stored in a MessageSet. +type messageTypeIder interface { + MessageTypeId() int32 +} + +func (ms *messageSet) find(pb Message) *_MessageSet_Item { + mti, ok := pb.(messageTypeIder) + if !ok { + return nil + } + id := mti.MessageTypeId() + for _, item := range ms.Item { + if *item.TypeId == id { + return item + } + } + return nil +} + +func (ms *messageSet) Has(pb Message) bool { + return ms.find(pb) != nil +} + +func (ms *messageSet) Unmarshal(pb Message) error { + if item := ms.find(pb); item != nil { + return Unmarshal(item.Message, pb) + } + if _, ok := pb.(messageTypeIder); !ok { + return errNoMessageTypeID + } + return nil // TODO: return error instead? +} + +func (ms *messageSet) Marshal(pb Message) error { + msg, err := Marshal(pb) + if err != nil { + return err + } + if item := ms.find(pb); item != nil { + // reuse existing item + item.Message = msg + return nil + } + + mti, ok := pb.(messageTypeIder) + if !ok { + return errNoMessageTypeID + } + + mtid := mti.MessageTypeId() + ms.Item = append(ms.Item, &_MessageSet_Item{ + TypeId: &mtid, + Message: msg, + }) + return nil +} + +func (ms *messageSet) Reset() { *ms = messageSet{} } +func (ms *messageSet) String() string { return CompactTextString(ms) } +func (*messageSet) ProtoMessage() {} + +// Support for the message_set_wire_format message option. + +func skipVarint(buf []byte) []byte { + i := 0 + for ; buf[i]&0x80 != 0; i++ { + } + return buf[i+1:] +} + +// MarshalMessageSet encodes the extension map represented by m in the message set wire format. +// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. +func MarshalMessageSet(exts interface{}) ([]byte, error) { + return marshalMessageSet(exts, false) +} + +// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal. +func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) { + switch exts := exts.(type) { + case *XXX_InternalExtensions: + var u marshalInfo + siz := u.sizeMessageSet(exts) + b := make([]byte, 0, siz) + return u.appendMessageSet(b, exts, deterministic) + + case map[int32]Extension: + // This is an old-style extension map. + // Wrap it in a new-style XXX_InternalExtensions. + ie := XXX_InternalExtensions{ + p: &struct { + mu sync.Mutex + extensionMap map[int32]Extension + }{ + extensionMap: exts, + }, + } + + var u marshalInfo + siz := u.sizeMessageSet(&ie) + b := make([]byte, 0, siz) + return u.appendMessageSet(b, &ie, deterministic) + + default: + return nil, errors.New("proto: not an extension map") + } +} + +// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. +// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. +func UnmarshalMessageSet(buf []byte, exts interface{}) error { + var m map[int32]Extension + switch exts := exts.(type) { + case *XXX_InternalExtensions: + m = exts.extensionsWrite() + case map[int32]Extension: + m = exts + default: + return errors.New("proto: not an extension map") + } + + ms := new(messageSet) + if err := Unmarshal(buf, ms); err != nil { + return err + } + for _, item := range ms.Item { + id := *item.TypeId + msg := item.Message + + // Restore wire type and field number varint, plus length varint. + // Be careful to preserve duplicate items. + b := EncodeVarint(uint64(id)<<3 | WireBytes) + if ext, ok := m[id]; ok { + // Existing data; rip off the tag and length varint + // so we join the new data correctly. + // We can assume that ext.enc is set because we are unmarshaling. + o := ext.enc[len(b):] // skip wire type and field number + _, n := DecodeVarint(o) // calculate length of length varint + o = o[n:] // skip length varint + msg = append(o, msg...) // join old data and new data + } + b = append(b, EncodeVarint(uint64(len(msg)))...) + b = append(b, msg...) + + m[id] = Extension{enc: b} + } + return nil +} + +// MarshalMessageSetJSON encodes the extension map represented by m in JSON format. +// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. +func MarshalMessageSetJSON(exts interface{}) ([]byte, error) { + var m map[int32]Extension + switch exts := exts.(type) { + case *XXX_InternalExtensions: + var mu sync.Locker + m, mu = exts.extensionsRead() + if m != nil { + // Keep the extensions map locked until we're done marshaling to prevent + // races between marshaling and unmarshaling the lazily-{en,de}coded + // values. + mu.Lock() + defer mu.Unlock() + } + case map[int32]Extension: + m = exts + default: + return nil, errors.New("proto: not an extension map") + } + var b bytes.Buffer + b.WriteByte('{') + + // Process the map in key order for deterministic output. + ids := make([]int32, 0, len(m)) + for id := range m { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) // int32Slice defined in text.go + + for i, id := range ids { + ext := m[id] + msd, ok := messageSetMap[id] + if !ok { + // Unknown type; we can't render it, so skip it. + continue + } + + if i > 0 && b.Len() > 1 { + b.WriteByte(',') + } + + fmt.Fprintf(&b, `"[%s]":`, msd.name) + + x := ext.value + if x == nil { + x = reflect.New(msd.t.Elem()).Interface() + if err := Unmarshal(ext.enc, x.(Message)); err != nil { + return nil, err + } + } + d, err := json.Marshal(x) + if err != nil { + return nil, err + } + b.Write(d) + } + b.WriteByte('}') + return b.Bytes(), nil +} + +// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. +// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. +func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error { + // Common-case fast path. + if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { + return nil + } + + // This is fairly tricky, and it's not clear that it is needed. + return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") +} + +// A global registry of types that can be used in a MessageSet. + +var messageSetMap = make(map[int32]messageSetDesc) + +type messageSetDesc struct { + t reflect.Type // pointer to struct + name string +} + +// RegisterMessageSetType is called from the generated code. +func RegisterMessageSetType(m Message, fieldNum int32, name string) { + messageSetMap[fieldNum] = messageSetDesc{ + t: reflect.TypeOf(m), + name: name, + } +} diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go new file mode 100644 index 000000000..b6cad9083 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go @@ -0,0 +1,357 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +build purego appengine js + +// This file contains an implementation of proto field accesses using package reflect. +// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can +// be used on App Engine. + +package proto + +import ( + "reflect" + "sync" +) + +const unsafeAllowed = false + +// A field identifies a field in a struct, accessible from a pointer. +// In this implementation, a field is identified by the sequence of field indices +// passed to reflect's FieldByIndex. +type field []int + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return f.Index +} + +// invalidField is an invalid field identifier. +var invalidField = field(nil) + +// zeroField is a noop when calling pointer.offset. +var zeroField = field([]int{}) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { return f != nil } + +// The pointer type is for the table-driven decoder. +// The implementation here uses a reflect.Value of pointer type to +// create a generic pointer. In pointer_unsafe.go we use unsafe +// instead of reflect to implement the same (but faster) interface. +type pointer struct { + v reflect.Value +} + +// toPointer converts an interface of pointer type to a pointer +// that points to the same target. +func toPointer(i *Message) pointer { + return pointer{v: reflect.ValueOf(*i)} +} + +// toAddrPointer converts an interface to a pointer that points to +// the interface data. +func toAddrPointer(i *interface{}, isptr bool) pointer { + v := reflect.ValueOf(*i) + u := reflect.New(v.Type()) + u.Elem().Set(v) + return pointer{v: u} +} + +// valToPointer converts v to a pointer. v must be of pointer type. +func valToPointer(v reflect.Value) pointer { + return pointer{v: v} +} + +// offset converts from a pointer to a structure to a pointer to +// one of its fields. +func (p pointer) offset(f field) pointer { + return pointer{v: p.v.Elem().FieldByIndex(f).Addr()} +} + +func (p pointer) isNil() bool { + return p.v.IsNil() +} + +// grow updates the slice s in place to make it one element longer. +// s must be addressable. +// Returns the (addressable) new element. +func grow(s reflect.Value) reflect.Value { + n, m := s.Len(), s.Cap() + if n < m { + s.SetLen(n + 1) + } else { + s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem()))) + } + return s.Index(n) +} + +func (p pointer) toInt64() *int64 { + return p.v.Interface().(*int64) +} +func (p pointer) toInt64Ptr() **int64 { + return p.v.Interface().(**int64) +} +func (p pointer) toInt64Slice() *[]int64 { + return p.v.Interface().(*[]int64) +} + +var int32ptr = reflect.TypeOf((*int32)(nil)) + +func (p pointer) toInt32() *int32 { + return p.v.Convert(int32ptr).Interface().(*int32) +} + +// The toInt32Ptr/Slice methods don't work because of enums. +// Instead, we must use set/get methods for the int32ptr/slice case. +/* + func (p pointer) toInt32Ptr() **int32 { + return p.v.Interface().(**int32) +} + func (p pointer) toInt32Slice() *[]int32 { + return p.v.Interface().(*[]int32) +} +*/ +func (p pointer) getInt32Ptr() *int32 { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + return p.v.Elem().Interface().(*int32) + } + // an enum + return p.v.Elem().Convert(int32PtrType).Interface().(*int32) +} +func (p pointer) setInt32Ptr(v int32) { + // Allocate value in a *int32. Possibly convert that to a *enum. + // Then assign it to a **int32 or **enum. + // Note: we can convert *int32 to *enum, but we can't convert + // **int32 to **enum! + p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem())) +} + +// getInt32Slice copies []int32 from p as a new slice. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) getInt32Slice() []int32 { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + return p.v.Elem().Interface().([]int32) + } + // an enum + // Allocate a []int32, then assign []enum's values into it. + // Note: we can't convert []enum to []int32. + slice := p.v.Elem() + s := make([]int32, slice.Len()) + for i := 0; i < slice.Len(); i++ { + s[i] = int32(slice.Index(i).Int()) + } + return s +} + +// setInt32Slice copies []int32 into p as a new slice. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) setInt32Slice(v []int32) { + if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { + // raw int32 type + p.v.Elem().Set(reflect.ValueOf(v)) + return + } + // an enum + // Allocate a []enum, then assign []int32's values into it. + // Note: we can't convert []enum to []int32. + slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v)) + for i, x := range v { + slice.Index(i).SetInt(int64(x)) + } + p.v.Elem().Set(slice) +} +func (p pointer) appendInt32Slice(v int32) { + grow(p.v.Elem()).SetInt(int64(v)) +} + +func (p pointer) toUint64() *uint64 { + return p.v.Interface().(*uint64) +} +func (p pointer) toUint64Ptr() **uint64 { + return p.v.Interface().(**uint64) +} +func (p pointer) toUint64Slice() *[]uint64 { + return p.v.Interface().(*[]uint64) +} +func (p pointer) toUint32() *uint32 { + return p.v.Interface().(*uint32) +} +func (p pointer) toUint32Ptr() **uint32 { + return p.v.Interface().(**uint32) +} +func (p pointer) toUint32Slice() *[]uint32 { + return p.v.Interface().(*[]uint32) +} +func (p pointer) toBool() *bool { + return p.v.Interface().(*bool) +} +func (p pointer) toBoolPtr() **bool { + return p.v.Interface().(**bool) +} +func (p pointer) toBoolSlice() *[]bool { + return p.v.Interface().(*[]bool) +} +func (p pointer) toFloat64() *float64 { + return p.v.Interface().(*float64) +} +func (p pointer) toFloat64Ptr() **float64 { + return p.v.Interface().(**float64) +} +func (p pointer) toFloat64Slice() *[]float64 { + return p.v.Interface().(*[]float64) +} +func (p pointer) toFloat32() *float32 { + return p.v.Interface().(*float32) +} +func (p pointer) toFloat32Ptr() **float32 { + return p.v.Interface().(**float32) +} +func (p pointer) toFloat32Slice() *[]float32 { + return p.v.Interface().(*[]float32) +} +func (p pointer) toString() *string { + return p.v.Interface().(*string) +} +func (p pointer) toStringPtr() **string { + return p.v.Interface().(**string) +} +func (p pointer) toStringSlice() *[]string { + return p.v.Interface().(*[]string) +} +func (p pointer) toBytes() *[]byte { + return p.v.Interface().(*[]byte) +} +func (p pointer) toBytesSlice() *[][]byte { + return p.v.Interface().(*[][]byte) +} +func (p pointer) toExtensions() *XXX_InternalExtensions { + return p.v.Interface().(*XXX_InternalExtensions) +} +func (p pointer) toOldExtensions() *map[int32]Extension { + return p.v.Interface().(*map[int32]Extension) +} +func (p pointer) getPointer() pointer { + return pointer{v: p.v.Elem()} +} +func (p pointer) setPointer(q pointer) { + p.v.Elem().Set(q.v) +} +func (p pointer) appendPointer(q pointer) { + grow(p.v.Elem()).Set(q.v) +} + +// getPointerSlice copies []*T from p as a new []pointer. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) getPointerSlice() []pointer { + if p.v.IsNil() { + return nil + } + n := p.v.Elem().Len() + s := make([]pointer, n) + for i := 0; i < n; i++ { + s[i] = pointer{v: p.v.Elem().Index(i)} + } + return s +} + +// setPointerSlice copies []pointer into p as a new []*T. +// This behavior differs from the implementation in pointer_unsafe.go. +func (p pointer) setPointerSlice(v []pointer) { + if v == nil { + p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem()) + return + } + s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v)) + for _, p := range v { + s = reflect.Append(s, p.v) + } + p.v.Elem().Set(s) +} + +// getInterfacePointer returns a pointer that points to the +// interface data of the interface pointed by p. +func (p pointer) getInterfacePointer() pointer { + if p.v.Elem().IsNil() { + return pointer{v: p.v.Elem()} + } + return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct +} + +func (p pointer) asPointerTo(t reflect.Type) reflect.Value { + // TODO: check that p.v.Type().Elem() == t? + return p.v +} + +func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} +func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { + atomicLock.Lock() + defer atomicLock.Unlock() + return *p +} +func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { + atomicLock.Lock() + defer atomicLock.Unlock() + *p = v +} + +var atomicLock sync.Mutex diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go new file mode 100644 index 000000000..d55a335d9 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go @@ -0,0 +1,308 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// +build !purego,!appengine,!js + +// This file contains the implementation of the proto field accesses using package unsafe. + +package proto + +import ( + "reflect" + "sync/atomic" + "unsafe" +) + +const unsafeAllowed = true + +// A field identifies a field in a struct, accessible from a pointer. +// In this implementation, a field is identified by its byte offset from the start of the struct. +type field uintptr + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return field(f.Offset) +} + +// invalidField is an invalid field identifier. +const invalidField = ^field(0) + +// zeroField is a noop when calling pointer.offset. +const zeroField = field(0) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { + return f != invalidField +} + +// The pointer type below is for the new table-driven encoder/decoder. +// The implementation here uses unsafe.Pointer to create a generic pointer. +// In pointer_reflect.go we use reflect instead of unsafe to implement +// the same (but slower) interface. +type pointer struct { + p unsafe.Pointer +} + +// size of pointer +var ptrSize = unsafe.Sizeof(uintptr(0)) + +// toPointer converts an interface of pointer type to a pointer +// that points to the same target. +func toPointer(i *Message) pointer { + // Super-tricky - read pointer out of data word of interface value. + // Saves ~25ns over the equivalent: + // return valToPointer(reflect.ValueOf(*i)) + return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} +} + +// toAddrPointer converts an interface to a pointer that points to +// the interface data. +func toAddrPointer(i *interface{}, isptr bool) pointer { + // Super-tricky - read or get the address of data word of interface value. + if isptr { + // The interface is of pointer type, thus it is a direct interface. + // The data word is the pointer data itself. We take its address. + return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} + } + // The interface is not of pointer type. The data word is the pointer + // to the data. + return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} +} + +// valToPointer converts v to a pointer. v must be of pointer type. +func valToPointer(v reflect.Value) pointer { + return pointer{p: unsafe.Pointer(v.Pointer())} +} + +// offset converts from a pointer to a structure to a pointer to +// one of its fields. +func (p pointer) offset(f field) pointer { + // For safety, we should panic if !f.IsValid, however calling panic causes + // this to no longer be inlineable, which is a serious performance cost. + /* + if !f.IsValid() { + panic("invalid field") + } + */ + return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))} +} + +func (p pointer) isNil() bool { + return p.p == nil +} + +func (p pointer) toInt64() *int64 { + return (*int64)(p.p) +} +func (p pointer) toInt64Ptr() **int64 { + return (**int64)(p.p) +} +func (p pointer) toInt64Slice() *[]int64 { + return (*[]int64)(p.p) +} +func (p pointer) toInt32() *int32 { + return (*int32)(p.p) +} + +// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist. +/* + func (p pointer) toInt32Ptr() **int32 { + return (**int32)(p.p) + } + func (p pointer) toInt32Slice() *[]int32 { + return (*[]int32)(p.p) + } +*/ +func (p pointer) getInt32Ptr() *int32 { + return *(**int32)(p.p) +} +func (p pointer) setInt32Ptr(v int32) { + *(**int32)(p.p) = &v +} + +// getInt32Slice loads a []int32 from p. +// The value returned is aliased with the original slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) getInt32Slice() []int32 { + return *(*[]int32)(p.p) +} + +// setInt32Slice stores a []int32 to p. +// The value set is aliased with the input slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) setInt32Slice(v []int32) { + *(*[]int32)(p.p) = v +} + +// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead? +func (p pointer) appendInt32Slice(v int32) { + s := (*[]int32)(p.p) + *s = append(*s, v) +} + +func (p pointer) toUint64() *uint64 { + return (*uint64)(p.p) +} +func (p pointer) toUint64Ptr() **uint64 { + return (**uint64)(p.p) +} +func (p pointer) toUint64Slice() *[]uint64 { + return (*[]uint64)(p.p) +} +func (p pointer) toUint32() *uint32 { + return (*uint32)(p.p) +} +func (p pointer) toUint32Ptr() **uint32 { + return (**uint32)(p.p) +} +func (p pointer) toUint32Slice() *[]uint32 { + return (*[]uint32)(p.p) +} +func (p pointer) toBool() *bool { + return (*bool)(p.p) +} +func (p pointer) toBoolPtr() **bool { + return (**bool)(p.p) +} +func (p pointer) toBoolSlice() *[]bool { + return (*[]bool)(p.p) +} +func (p pointer) toFloat64() *float64 { + return (*float64)(p.p) +} +func (p pointer) toFloat64Ptr() **float64 { + return (**float64)(p.p) +} +func (p pointer) toFloat64Slice() *[]float64 { + return (*[]float64)(p.p) +} +func (p pointer) toFloat32() *float32 { + return (*float32)(p.p) +} +func (p pointer) toFloat32Ptr() **float32 { + return (**float32)(p.p) +} +func (p pointer) toFloat32Slice() *[]float32 { + return (*[]float32)(p.p) +} +func (p pointer) toString() *string { + return (*string)(p.p) +} +func (p pointer) toStringPtr() **string { + return (**string)(p.p) +} +func (p pointer) toStringSlice() *[]string { + return (*[]string)(p.p) +} +func (p pointer) toBytes() *[]byte { + return (*[]byte)(p.p) +} +func (p pointer) toBytesSlice() *[][]byte { + return (*[][]byte)(p.p) +} +func (p pointer) toExtensions() *XXX_InternalExtensions { + return (*XXX_InternalExtensions)(p.p) +} +func (p pointer) toOldExtensions() *map[int32]Extension { + return (*map[int32]Extension)(p.p) +} + +// getPointerSlice loads []*T from p as a []pointer. +// The value returned is aliased with the original slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) getPointerSlice() []pointer { + // Super-tricky - p should point to a []*T where T is a + // message type. We load it as []pointer. + return *(*[]pointer)(p.p) +} + +// setPointerSlice stores []pointer into p as a []*T. +// The value set is aliased with the input slice. +// This behavior differs from the implementation in pointer_reflect.go. +func (p pointer) setPointerSlice(v []pointer) { + // Super-tricky - p should point to a []*T where T is a + // message type. We store it as []pointer. + *(*[]pointer)(p.p) = v +} + +// getPointer loads the pointer at p and returns it. +func (p pointer) getPointer() pointer { + return pointer{p: *(*unsafe.Pointer)(p.p)} +} + +// setPointer stores the pointer q at p. +func (p pointer) setPointer(q pointer) { + *(*unsafe.Pointer)(p.p) = q.p +} + +// append q to the slice pointed to by p. +func (p pointer) appendPointer(q pointer) { + s := (*[]unsafe.Pointer)(p.p) + *s = append(*s, q.p) +} + +// getInterfacePointer returns a pointer that points to the +// interface data of the interface pointed by p. +func (p pointer) getInterfacePointer() pointer { + // Super-tricky - read pointer out of data word of interface value. + return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]} +} + +// asPointerTo returns a reflect.Value that is a pointer to an +// object of type t stored at p. +func (p pointer) asPointerTo(t reflect.Type) reflect.Value { + return reflect.NewAt(t, p.p) +} + +func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { + return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { + return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { + return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} +func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { + return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go new file mode 100644 index 000000000..50b99b83a --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -0,0 +1,544 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "fmt" + "log" + "os" + "reflect" + "sort" + "strconv" + "strings" + "sync" +) + +const debug bool = false + +// Constants that identify the encoding of a value on the wire. +const ( + WireVarint = 0 + WireFixed64 = 1 + WireBytes = 2 + WireStartGroup = 3 + WireEndGroup = 4 + WireFixed32 = 5 +) + +// tagMap is an optimization over map[int]int for typical protocol buffer +// use-cases. Encoded protocol buffers are often in tag order with small tag +// numbers. +type tagMap struct { + fastTags []int + slowTags map[int]int +} + +// tagMapFastLimit is the upper bound on the tag number that will be stored in +// the tagMap slice rather than its map. +const tagMapFastLimit = 1024 + +func (p *tagMap) get(t int) (int, bool) { + if t > 0 && t < tagMapFastLimit { + if t >= len(p.fastTags) { + return 0, false + } + fi := p.fastTags[t] + return fi, fi >= 0 + } + fi, ok := p.slowTags[t] + return fi, ok +} + +func (p *tagMap) put(t int, fi int) { + if t > 0 && t < tagMapFastLimit { + for len(p.fastTags) < t+1 { + p.fastTags = append(p.fastTags, -1) + } + p.fastTags[t] = fi + return + } + if p.slowTags == nil { + p.slowTags = make(map[int]int) + } + p.slowTags[t] = fi +} + +// StructProperties represents properties for all the fields of a struct. +// decoderTags and decoderOrigNames should only be used by the decoder. +type StructProperties struct { + Prop []*Properties // properties for each field + reqCount int // required count + decoderTags tagMap // map from proto tag to struct field number + decoderOrigNames map[string]int // map from original name to struct field number + order []int // list of struct field numbers in tag order + + // OneofTypes contains information about the oneof fields in this message. + // It is keyed by the original name of a field. + OneofTypes map[string]*OneofProperties +} + +// OneofProperties represents information about a specific field in a oneof. +type OneofProperties struct { + Type reflect.Type // pointer to generated struct type for this oneof field + Field int // struct field number of the containing oneof in the message + Prop *Properties +} + +// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. +// See encode.go, (*Buffer).enc_struct. + +func (sp *StructProperties) Len() int { return len(sp.order) } +func (sp *StructProperties) Less(i, j int) bool { + return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag +} +func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } + +// Properties represents the protocol-specific behavior of a single struct field. +type Properties struct { + Name string // name of the field, for error messages + OrigName string // original name before protocol compiler (always set) + JSONName string // name to use for JSON; determined by protoc + Wire string + WireType int + Tag int + Required bool + Optional bool + Repeated bool + Packed bool // relevant for repeated primitives only + Enum string // set for enum types only + proto3 bool // whether this is known to be a proto3 field + oneof bool // whether this is a oneof field + + Default string // default value + HasDefault bool // whether an explicit default was provided + + stype reflect.Type // set for struct types only + sprop *StructProperties // set for struct types only + + mtype reflect.Type // set for map types only + MapKeyProp *Properties // set for map types only + MapValProp *Properties // set for map types only +} + +// String formats the properties in the protobuf struct field tag style. +func (p *Properties) String() string { + s := p.Wire + s += "," + s += strconv.Itoa(p.Tag) + if p.Required { + s += ",req" + } + if p.Optional { + s += ",opt" + } + if p.Repeated { + s += ",rep" + } + if p.Packed { + s += ",packed" + } + s += ",name=" + p.OrigName + if p.JSONName != p.OrigName { + s += ",json=" + p.JSONName + } + if p.proto3 { + s += ",proto3" + } + if p.oneof { + s += ",oneof" + } + if len(p.Enum) > 0 { + s += ",enum=" + p.Enum + } + if p.HasDefault { + s += ",def=" + p.Default + } + return s +} + +// Parse populates p by parsing a string in the protobuf struct field tag style. +func (p *Properties) Parse(s string) { + // "bytes,49,opt,name=foo,def=hello!" + fields := strings.Split(s, ",") // breaks def=, but handled below. + if len(fields) < 2 { + fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) + return + } + + p.Wire = fields[0] + switch p.Wire { + case "varint": + p.WireType = WireVarint + case "fixed32": + p.WireType = WireFixed32 + case "fixed64": + p.WireType = WireFixed64 + case "zigzag32": + p.WireType = WireVarint + case "zigzag64": + p.WireType = WireVarint + case "bytes", "group": + p.WireType = WireBytes + // no numeric converter for non-numeric types + default: + fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) + return + } + + var err error + p.Tag, err = strconv.Atoi(fields[1]) + if err != nil { + return + } + +outer: + for i := 2; i < len(fields); i++ { + f := fields[i] + switch { + case f == "req": + p.Required = true + case f == "opt": + p.Optional = true + case f == "rep": + p.Repeated = true + case f == "packed": + p.Packed = true + case strings.HasPrefix(f, "name="): + p.OrigName = f[5:] + case strings.HasPrefix(f, "json="): + p.JSONName = f[5:] + case strings.HasPrefix(f, "enum="): + p.Enum = f[5:] + case f == "proto3": + p.proto3 = true + case f == "oneof": + p.oneof = true + case strings.HasPrefix(f, "def="): + p.HasDefault = true + p.Default = f[4:] // rest of string + if i+1 < len(fields) { + // Commas aren't escaped, and def is always last. + p.Default += "," + strings.Join(fields[i+1:], ",") + break outer + } + } + } +} + +var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() + +// setFieldProps initializes the field properties for submessages and maps. +func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { + switch t1 := typ; t1.Kind() { + case reflect.Ptr: + if t1.Elem().Kind() == reflect.Struct { + p.stype = t1.Elem() + } + + case reflect.Slice: + if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct { + p.stype = t2.Elem() + } + + case reflect.Map: + p.mtype = t1 + p.MapKeyProp = &Properties{} + p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) + p.MapValProp = &Properties{} + vtype := p.mtype.Elem() + if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { + // The value type is not a message (*T) or bytes ([]byte), + // so we need encoders for the pointer to this type. + vtype = reflect.PtrTo(vtype) + } + p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) + } + + if p.stype != nil { + if lockGetProp { + p.sprop = GetProperties(p.stype) + } else { + p.sprop = getPropertiesLocked(p.stype) + } + } +} + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() +) + +// Init populates the properties from a protocol buffer struct tag. +func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { + p.init(typ, name, tag, f, true) +} + +func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { + // "bytes,49,opt,def=hello!" + p.Name = name + p.OrigName = name + if tag == "" { + return + } + p.Parse(tag) + p.setFieldProps(typ, f, lockGetProp) +} + +var ( + propertiesMu sync.RWMutex + propertiesMap = make(map[reflect.Type]*StructProperties) +) + +// GetProperties returns the list of properties for the type represented by t. +// t must represent a generated struct type of a protocol message. +func GetProperties(t reflect.Type) *StructProperties { + if t.Kind() != reflect.Struct { + panic("proto: type must have kind struct") + } + + // Most calls to GetProperties in a long-running program will be + // retrieving details for types we have seen before. + propertiesMu.RLock() + sprop, ok := propertiesMap[t] + propertiesMu.RUnlock() + if ok { + if collectStats { + stats.Chit++ + } + return sprop + } + + propertiesMu.Lock() + sprop = getPropertiesLocked(t) + propertiesMu.Unlock() + return sprop +} + +// getPropertiesLocked requires that propertiesMu is held. +func getPropertiesLocked(t reflect.Type) *StructProperties { + if prop, ok := propertiesMap[t]; ok { + if collectStats { + stats.Chit++ + } + return prop + } + if collectStats { + stats.Cmiss++ + } + + prop := new(StructProperties) + // in case of recursive protos, fill this in now. + propertiesMap[t] = prop + + // build properties + prop.Prop = make([]*Properties, t.NumField()) + prop.order = make([]int, t.NumField()) + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + p := new(Properties) + name := f.Name + p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) + + oneof := f.Tag.Get("protobuf_oneof") // special case + if oneof != "" { + // Oneof fields don't use the traditional protobuf tag. + p.OrigName = oneof + } + prop.Prop[i] = p + prop.order[i] = i + if debug { + print(i, " ", f.Name, " ", t.String(), " ") + if p.Tag > 0 { + print(p.String()) + } + print("\n") + } + } + + // Re-order prop.order. + sort.Sort(prop) + + type oneofMessage interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + } + if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { + var oots []interface{} + _, _, _, oots = om.XXX_OneofFuncs() + + // Interpret oneof metadata. + prop.OneofTypes = make(map[string]*OneofProperties) + for _, oot := range oots { + oop := &OneofProperties{ + Type: reflect.ValueOf(oot).Type(), // *T + Prop: new(Properties), + } + sft := oop.Type.Elem().Field(0) + oop.Prop.Name = sft.Name + oop.Prop.Parse(sft.Tag.Get("protobuf")) + // There will be exactly one interface field that + // this new value is assignable to. + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type.Kind() != reflect.Interface { + continue + } + if !oop.Type.AssignableTo(f.Type) { + continue + } + oop.Field = i + break + } + prop.OneofTypes[oop.Prop.OrigName] = oop + } + } + + // build required counts + // build tags + reqCount := 0 + prop.decoderOrigNames = make(map[string]int) + for i, p := range prop.Prop { + if strings.HasPrefix(p.Name, "XXX_") { + // Internal fields should not appear in tags/origNames maps. + // They are handled specially when encoding and decoding. + continue + } + if p.Required { + reqCount++ + } + prop.decoderTags.put(p.Tag, i) + prop.decoderOrigNames[p.OrigName] = i + } + prop.reqCount = reqCount + + return prop +} + +// A global registry of enum types. +// The generated code will register the generated maps by calling RegisterEnum. + +var enumValueMaps = make(map[string]map[string]int32) + +// RegisterEnum is called from the generated code to install the enum descriptor +// maps into the global table to aid parsing text format protocol buffers. +func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { + if _, ok := enumValueMaps[typeName]; ok { + panic("proto: duplicate enum registered: " + typeName) + } + enumValueMaps[typeName] = valueMap +} + +// EnumValueMap returns the mapping from names to integers of the +// enum type enumType, or a nil if not found. +func EnumValueMap(enumType string) map[string]int32 { + return enumValueMaps[enumType] +} + +// A registry of all linked message types. +// The string is a fully-qualified proto name ("pkg.Message"). +var ( + protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers + protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types + revProtoTypes = make(map[reflect.Type]string) +) + +// RegisterType is called from generated code and maps from the fully qualified +// proto name to the type (pointer to struct) of the protocol buffer. +func RegisterType(x Message, name string) { + if _, ok := protoTypedNils[name]; ok { + // TODO: Some day, make this a panic. + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { + // Generated code always calls RegisterType with nil x. + // This check is just for extra safety. + protoTypedNils[name] = x + } else { + protoTypedNils[name] = reflect.Zero(t).Interface().(Message) + } + revProtoTypes[t] = name +} + +// RegisterMapType is called from generated code and maps from the fully qualified +// proto name to the native map type of the proto map definition. +func RegisterMapType(x interface{}, name string) { + if reflect.TypeOf(x).Kind() != reflect.Map { + panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) + } + if _, ok := protoMapTypes[name]; ok { + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + protoMapTypes[name] = t + revProtoTypes[t] = name +} + +// MessageName returns the fully-qualified proto name for the given message type. +func MessageName(x Message) string { + type xname interface { + XXX_MessageName() string + } + if m, ok := x.(xname); ok { + return m.XXX_MessageName() + } + return revProtoTypes[reflect.TypeOf(x)] +} + +// MessageType returns the message type (pointer to struct) for a named message. +// The type is not guaranteed to implement proto.Message if the name refers to a +// map entry. +func MessageType(name string) reflect.Type { + if t, ok := protoTypedNils[name]; ok { + return reflect.TypeOf(t) + } + return protoMapTypes[name] +} + +// A registry of all linked proto files. +var ( + protoFiles = make(map[string][]byte) // file name => fileDescriptor +) + +// RegisterFile is called from generated code and maps from the +// full file name of a .proto file to its compressed FileDescriptorProto. +func RegisterFile(filename string, fileDescriptor []byte) { + protoFiles[filename] = fileDescriptor +} + +// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. +func FileDescriptor(filename string) []byte { return protoFiles[filename] } diff --git a/vendor/github.com/golang/protobuf/proto/table_marshal.go b/vendor/github.com/golang/protobuf/proto/table_marshal.go new file mode 100644 index 000000000..b16794496 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/table_marshal.go @@ -0,0 +1,2767 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +import ( + "errors" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "sync/atomic" + "unicode/utf8" +) + +// a sizer takes a pointer to a field and the size of its tag, computes the size of +// the encoded data. +type sizer func(pointer, int) int + +// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format), +// marshals the field to the end of the slice, returns the slice and error (if any). +type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) + +// marshalInfo is the information used for marshaling a message. +type marshalInfo struct { + typ reflect.Type + fields []*marshalFieldInfo + unrecognized field // offset of XXX_unrecognized + extensions field // offset of XXX_InternalExtensions + v1extensions field // offset of XXX_extensions + sizecache field // offset of XXX_sizecache + initialized int32 // 0 -- only typ is set, 1 -- fully initialized + messageset bool // uses message set wire format + hasmarshaler bool // has custom marshaler + sync.RWMutex // protect extElems map, also for initialization + extElems map[int32]*marshalElemInfo // info of extension elements +} + +// marshalFieldInfo is the information used for marshaling a field of a message. +type marshalFieldInfo struct { + field field + wiretag uint64 // tag in wire format + tagsize int // size of tag in wire format + sizer sizer + marshaler marshaler + isPointer bool + required bool // field is required + name string // name of the field, for error reporting + oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements +} + +// marshalElemInfo is the information used for marshaling an extension or oneof element. +type marshalElemInfo struct { + wiretag uint64 // tag in wire format + tagsize int // size of tag in wire format + sizer sizer + marshaler marshaler + isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) +} + +var ( + marshalInfoMap = map[reflect.Type]*marshalInfo{} + marshalInfoLock sync.Mutex +) + +// getMarshalInfo returns the information to marshal a given type of message. +// The info it returns may not necessarily initialized. +// t is the type of the message (NOT the pointer to it). +func getMarshalInfo(t reflect.Type) *marshalInfo { + marshalInfoLock.Lock() + u, ok := marshalInfoMap[t] + if !ok { + u = &marshalInfo{typ: t} + marshalInfoMap[t] = u + } + marshalInfoLock.Unlock() + return u +} + +// Size is the entry point from generated code, +// and should be ONLY called by generated code. +// It computes the size of encoded data of msg. +// a is a pointer to a place to store cached marshal info. +func (a *InternalMessageInfo) Size(msg Message) int { + u := getMessageMarshalInfo(msg, a) + ptr := toPointer(&msg) + if ptr.isNil() { + // We get here if msg is a typed nil ((*SomeMessage)(nil)), + // so it satisfies the interface, and msg == nil wouldn't + // catch it. We don't want crash in this case. + return 0 + } + return u.size(ptr) +} + +// Marshal is the entry point from generated code, +// and should be ONLY called by generated code. +// It marshals msg to the end of b. +// a is a pointer to a place to store cached marshal info. +func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) { + u := getMessageMarshalInfo(msg, a) + ptr := toPointer(&msg) + if ptr.isNil() { + // We get here if msg is a typed nil ((*SomeMessage)(nil)), + // so it satisfies the interface, and msg == nil wouldn't + // catch it. We don't want crash in this case. + return b, ErrNil + } + return u.marshal(b, ptr, deterministic) +} + +func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo { + // u := a.marshal, but atomically. + // We use an atomic here to ensure memory consistency. + u := atomicLoadMarshalInfo(&a.marshal) + if u == nil { + // Get marshal information from type of message. + t := reflect.ValueOf(msg).Type() + if t.Kind() != reflect.Ptr { + panic(fmt.Sprintf("cannot handle non-pointer message type %v", t)) + } + u = getMarshalInfo(t.Elem()) + // Store it in the cache for later users. + // a.marshal = u, but atomically. + atomicStoreMarshalInfo(&a.marshal, u) + } + return u +} + +// size is the main function to compute the size of the encoded data of a message. +// ptr is the pointer to the message. +func (u *marshalInfo) size(ptr pointer) int { + if atomic.LoadInt32(&u.initialized) == 0 { + u.computeMarshalInfo() + } + + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if u.hasmarshaler { + m := ptr.asPointerTo(u.typ).Interface().(Marshaler) + b, _ := m.Marshal() + return len(b) + } + + n := 0 + for _, f := range u.fields { + if f.isPointer && ptr.offset(f.field).getPointer().isNil() { + // nil pointer always marshals to nothing + continue + } + n += f.sizer(ptr.offset(f.field), f.tagsize) + } + if u.extensions.IsValid() { + e := ptr.offset(u.extensions).toExtensions() + if u.messageset { + n += u.sizeMessageSet(e) + } else { + n += u.sizeExtensions(e) + } + } + if u.v1extensions.IsValid() { + m := *ptr.offset(u.v1extensions).toOldExtensions() + n += u.sizeV1Extensions(m) + } + if u.unrecognized.IsValid() { + s := *ptr.offset(u.unrecognized).toBytes() + n += len(s) + } + // cache the result for use in marshal + if u.sizecache.IsValid() { + atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n)) + } + return n +} + +// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated), +// fall back to compute the size. +func (u *marshalInfo) cachedsize(ptr pointer) int { + if u.sizecache.IsValid() { + return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32())) + } + return u.size(ptr) +} + +// marshal is the main function to marshal a message. It takes a byte slice and appends +// the encoded data to the end of the slice, returns the slice and error (if any). +// ptr is the pointer to the message. +// If deterministic is true, map is marshaled in deterministic order. +func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) { + if atomic.LoadInt32(&u.initialized) == 0 { + u.computeMarshalInfo() + } + + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if u.hasmarshaler { + m := ptr.asPointerTo(u.typ).Interface().(Marshaler) + b1, err := m.Marshal() + b = append(b, b1...) + return b, err + } + + var err, errLater error + // The old marshaler encodes extensions at beginning. + if u.extensions.IsValid() { + e := ptr.offset(u.extensions).toExtensions() + if u.messageset { + b, err = u.appendMessageSet(b, e, deterministic) + } else { + b, err = u.appendExtensions(b, e, deterministic) + } + if err != nil { + return b, err + } + } + if u.v1extensions.IsValid() { + m := *ptr.offset(u.v1extensions).toOldExtensions() + b, err = u.appendV1Extensions(b, m, deterministic) + if err != nil { + return b, err + } + } + for _, f := range u.fields { + if f.required { + if ptr.offset(f.field).getPointer().isNil() { + // Required field is not set. + // We record the error but keep going, to give a complete marshaling. + if errLater == nil { + errLater = &RequiredNotSetError{f.name} + } + continue + } + } + if f.isPointer && ptr.offset(f.field).getPointer().isNil() { + // nil pointer always marshals to nothing + continue + } + b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic) + if err != nil { + if err1, ok := err.(*RequiredNotSetError); ok { + // Required field in submessage is not set. + // We record the error but keep going, to give a complete marshaling. + if errLater == nil { + errLater = &RequiredNotSetError{f.name + "." + err1.field} + } + continue + } + if err == errRepeatedHasNil { + err = errors.New("proto: repeated field " + f.name + " has nil element") + } + if err == errInvalidUTF8 { + if errLater == nil { + fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name + errLater = &invalidUTF8Error{fullName} + } + continue + } + return b, err + } + } + if u.unrecognized.IsValid() { + s := *ptr.offset(u.unrecognized).toBytes() + b = append(b, s...) + } + return b, errLater +} + +// computeMarshalInfo initializes the marshal info. +func (u *marshalInfo) computeMarshalInfo() { + u.Lock() + defer u.Unlock() + if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock + return + } + + t := u.typ + u.unrecognized = invalidField + u.extensions = invalidField + u.v1extensions = invalidField + u.sizecache = invalidField + + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + if reflect.PtrTo(t).Implements(marshalerType) { + u.hasmarshaler = true + atomic.StoreInt32(&u.initialized, 1) + return + } + + // get oneof implementers + var oneofImplementers []interface{} + if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { + _, _, _, oneofImplementers = m.XXX_OneofFuncs() + } + + n := t.NumField() + + // deal with XXX fields first + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if !strings.HasPrefix(f.Name, "XXX_") { + continue + } + switch f.Name { + case "XXX_sizecache": + u.sizecache = toField(&f) + case "XXX_unrecognized": + u.unrecognized = toField(&f) + case "XXX_InternalExtensions": + u.extensions = toField(&f) + u.messageset = f.Tag.Get("protobuf_messageset") == "1" + case "XXX_extensions": + u.v1extensions = toField(&f) + case "XXX_NoUnkeyedLiteral": + // nothing to do + default: + panic("unknown XXX field: " + f.Name) + } + n-- + } + + // normal fields + fields := make([]marshalFieldInfo, n) // batch allocation + u.fields = make([]*marshalFieldInfo, 0, n) + for i, j := 0, 0; i < t.NumField(); i++ { + f := t.Field(i) + + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + field := &fields[j] + j++ + field.name = f.Name + u.fields = append(u.fields, field) + if f.Tag.Get("protobuf_oneof") != "" { + field.computeOneofFieldInfo(&f, oneofImplementers) + continue + } + if f.Tag.Get("protobuf") == "" { + // field has no tag (not in generated message), ignore it + u.fields = u.fields[:len(u.fields)-1] + j-- + continue + } + field.computeMarshalFieldInfo(&f) + } + + // fields are marshaled in tag order on the wire. + sort.Sort(byTag(u.fields)) + + atomic.StoreInt32(&u.initialized, 1) +} + +// helper for sorting fields by tag +type byTag []*marshalFieldInfo + +func (a byTag) Len() int { return len(a) } +func (a byTag) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag } + +// getExtElemInfo returns the information to marshal an extension element. +// The info it returns is initialized. +func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { + // get from cache first + u.RLock() + e, ok := u.extElems[desc.Field] + u.RUnlock() + if ok { + return e + } + + t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct + tags := strings.Split(desc.Tag, ",") + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + sizer, marshaler := typeMarshaler(t, tags, false, false) + e = &marshalElemInfo{ + wiretag: uint64(tag)<<3 | wt, + tagsize: SizeVarint(uint64(tag) << 3), + sizer: sizer, + marshaler: marshaler, + isptr: t.Kind() == reflect.Ptr, + } + + // update cache + u.Lock() + if u.extElems == nil { + u.extElems = make(map[int32]*marshalElemInfo) + } + u.extElems[desc.Field] = e + u.Unlock() + return e +} + +// computeMarshalFieldInfo fills up the information to marshal a field. +func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { + // parse protobuf tag of the field. + // tag has format of "bytes,49,opt,name=foo,def=hello!" + tags := strings.Split(f.Tag.Get("protobuf"), ",") + if tags[0] == "" { + return + } + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + if tags[2] == "req" { + fi.required = true + } + fi.setTag(f, tag, wt) + fi.setMarshaler(f, tags) +} + +func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { + fi.field = toField(f) + fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. + fi.isPointer = true + fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) + fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) + + ityp := f.Type // interface type + for _, o := range oneofImplementers { + t := reflect.TypeOf(o) + if !t.Implements(ityp) { + continue + } + sf := t.Elem().Field(0) // oneof implementer is a struct with a single field + tags := strings.Split(sf.Tag.Get("protobuf"), ",") + tag, err := strconv.Atoi(tags[1]) + if err != nil { + panic("tag is not an integer") + } + wt := wiretype(tags[0]) + sizer, marshaler := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value + fi.oneofElems[t.Elem()] = &marshalElemInfo{ + wiretag: uint64(tag)<<3 | wt, + tagsize: SizeVarint(uint64(tag) << 3), + sizer: sizer, + marshaler: marshaler, + } + } +} + +type oneofMessage interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) +} + +// wiretype returns the wire encoding of the type. +func wiretype(encoding string) uint64 { + switch encoding { + case "fixed32": + return WireFixed32 + case "fixed64": + return WireFixed64 + case "varint", "zigzag32", "zigzag64": + return WireVarint + case "bytes": + return WireBytes + case "group": + return WireStartGroup + } + panic("unknown wire type " + encoding) +} + +// setTag fills up the tag (in wire format) and its size in the info of a field. +func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) { + fi.field = toField(f) + fi.wiretag = uint64(tag)<<3 | wt + fi.tagsize = SizeVarint(uint64(tag) << 3) +} + +// setMarshaler fills up the sizer and marshaler in the info of a field. +func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) { + switch f.Type.Kind() { + case reflect.Map: + // map field + fi.isPointer = true + fi.sizer, fi.marshaler = makeMapMarshaler(f) + return + case reflect.Ptr, reflect.Slice: + fi.isPointer = true + } + fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false) +} + +// typeMarshaler returns the sizer and marshaler of a given field. +// t is the type of the field. +// tags is the generated "protobuf" tag of the field. +// If nozero is true, zero value is not marshaled to the wire. +// If oneof is true, it is a oneof field. +func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) { + encoding := tags[0] + + pointer := false + slice := false + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + slice = true + t = t.Elem() + } + if t.Kind() == reflect.Ptr { + pointer = true + t = t.Elem() + } + + packed := false + proto3 := false + validateUTF8 := true + for i := 2; i < len(tags); i++ { + if tags[i] == "packed" { + packed = true + } + if tags[i] == "proto3" { + proto3 = true + } + } + validateUTF8 = validateUTF8 && proto3 + + switch t.Kind() { + case reflect.Bool: + if pointer { + return sizeBoolPtr, appendBoolPtr + } + if slice { + if packed { + return sizeBoolPackedSlice, appendBoolPackedSlice + } + return sizeBoolSlice, appendBoolSlice + } + if nozero { + return sizeBoolValueNoZero, appendBoolValueNoZero + } + return sizeBoolValue, appendBoolValue + case reflect.Uint32: + switch encoding { + case "fixed32": + if pointer { + return sizeFixed32Ptr, appendFixed32Ptr + } + if slice { + if packed { + return sizeFixed32PackedSlice, appendFixed32PackedSlice + } + return sizeFixed32Slice, appendFixed32Slice + } + if nozero { + return sizeFixed32ValueNoZero, appendFixed32ValueNoZero + } + return sizeFixed32Value, appendFixed32Value + case "varint": + if pointer { + return sizeVarint32Ptr, appendVarint32Ptr + } + if slice { + if packed { + return sizeVarint32PackedSlice, appendVarint32PackedSlice + } + return sizeVarint32Slice, appendVarint32Slice + } + if nozero { + return sizeVarint32ValueNoZero, appendVarint32ValueNoZero + } + return sizeVarint32Value, appendVarint32Value + } + case reflect.Int32: + switch encoding { + case "fixed32": + if pointer { + return sizeFixedS32Ptr, appendFixedS32Ptr + } + if slice { + if packed { + return sizeFixedS32PackedSlice, appendFixedS32PackedSlice + } + return sizeFixedS32Slice, appendFixedS32Slice + } + if nozero { + return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero + } + return sizeFixedS32Value, appendFixedS32Value + case "varint": + if pointer { + return sizeVarintS32Ptr, appendVarintS32Ptr + } + if slice { + if packed { + return sizeVarintS32PackedSlice, appendVarintS32PackedSlice + } + return sizeVarintS32Slice, appendVarintS32Slice + } + if nozero { + return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero + } + return sizeVarintS32Value, appendVarintS32Value + case "zigzag32": + if pointer { + return sizeZigzag32Ptr, appendZigzag32Ptr + } + if slice { + if packed { + return sizeZigzag32PackedSlice, appendZigzag32PackedSlice + } + return sizeZigzag32Slice, appendZigzag32Slice + } + if nozero { + return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero + } + return sizeZigzag32Value, appendZigzag32Value + } + case reflect.Uint64: + switch encoding { + case "fixed64": + if pointer { + return sizeFixed64Ptr, appendFixed64Ptr + } + if slice { + if packed { + return sizeFixed64PackedSlice, appendFixed64PackedSlice + } + return sizeFixed64Slice, appendFixed64Slice + } + if nozero { + return sizeFixed64ValueNoZero, appendFixed64ValueNoZero + } + return sizeFixed64Value, appendFixed64Value + case "varint": + if pointer { + return sizeVarint64Ptr, appendVarint64Ptr + } + if slice { + if packed { + return sizeVarint64PackedSlice, appendVarint64PackedSlice + } + return sizeVarint64Slice, appendVarint64Slice + } + if nozero { + return sizeVarint64ValueNoZero, appendVarint64ValueNoZero + } + return sizeVarint64Value, appendVarint64Value + } + case reflect.Int64: + switch encoding { + case "fixed64": + if pointer { + return sizeFixedS64Ptr, appendFixedS64Ptr + } + if slice { + if packed { + return sizeFixedS64PackedSlice, appendFixedS64PackedSlice + } + return sizeFixedS64Slice, appendFixedS64Slice + } + if nozero { + return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero + } + return sizeFixedS64Value, appendFixedS64Value + case "varint": + if pointer { + return sizeVarintS64Ptr, appendVarintS64Ptr + } + if slice { + if packed { + return sizeVarintS64PackedSlice, appendVarintS64PackedSlice + } + return sizeVarintS64Slice, appendVarintS64Slice + } + if nozero { + return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero + } + return sizeVarintS64Value, appendVarintS64Value + case "zigzag64": + if pointer { + return sizeZigzag64Ptr, appendZigzag64Ptr + } + if slice { + if packed { + return sizeZigzag64PackedSlice, appendZigzag64PackedSlice + } + return sizeZigzag64Slice, appendZigzag64Slice + } + if nozero { + return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero + } + return sizeZigzag64Value, appendZigzag64Value + } + case reflect.Float32: + if pointer { + return sizeFloat32Ptr, appendFloat32Ptr + } + if slice { + if packed { + return sizeFloat32PackedSlice, appendFloat32PackedSlice + } + return sizeFloat32Slice, appendFloat32Slice + } + if nozero { + return sizeFloat32ValueNoZero, appendFloat32ValueNoZero + } + return sizeFloat32Value, appendFloat32Value + case reflect.Float64: + if pointer { + return sizeFloat64Ptr, appendFloat64Ptr + } + if slice { + if packed { + return sizeFloat64PackedSlice, appendFloat64PackedSlice + } + return sizeFloat64Slice, appendFloat64Slice + } + if nozero { + return sizeFloat64ValueNoZero, appendFloat64ValueNoZero + } + return sizeFloat64Value, appendFloat64Value + case reflect.String: + if validateUTF8 { + if pointer { + return sizeStringPtr, appendUTF8StringPtr + } + if slice { + return sizeStringSlice, appendUTF8StringSlice + } + if nozero { + return sizeStringValueNoZero, appendUTF8StringValueNoZero + } + return sizeStringValue, appendUTF8StringValue + } + if pointer { + return sizeStringPtr, appendStringPtr + } + if slice { + return sizeStringSlice, appendStringSlice + } + if nozero { + return sizeStringValueNoZero, appendStringValueNoZero + } + return sizeStringValue, appendStringValue + case reflect.Slice: + if slice { + return sizeBytesSlice, appendBytesSlice + } + if oneof { + // Oneof bytes field may also have "proto3" tag. + // We want to marshal it as a oneof field. Do this + // check before the proto3 check. + return sizeBytesOneof, appendBytesOneof + } + if proto3 { + return sizeBytes3, appendBytes3 + } + return sizeBytes, appendBytes + case reflect.Struct: + switch encoding { + case "group": + if slice { + return makeGroupSliceMarshaler(getMarshalInfo(t)) + } + return makeGroupMarshaler(getMarshalInfo(t)) + case "bytes": + if slice { + return makeMessageSliceMarshaler(getMarshalInfo(t)) + } + return makeMessageMarshaler(getMarshalInfo(t)) + } + } + panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding)) +} + +// Below are functions to size/marshal a specific type of a field. +// They are stored in the field's info, and called by function pointers. +// They have type sizer or marshaler. + +func sizeFixed32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFixed32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFixed32Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + return (4 + tagsize) * len(s) +} +func sizeFixed32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFixedS32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFixedS32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFixedS32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + return (4 + tagsize) * len(s) +} +func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFloat32Value(_ pointer, tagsize int) int { + return 4 + tagsize +} +func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int { + v := math.Float32bits(*ptr.toFloat32()) + if v == 0 { + return 0 + } + return 4 + tagsize +} +func sizeFloat32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toFloat32Ptr() + if p == nil { + return 0 + } + return 4 + tagsize +} +func sizeFloat32Slice(ptr pointer, tagsize int) int { + s := *ptr.toFloat32Slice() + return (4 + tagsize) * len(s) +} +func sizeFloat32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toFloat32Slice() + if len(s) == 0 { + return 0 + } + return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize +} +func sizeFixed64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFixed64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFixed64Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + return (8 + tagsize) * len(s) +} +func sizeFixed64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeFixedS64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFixedS64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFixedS64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + return (8 + tagsize) * len(s) +} +func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeFloat64Value(_ pointer, tagsize int) int { + return 8 + tagsize +} +func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int { + v := math.Float64bits(*ptr.toFloat64()) + if v == 0 { + return 0 + } + return 8 + tagsize +} +func sizeFloat64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toFloat64Ptr() + if p == nil { + return 0 + } + return 8 + tagsize +} +func sizeFloat64Slice(ptr pointer, tagsize int) int { + s := *ptr.toFloat64Slice() + return (8 + tagsize) * len(s) +} +func sizeFloat64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toFloat64Slice() + if len(s) == 0 { + return 0 + } + return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize +} +func sizeVarint32Value(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint32() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarint32Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint32Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarint32Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarint32PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarintS32Value(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarintS32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarint64Value(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + return SizeVarint(v) + tagsize +} +func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toUint64() + if v == 0 { + return 0 + } + return SizeVarint(v) + tagsize +} +func sizeVarint64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toUint64Ptr() + if p == nil { + return 0 + } + return SizeVarint(*p) + tagsize +} +func sizeVarint64Slice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(v) + tagsize + } + return n +} +func sizeVarint64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(v) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeVarintS64Value(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v)) + tagsize +} +func sizeVarintS64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + return SizeVarint(uint64(*p)) + tagsize +} +func sizeVarintS64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + tagsize + } + return n +} +func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeZigzag32Value(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt32() + if v == 0 { + return 0 + } + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32Ptr(ptr pointer, tagsize int) int { + p := ptr.getInt32Ptr() + if p == nil { + return 0 + } + v := *p + return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize +} +func sizeZigzag32Slice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize + } + return n +} +func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int { + s := ptr.getInt32Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeZigzag64Value(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toInt64() + if v == 0 { + return 0 + } + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64Ptr(ptr pointer, tagsize int) int { + p := *ptr.toInt64Ptr() + if p == nil { + return 0 + } + v := *p + return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize +} +func sizeZigzag64Slice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize + } + return n +} +func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return 0 + } + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) + } + return n + SizeVarint(uint64(n)) + tagsize +} +func sizeBoolValue(_ pointer, tagsize int) int { + return 1 + tagsize +} +func sizeBoolValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toBool() + if !v { + return 0 + } + return 1 + tagsize +} +func sizeBoolPtr(ptr pointer, tagsize int) int { + p := *ptr.toBoolPtr() + if p == nil { + return 0 + } + return 1 + tagsize +} +func sizeBoolSlice(ptr pointer, tagsize int) int { + s := *ptr.toBoolSlice() + return (1 + tagsize) * len(s) +} +func sizeBoolPackedSlice(ptr pointer, tagsize int) int { + s := *ptr.toBoolSlice() + if len(s) == 0 { + return 0 + } + return len(s) + SizeVarint(uint64(len(s))) + tagsize +} +func sizeStringValue(ptr pointer, tagsize int) int { + v := *ptr.toString() + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringValueNoZero(ptr pointer, tagsize int) int { + v := *ptr.toString() + if v == "" { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringPtr(ptr pointer, tagsize int) int { + p := *ptr.toStringPtr() + if p == nil { + return 0 + } + v := *p + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeStringSlice(ptr pointer, tagsize int) int { + s := *ptr.toStringSlice() + n := 0 + for _, v := range s { + n += len(v) + SizeVarint(uint64(len(v))) + tagsize + } + return n +} +func sizeBytes(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + if v == nil { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytes3(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + if len(v) == 0 { + return 0 + } + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytesOneof(ptr pointer, tagsize int) int { + v := *ptr.toBytes() + return len(v) + SizeVarint(uint64(len(v))) + tagsize +} +func sizeBytesSlice(ptr pointer, tagsize int) int { + s := *ptr.toBytesSlice() + n := 0 + for _, v := range s { + n += len(v) + SizeVarint(uint64(len(v))) + tagsize + } + return n +} + +// appendFixed32 appends an encoded fixed32 to b. +func appendFixed32(b []byte, v uint32) []byte { + b = append(b, + byte(v), + byte(v>>8), + byte(v>>16), + byte(v>>24)) + return b +} + +// appendFixed64 appends an encoded fixed64 to b. +func appendFixed64(b []byte, v uint64) []byte { + b = append(b, + byte(v), + byte(v>>8), + byte(v>>16), + byte(v>>24), + byte(v>>32), + byte(v>>40), + byte(v>>48), + byte(v>>56)) + return b +} + +// appendVarint appends an encoded varint to b. +func appendVarint(b []byte, v uint64) []byte { + // TODO: make 1-byte (maybe 2-byte) case inline-able, once we + // have non-leaf inliner. + switch { + case v < 1<<7: + b = append(b, byte(v)) + case v < 1<<14: + b = append(b, + byte(v&0x7f|0x80), + byte(v>>7)) + case v < 1<<21: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte(v>>14)) + case v < 1<<28: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte(v>>21)) + case v < 1<<35: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte(v>>28)) + case v < 1<<42: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte(v>>35)) + case v < 1<<49: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte(v>>42)) + case v < 1<<56: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte(v>>49)) + case v < 1<<63: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte((v>>49)&0x7f|0x80), + byte(v>>56)) + default: + b = append(b, + byte(v&0x7f|0x80), + byte((v>>7)&0x7f|0x80), + byte((v>>14)&0x7f|0x80), + byte((v>>21)&0x7f|0x80), + byte((v>>28)&0x7f|0x80), + byte((v>>35)&0x7f|0x80), + byte((v>>42)&0x7f|0x80), + byte((v>>49)&0x7f|0x80), + byte((v>>56)&0x7f|0x80), + 1) + } + return b +} + +func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, *p) + return b, nil +} +func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + } + return b, nil +} +func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, v) + } + return b, nil +} +func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + return b, nil +} +func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + return b, nil +} +func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(*p)) + return b, nil +} +func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, uint32(v)) + } + return b, nil +} +func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, uint32(v)) + } + return b, nil +} +func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float32bits(*ptr.toFloat32()) + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float32bits(*ptr.toFloat32()) + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, v) + return b, nil +} +func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toFloat32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed32(b, math.Float32bits(*p)) + return b, nil +} +func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed32(b, math.Float32bits(v)) + } + return b, nil +} +func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(4*len(s))) + for _, v := range s { + b = appendFixed32(b, math.Float32bits(v)) + } + return b, nil +} +func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, *p) + return b, nil +} +func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + } + return b, nil +} +func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, v) + } + return b, nil +} +func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + return b, nil +} +func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + return b, nil +} +func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(*p)) + return b, nil +} +func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, uint64(v)) + } + return b, nil +} +func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, uint64(v)) + } + return b, nil +} +func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float64bits(*ptr.toFloat64()) + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := math.Float64bits(*ptr.toFloat64()) + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, v) + return b, nil +} +func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toFloat64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendFixed64(b, math.Float64bits(*p)) + return b, nil +} +func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendFixed64(b, math.Float64bits(v)) + } + return b, nil +} +func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toFloat64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(8*len(s))) + for _, v := range s { + b = appendFixed64(b, math.Float64bits(v)) + } + return b, nil +} +func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + return b, nil +} +func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toUint64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + return b, nil +} +func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toUint64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, *p) + return b, nil +} +func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, v) + } + return b, nil +} +func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toUint64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(v) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, v) + } + return b, nil +} +func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + return b, nil +} +func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(*p)) + return b, nil +} +func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v)) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v)) + } + return b, nil +} +func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt32() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := ptr.getInt32Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + v := *p + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + return b, nil +} +func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + } + return b, nil +} +func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := ptr.getInt32Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + } + return b, nil +} +func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toInt64() + if v == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toInt64Ptr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + v := *p + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + return b, nil +} +func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + } + return b, nil +} +func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toInt64Slice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + // compute size + n := 0 + for _, v := range s { + n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) + } + b = appendVarint(b, uint64(n)) + for _, v := range s { + b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) + } + return b, nil +} +func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBool() + b = appendVarint(b, wiretag) + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + return b, nil +} +func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBool() + if !v { + return b, nil + } + b = appendVarint(b, wiretag) + b = append(b, 1) + return b, nil +} + +func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toBoolPtr() + if p == nil { + return b, nil + } + b = appendVarint(b, wiretag) + if *p { + b = append(b, 1) + } else { + b = append(b, 0) + } + return b, nil +} +func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBoolSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + } + return b, nil +} +func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBoolSlice() + if len(s) == 0 { + return b, nil + } + b = appendVarint(b, wiretag&^7|WireBytes) + b = appendVarint(b, uint64(len(s))) + for _, v := range s { + if v { + b = append(b, 1) + } else { + b = append(b, 0) + } + } + return b, nil +} +func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toString() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toString() + if v == "" { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + p := *ptr.toStringPtr() + if p == nil { + return b, nil + } + v := *p + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toStringSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + return b, nil +} +func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + v := *ptr.toString() + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + v := *ptr.toString() + if v == "" { + return b, nil + } + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + p := *ptr.toStringPtr() + if p == nil { + return b, nil + } + v := *p + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + var invalidUTF8 bool + s := *ptr.toStringSlice() + for _, v := range s { + if !utf8.ValidString(v) { + invalidUTF8 = true + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + if invalidUTF8 { + return b, errInvalidUTF8 + } + return b, nil +} +func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + if v == nil { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + if len(v) == 0 { + return b, nil + } + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + v := *ptr.toBytes() + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + return b, nil +} +func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { + s := *ptr.toBytesSlice() + for _, v := range s { + b = appendVarint(b, wiretag) + b = appendVarint(b, uint64(len(v))) + b = append(b, v...) + } + return b, nil +} + +// makeGroupMarshaler returns the sizer and marshaler for a group. +// u is the marshal info of the underlying message. +func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + p := ptr.getPointer() + if p.isNil() { + return 0 + } + return u.size(p) + 2*tagsize + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + p := ptr.getPointer() + if p.isNil() { + return b, nil + } + var err error + b = appendVarint(b, wiretag) // start group + b, err = u.marshal(b, p, deterministic) + b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group + return b, err + } +} + +// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice. +// u is the marshal info of the underlying message. +func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getPointerSlice() + n := 0 + for _, v := range s { + if v.isNil() { + continue + } + n += u.size(v) + 2*tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getPointerSlice() + var err error + var nerr nonFatal + for _, v := range s { + if v.isNil() { + return b, errRepeatedHasNil + } + b = appendVarint(b, wiretag) // start group + b, err = u.marshal(b, v, deterministic) + b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group + if !nerr.Merge(err) { + if err == ErrNil { + err = errRepeatedHasNil + } + return b, err + } + } + return b, nerr.E + } +} + +// makeMessageMarshaler returns the sizer and marshaler for a message field. +// u is the marshal info of the message. +func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + p := ptr.getPointer() + if p.isNil() { + return 0 + } + siz := u.size(p) + return siz + SizeVarint(uint64(siz)) + tagsize + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + p := ptr.getPointer() + if p.isNil() { + return b, nil + } + b = appendVarint(b, wiretag) + siz := u.cachedsize(p) + b = appendVarint(b, uint64(siz)) + return u.marshal(b, p, deterministic) + } +} + +// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice. +// u is the marshal info of the message. +func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { + return func(ptr pointer, tagsize int) int { + s := ptr.getPointerSlice() + n := 0 + for _, v := range s { + if v.isNil() { + continue + } + siz := u.size(v) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { + s := ptr.getPointerSlice() + var err error + var nerr nonFatal + for _, v := range s { + if v.isNil() { + return b, errRepeatedHasNil + } + b = appendVarint(b, wiretag) + siz := u.cachedsize(v) + b = appendVarint(b, uint64(siz)) + b, err = u.marshal(b, v, deterministic) + + if !nerr.Merge(err) { + if err == ErrNil { + err = errRepeatedHasNil + } + return b, err + } + } + return b, nerr.E + } +} + +// makeMapMarshaler returns the sizer and marshaler for a map field. +// f is the pointer to the reflect data structure of the field. +func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { + // figure out key and value type + t := f.Type + keyType := t.Key() + valType := t.Elem() + keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",") + valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") + keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map + valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map + keyWireTag := 1<<3 | wiretype(keyTags[0]) + valWireTag := 2<<3 | wiretype(valTags[0]) + + // We create an interface to get the addresses of the map key and value. + // If value is pointer-typed, the interface is a direct interface, the + // idata itself is the value. Otherwise, the idata is the pointer to the + // value. + // Key cannot be pointer-typed. + valIsPtr := valType.Kind() == reflect.Ptr + + // If value is a message with nested maps, calling + // valSizer in marshal may be quadratic. We should use + // cached version in marshal (but not in size). + // If value is not message type, we don't have size cache, + // but it cannot be nested either. Just use valSizer. + valCachedSizer := valSizer + if valIsPtr && valType.Elem().Kind() == reflect.Struct { + u := getMarshalInfo(valType.Elem()) + valCachedSizer = func(ptr pointer, tagsize int) int { + // Same as message sizer, but use cache. + p := ptr.getPointer() + if p.isNil() { + return 0 + } + siz := u.cachedsize(p) + return siz + SizeVarint(uint64(siz)) + tagsize + } + } + return func(ptr pointer, tagsize int) int { + m := ptr.asPointerTo(t).Elem() // the map + n := 0 + for _, k := range m.MapKeys() { + ki := k.Interface() + vi := m.MapIndex(k).Interface() + kaddr := toAddrPointer(&ki, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value + siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) + n += siz + SizeVarint(uint64(siz)) + tagsize + } + return n + }, + func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) { + m := ptr.asPointerTo(t).Elem() // the map + var err error + keys := m.MapKeys() + if len(keys) > 1 && deterministic { + sort.Sort(mapKeys(keys)) + } + + var nerr nonFatal + for _, k := range keys { + ki := k.Interface() + vi := m.MapIndex(k).Interface() + kaddr := toAddrPointer(&ki, false) // pointer to key + vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value + b = appendVarint(b, tag) + siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) + b = appendVarint(b, uint64(siz)) + b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) + if !nerr.Merge(err) { + return b, err + } + b, err = valMarshaler(b, vaddr, valWireTag, deterministic) + if err != ErrNil && !nerr.Merge(err) { // allow nil value in map + return b, err + } + } + return b, nerr.E + } +} + +// makeOneOfMarshaler returns the sizer and marshaler for a oneof field. +// fi is the marshal info of the field. +// f is the pointer to the reflect data structure of the field. +func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) { + // Oneof field is an interface. We need to get the actual data type on the fly. + t := f.Type + return func(ptr pointer, _ int) int { + p := ptr.getInterfacePointer() + if p.isNil() { + return 0 + } + v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct + telem := v.Type() + e := fi.oneofElems[telem] + return e.sizer(p, e.tagsize) + }, + func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) { + p := ptr.getInterfacePointer() + if p.isNil() { + return b, nil + } + v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct + telem := v.Type() + if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() { + return b, errOneofHasNil + } + e := fi.oneofElems[telem] + return e.marshaler(b, p, e.wiretag, deterministic) + } +} + +// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field. +func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { + m, mu := ext.extensionsRead() + if m == nil { + return 0 + } + mu.Lock() + + n := 0 + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + n += ei.sizer(p, ei.tagsize) + } + mu.Unlock() + return n +} + +// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b. +func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { + m, mu := ext.extensionsRead() + if m == nil { + return b, nil + } + mu.Lock() + defer mu.Unlock() + + var err error + var nerr nonFatal + + // Fast-path for common cases: zero or one extensions. + // Don't bother sorting the keys. + if len(m) <= 1 { + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E + } + + // Sort the keys to provide a deterministic encoding. + // Not sure this is required, but the old code does it. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + for _, k := range keys { + e := m[int32(k)] + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// message set format is: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required string message = 3; +// }; +// } + +// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field +// in message set format (above). +func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { + m, mu := ext.extensionsRead() + if m == nil { + return 0 + } + mu.Lock() + + n := 0 + for id, e := range m { + n += 2 // start group, end group. tag = 1 (size=1) + n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + siz := len(msgWithLen) + n += siz + 1 // message, tag = 3 (size=1) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + n += ei.sizer(p, 1) // message, tag = 3 (size=1) + } + mu.Unlock() + return n +} + +// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above) +// to the end of byte slice b. +func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { + m, mu := ext.extensionsRead() + if m == nil { + return b, nil + } + mu.Lock() + defer mu.Unlock() + + var err error + var nerr nonFatal + + // Fast-path for common cases: zero or one extensions. + // Don't bother sorting the keys. + if len(m) <= 1 { + for id, e := range m { + b = append(b, 1<<3|WireStartGroup) + b = append(b, 2<<3|WireVarint) + b = appendVarint(b, uint64(id)) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + b = append(b, 3<<3|WireBytes) + b = append(b, msgWithLen...) + b = append(b, 1<<3|WireEndGroup) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) + if !nerr.Merge(err) { + return b, err + } + b = append(b, 1<<3|WireEndGroup) + } + return b, nerr.E + } + + // Sort the keys to provide a deterministic encoding. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + for _, id := range keys { + e := m[int32(id)] + b = append(b, 1<<3|WireStartGroup) + b = append(b, 2<<3|WireVarint) + b = appendVarint(b, uint64(id)) + + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint + b = append(b, 3<<3|WireBytes) + b = append(b, msgWithLen...) + b = append(b, 1<<3|WireEndGroup) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) + b = append(b, 1<<3|WireEndGroup) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// sizeV1Extensions computes the size of encoded data for a V1-API extension field. +func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { + if m == nil { + return 0 + } + + n := 0 + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + n += ei.sizer(p, ei.tagsize) + } + return n +} + +// appendV1Extensions marshals a V1-API extension field to the end of byte slice b. +func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) { + if m == nil { + return b, nil + } + + // Sort the keys to provide a deterministic encoding. + keys := make([]int, 0, len(m)) + for k := range m { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + var err error + var nerr nonFatal + for _, k := range keys { + e := m[int32(k)] + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + b = append(b, e.enc...) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + ei := u.getExtElemInfo(e.desc) + v := e.value + p := toAddrPointer(&v, ei.isptr) + b, err = ei.marshaler(b, p, ei.wiretag, deterministic) + if !nerr.Merge(err) { + return b, err + } + } + return b, nerr.E +} + +// newMarshaler is the interface representing objects that can marshal themselves. +// +// This exists to support protoc-gen-go generated messages. +// The proto package will stop type-asserting to this interface in the future. +// +// DO NOT DEPEND ON THIS. +type newMarshaler interface { + XXX_Size() int + XXX_Marshal(b []byte, deterministic bool) ([]byte, error) +} + +// Size returns the encoded size of a protocol buffer message. +// This is the main entry point. +func Size(pb Message) int { + if m, ok := pb.(newMarshaler); ok { + return m.XXX_Size() + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + b, _ := m.Marshal() + return len(b) + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return 0 + } + var info InternalMessageInfo + return info.Size(pb) +} + +// Marshal takes a protocol buffer message +// and encodes it into the wire format, returning the data. +// This is the main entry point. +func Marshal(pb Message) ([]byte, error) { + if m, ok := pb.(newMarshaler); ok { + siz := m.XXX_Size() + b := make([]byte, 0, siz) + return m.XXX_Marshal(b, false) + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + return m.Marshal() + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return nil, ErrNil + } + var info InternalMessageInfo + siz := info.Size(pb) + b := make([]byte, 0, siz) + return info.Marshal(b, pb, false) +} + +// Marshal takes a protocol buffer message +// and encodes it into the wire format, writing the result to the +// Buffer. +// This is an alternative entry point. It is not necessary to use +// a Buffer for most applications. +func (p *Buffer) Marshal(pb Message) error { + var err error + if m, ok := pb.(newMarshaler); ok { + siz := m.XXX_Size() + p.grow(siz) // make sure buf has enough capacity + p.buf, err = m.XXX_Marshal(p.buf, p.deterministic) + return err + } + if m, ok := pb.(Marshaler); ok { + // If the message can marshal itself, let it do it, for compatibility. + // NOTE: This is not efficient. + b, err := m.Marshal() + p.buf = append(p.buf, b...) + return err + } + // in case somehow we didn't generate the wrapper + if pb == nil { + return ErrNil + } + var info InternalMessageInfo + siz := info.Size(pb) + p.grow(siz) // make sure buf has enough capacity + p.buf, err = info.Marshal(p.buf, pb, p.deterministic) + return err +} + +// grow grows the buffer's capacity, if necessary, to guarantee space for +// another n bytes. After grow(n), at least n bytes can be written to the +// buffer without another allocation. +func (p *Buffer) grow(n int) { + need := len(p.buf) + n + if need <= cap(p.buf) { + return + } + newCap := len(p.buf) * 2 + if newCap < need { + newCap = need + } + p.buf = append(make([]byte, 0, newCap), p.buf...) +} diff --git a/vendor/github.com/golang/protobuf/proto/table_merge.go b/vendor/github.com/golang/protobuf/proto/table_merge.go new file mode 100644 index 000000000..5525def6a --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/table_merge.go @@ -0,0 +1,654 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +import ( + "fmt" + "reflect" + "strings" + "sync" + "sync/atomic" +) + +// Merge merges the src message into dst. +// This assumes that dst and src of the same type and are non-nil. +func (a *InternalMessageInfo) Merge(dst, src Message) { + mi := atomicLoadMergeInfo(&a.merge) + if mi == nil { + mi = getMergeInfo(reflect.TypeOf(dst).Elem()) + atomicStoreMergeInfo(&a.merge, mi) + } + mi.merge(toPointer(&dst), toPointer(&src)) +} + +type mergeInfo struct { + typ reflect.Type + + initialized int32 // 0: only typ is valid, 1: everything is valid + lock sync.Mutex + + fields []mergeFieldInfo + unrecognized field // Offset of XXX_unrecognized +} + +type mergeFieldInfo struct { + field field // Offset of field, guaranteed to be valid + + // isPointer reports whether the value in the field is a pointer. + // This is true for the following situations: + // * Pointer to struct + // * Pointer to basic type (proto2 only) + // * Slice (first value in slice header is a pointer) + // * String (first value in string header is a pointer) + isPointer bool + + // basicWidth reports the width of the field assuming that it is directly + // embedded in the struct (as is the case for basic types in proto3). + // The possible values are: + // 0: invalid + // 1: bool + // 4: int32, uint32, float32 + // 8: int64, uint64, float64 + basicWidth int + + // Where dst and src are pointers to the types being merged. + merge func(dst, src pointer) +} + +var ( + mergeInfoMap = map[reflect.Type]*mergeInfo{} + mergeInfoLock sync.Mutex +) + +func getMergeInfo(t reflect.Type) *mergeInfo { + mergeInfoLock.Lock() + defer mergeInfoLock.Unlock() + mi := mergeInfoMap[t] + if mi == nil { + mi = &mergeInfo{typ: t} + mergeInfoMap[t] = mi + } + return mi +} + +// merge merges src into dst assuming they are both of type *mi.typ. +func (mi *mergeInfo) merge(dst, src pointer) { + if dst.isNil() { + panic("proto: nil destination") + } + if src.isNil() { + return // Nothing to do. + } + + if atomic.LoadInt32(&mi.initialized) == 0 { + mi.computeMergeInfo() + } + + for _, fi := range mi.fields { + sfp := src.offset(fi.field) + + // As an optimization, we can avoid the merge function call cost + // if we know for sure that the source will have no effect + // by checking if it is the zero value. + if unsafeAllowed { + if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string + continue + } + if fi.basicWidth > 0 { + switch { + case fi.basicWidth == 1 && !*sfp.toBool(): + continue + case fi.basicWidth == 4 && *sfp.toUint32() == 0: + continue + case fi.basicWidth == 8 && *sfp.toUint64() == 0: + continue + } + } + } + + dfp := dst.offset(fi.field) + fi.merge(dfp, sfp) + } + + // TODO: Make this faster? + out := dst.asPointerTo(mi.typ).Elem() + in := src.asPointerTo(mi.typ).Elem() + if emIn, err := extendable(in.Addr().Interface()); err == nil { + emOut, _ := extendable(out.Addr().Interface()) + mIn, muIn := emIn.extensionsRead() + if mIn != nil { + mOut := emOut.extensionsWrite() + muIn.Lock() + mergeExtension(mOut, mIn) + muIn.Unlock() + } + } + + if mi.unrecognized.IsValid() { + if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 { + *dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...) + } + } +} + +func (mi *mergeInfo) computeMergeInfo() { + mi.lock.Lock() + defer mi.lock.Unlock() + if mi.initialized != 0 { + return + } + t := mi.typ + n := t.NumField() + + props := GetProperties(t) + for i := 0; i < n; i++ { + f := t.Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + + mfi := mergeFieldInfo{field: toField(&f)} + tf := f.Type + + // As an optimization, we can avoid the merge function call cost + // if we know for sure that the source will have no effect + // by checking if it is the zero value. + if unsafeAllowed { + switch tf.Kind() { + case reflect.Ptr, reflect.Slice, reflect.String: + // As a special case, we assume slices and strings are pointers + // since we know that the first field in the SliceSlice or + // StringHeader is a data pointer. + mfi.isPointer = true + case reflect.Bool: + mfi.basicWidth = 1 + case reflect.Int32, reflect.Uint32, reflect.Float32: + mfi.basicWidth = 4 + case reflect.Int64, reflect.Uint64, reflect.Float64: + mfi.basicWidth = 8 + } + } + + // Unwrap tf to get at its most basic type. + var isPointer, isSlice bool + if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { + isSlice = true + tf = tf.Elem() + } + if tf.Kind() == reflect.Ptr { + isPointer = true + tf = tf.Elem() + } + if isPointer && isSlice && tf.Kind() != reflect.Struct { + panic("both pointer and slice for basic type in " + tf.Name()) + } + + switch tf.Kind() { + case reflect.Int32: + switch { + case isSlice: // E.g., []int32 + mfi.merge = func(dst, src pointer) { + // NOTE: toInt32Slice is not defined (see pointer_reflect.go). + /* + sfsp := src.toInt32Slice() + if *sfsp != nil { + dfsp := dst.toInt32Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []int64{} + } + } + */ + sfs := src.getInt32Slice() + if sfs != nil { + dfs := dst.getInt32Slice() + dfs = append(dfs, sfs...) + if dfs == nil { + dfs = []int32{} + } + dst.setInt32Slice(dfs) + } + } + case isPointer: // E.g., *int32 + mfi.merge = func(dst, src pointer) { + // NOTE: toInt32Ptr is not defined (see pointer_reflect.go). + /* + sfpp := src.toInt32Ptr() + if *sfpp != nil { + dfpp := dst.toInt32Ptr() + if *dfpp == nil { + *dfpp = Int32(**sfpp) + } else { + **dfpp = **sfpp + } + } + */ + sfp := src.getInt32Ptr() + if sfp != nil { + dfp := dst.getInt32Ptr() + if dfp == nil { + dst.setInt32Ptr(*sfp) + } else { + *dfp = *sfp + } + } + } + default: // E.g., int32 + mfi.merge = func(dst, src pointer) { + if v := *src.toInt32(); v != 0 { + *dst.toInt32() = v + } + } + } + case reflect.Int64: + switch { + case isSlice: // E.g., []int64 + mfi.merge = func(dst, src pointer) { + sfsp := src.toInt64Slice() + if *sfsp != nil { + dfsp := dst.toInt64Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []int64{} + } + } + } + case isPointer: // E.g., *int64 + mfi.merge = func(dst, src pointer) { + sfpp := src.toInt64Ptr() + if *sfpp != nil { + dfpp := dst.toInt64Ptr() + if *dfpp == nil { + *dfpp = Int64(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., int64 + mfi.merge = func(dst, src pointer) { + if v := *src.toInt64(); v != 0 { + *dst.toInt64() = v + } + } + } + case reflect.Uint32: + switch { + case isSlice: // E.g., []uint32 + mfi.merge = func(dst, src pointer) { + sfsp := src.toUint32Slice() + if *sfsp != nil { + dfsp := dst.toUint32Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []uint32{} + } + } + } + case isPointer: // E.g., *uint32 + mfi.merge = func(dst, src pointer) { + sfpp := src.toUint32Ptr() + if *sfpp != nil { + dfpp := dst.toUint32Ptr() + if *dfpp == nil { + *dfpp = Uint32(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., uint32 + mfi.merge = func(dst, src pointer) { + if v := *src.toUint32(); v != 0 { + *dst.toUint32() = v + } + } + } + case reflect.Uint64: + switch { + case isSlice: // E.g., []uint64 + mfi.merge = func(dst, src pointer) { + sfsp := src.toUint64Slice() + if *sfsp != nil { + dfsp := dst.toUint64Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []uint64{} + } + } + } + case isPointer: // E.g., *uint64 + mfi.merge = func(dst, src pointer) { + sfpp := src.toUint64Ptr() + if *sfpp != nil { + dfpp := dst.toUint64Ptr() + if *dfpp == nil { + *dfpp = Uint64(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., uint64 + mfi.merge = func(dst, src pointer) { + if v := *src.toUint64(); v != 0 { + *dst.toUint64() = v + } + } + } + case reflect.Float32: + switch { + case isSlice: // E.g., []float32 + mfi.merge = func(dst, src pointer) { + sfsp := src.toFloat32Slice() + if *sfsp != nil { + dfsp := dst.toFloat32Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []float32{} + } + } + } + case isPointer: // E.g., *float32 + mfi.merge = func(dst, src pointer) { + sfpp := src.toFloat32Ptr() + if *sfpp != nil { + dfpp := dst.toFloat32Ptr() + if *dfpp == nil { + *dfpp = Float32(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., float32 + mfi.merge = func(dst, src pointer) { + if v := *src.toFloat32(); v != 0 { + *dst.toFloat32() = v + } + } + } + case reflect.Float64: + switch { + case isSlice: // E.g., []float64 + mfi.merge = func(dst, src pointer) { + sfsp := src.toFloat64Slice() + if *sfsp != nil { + dfsp := dst.toFloat64Slice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []float64{} + } + } + } + case isPointer: // E.g., *float64 + mfi.merge = func(dst, src pointer) { + sfpp := src.toFloat64Ptr() + if *sfpp != nil { + dfpp := dst.toFloat64Ptr() + if *dfpp == nil { + *dfpp = Float64(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., float64 + mfi.merge = func(dst, src pointer) { + if v := *src.toFloat64(); v != 0 { + *dst.toFloat64() = v + } + } + } + case reflect.Bool: + switch { + case isSlice: // E.g., []bool + mfi.merge = func(dst, src pointer) { + sfsp := src.toBoolSlice() + if *sfsp != nil { + dfsp := dst.toBoolSlice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []bool{} + } + } + } + case isPointer: // E.g., *bool + mfi.merge = func(dst, src pointer) { + sfpp := src.toBoolPtr() + if *sfpp != nil { + dfpp := dst.toBoolPtr() + if *dfpp == nil { + *dfpp = Bool(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., bool + mfi.merge = func(dst, src pointer) { + if v := *src.toBool(); v { + *dst.toBool() = v + } + } + } + case reflect.String: + switch { + case isSlice: // E.g., []string + mfi.merge = func(dst, src pointer) { + sfsp := src.toStringSlice() + if *sfsp != nil { + dfsp := dst.toStringSlice() + *dfsp = append(*dfsp, *sfsp...) + if *dfsp == nil { + *dfsp = []string{} + } + } + } + case isPointer: // E.g., *string + mfi.merge = func(dst, src pointer) { + sfpp := src.toStringPtr() + if *sfpp != nil { + dfpp := dst.toStringPtr() + if *dfpp == nil { + *dfpp = String(**sfpp) + } else { + **dfpp = **sfpp + } + } + } + default: // E.g., string + mfi.merge = func(dst, src pointer) { + if v := *src.toString(); v != "" { + *dst.toString() = v + } + } + } + case reflect.Slice: + isProto3 := props.Prop[i].proto3 + switch { + case isPointer: + panic("bad pointer in byte slice case in " + tf.Name()) + case tf.Elem().Kind() != reflect.Uint8: + panic("bad element kind in byte slice case in " + tf.Name()) + case isSlice: // E.g., [][]byte + mfi.merge = func(dst, src pointer) { + sbsp := src.toBytesSlice() + if *sbsp != nil { + dbsp := dst.toBytesSlice() + for _, sb := range *sbsp { + if sb == nil { + *dbsp = append(*dbsp, nil) + } else { + *dbsp = append(*dbsp, append([]byte{}, sb...)) + } + } + if *dbsp == nil { + *dbsp = [][]byte{} + } + } + } + default: // E.g., []byte + mfi.merge = func(dst, src pointer) { + sbp := src.toBytes() + if *sbp != nil { + dbp := dst.toBytes() + if !isProto3 || len(*sbp) > 0 { + *dbp = append([]byte{}, *sbp...) + } + } + } + } + case reflect.Struct: + switch { + case !isPointer: + panic(fmt.Sprintf("message field %s without pointer", tf)) + case isSlice: // E.g., []*pb.T + mi := getMergeInfo(tf) + mfi.merge = func(dst, src pointer) { + sps := src.getPointerSlice() + if sps != nil { + dps := dst.getPointerSlice() + for _, sp := range sps { + var dp pointer + if !sp.isNil() { + dp = valToPointer(reflect.New(tf)) + mi.merge(dp, sp) + } + dps = append(dps, dp) + } + if dps == nil { + dps = []pointer{} + } + dst.setPointerSlice(dps) + } + } + default: // E.g., *pb.T + mi := getMergeInfo(tf) + mfi.merge = func(dst, src pointer) { + sp := src.getPointer() + if !sp.isNil() { + dp := dst.getPointer() + if dp.isNil() { + dp = valToPointer(reflect.New(tf)) + dst.setPointer(dp) + } + mi.merge(dp, sp) + } + } + } + case reflect.Map: + switch { + case isPointer || isSlice: + panic("bad pointer or slice in map case in " + tf.Name()) + default: // E.g., map[K]V + mfi.merge = func(dst, src pointer) { + sm := src.asPointerTo(tf).Elem() + if sm.Len() == 0 { + return + } + dm := dst.asPointerTo(tf).Elem() + if dm.IsNil() { + dm.Set(reflect.MakeMap(tf)) + } + + switch tf.Elem().Kind() { + case reflect.Ptr: // Proto struct (e.g., *T) + for _, key := range sm.MapKeys() { + val := sm.MapIndex(key) + val = reflect.ValueOf(Clone(val.Interface().(Message))) + dm.SetMapIndex(key, val) + } + case reflect.Slice: // E.g. Bytes type (e.g., []byte) + for _, key := range sm.MapKeys() { + val := sm.MapIndex(key) + val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) + dm.SetMapIndex(key, val) + } + default: // Basic type (e.g., string) + for _, key := range sm.MapKeys() { + val := sm.MapIndex(key) + dm.SetMapIndex(key, val) + } + } + } + } + case reflect.Interface: + // Must be oneof field. + switch { + case isPointer || isSlice: + panic("bad pointer or slice in interface case in " + tf.Name()) + default: // E.g., interface{} + // TODO: Make this faster? + mfi.merge = func(dst, src pointer) { + su := src.asPointerTo(tf).Elem() + if !su.IsNil() { + du := dst.asPointerTo(tf).Elem() + typ := su.Elem().Type() + if du.IsNil() || du.Elem().Type() != typ { + du.Set(reflect.New(typ.Elem())) // Initialize interface if empty + } + sv := su.Elem().Elem().Field(0) + if sv.Kind() == reflect.Ptr && sv.IsNil() { + return + } + dv := du.Elem().Elem().Field(0) + if dv.Kind() == reflect.Ptr && dv.IsNil() { + dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty + } + switch sv.Type().Kind() { + case reflect.Ptr: // Proto struct (e.g., *T) + Merge(dv.Interface().(Message), sv.Interface().(Message)) + case reflect.Slice: // E.g. Bytes type (e.g., []byte) + dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...))) + default: // Basic type (e.g., string) + dv.Set(sv) + } + } + } + } + default: + panic(fmt.Sprintf("merger not found for type:%s", tf)) + } + mi.fields = append(mi.fields, mfi) + } + + mi.unrecognized = invalidField + if f, ok := t.FieldByName("XXX_unrecognized"); ok { + if f.Type != reflect.TypeOf([]byte{}) { + panic("expected XXX_unrecognized to be of type []byte") + } + mi.unrecognized = toField(&f) + } + + atomic.StoreInt32(&mi.initialized, 1) +} diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go new file mode 100644 index 000000000..ebf1caa56 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go @@ -0,0 +1,2051 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +import ( + "errors" + "fmt" + "io" + "math" + "reflect" + "strconv" + "strings" + "sync" + "sync/atomic" + "unicode/utf8" +) + +// Unmarshal is the entry point from the generated .pb.go files. +// This function is not intended to be used by non-generated code. +// This function is not subject to any compatibility guarantee. +// msg contains a pointer to a protocol buffer struct. +// b is the data to be unmarshaled into the protocol buffer. +// a is a pointer to a place to store cached unmarshal information. +func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error { + // Load the unmarshal information for this message type. + // The atomic load ensures memory consistency. + u := atomicLoadUnmarshalInfo(&a.unmarshal) + if u == nil { + // Slow path: find unmarshal info for msg, update a with it. + u = getUnmarshalInfo(reflect.TypeOf(msg).Elem()) + atomicStoreUnmarshalInfo(&a.unmarshal, u) + } + // Then do the unmarshaling. + err := u.unmarshal(toPointer(&msg), b) + return err +} + +type unmarshalInfo struct { + typ reflect.Type // type of the protobuf struct + + // 0 = only typ field is initialized + // 1 = completely initialized + initialized int32 + lock sync.Mutex // prevents double initialization + dense []unmarshalFieldInfo // fields indexed by tag # + sparse map[uint64]unmarshalFieldInfo // fields indexed by tag # + reqFields []string // names of required fields + reqMask uint64 // 1< 0 { + // Read tag and wire type. + // Special case 1 and 2 byte varints. + var x uint64 + if b[0] < 128 { + x = uint64(b[0]) + b = b[1:] + } else if len(b) >= 2 && b[1] < 128 { + x = uint64(b[0]&0x7f) + uint64(b[1])<<7 + b = b[2:] + } else { + var n int + x, n = decodeVarint(b) + if n == 0 { + return io.ErrUnexpectedEOF + } + b = b[n:] + } + tag := x >> 3 + wire := int(x) & 7 + + // Dispatch on the tag to one of the unmarshal* functions below. + var f unmarshalFieldInfo + if tag < uint64(len(u.dense)) { + f = u.dense[tag] + } else { + f = u.sparse[tag] + } + if fn := f.unmarshal; fn != nil { + var err error + b, err = fn(b, m.offset(f.field), wire) + if err == nil { + reqMask |= f.reqMask + continue + } + if r, ok := err.(*RequiredNotSetError); ok { + // Remember this error, but keep parsing. We need to produce + // a full parse even if a required field is missing. + if errLater == nil { + errLater = r + } + reqMask |= f.reqMask + continue + } + if err != errInternalBadWireType { + if err == errInvalidUTF8 { + if errLater == nil { + fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name + errLater = &invalidUTF8Error{fullName} + } + continue + } + return err + } + // Fragments with bad wire type are treated as unknown fields. + } + + // Unknown tag. + if !u.unrecognized.IsValid() { + // Don't keep unrecognized data; just skip it. + var err error + b, err = skipField(b, wire) + if err != nil { + return err + } + continue + } + // Keep unrecognized data around. + // maybe in extensions, maybe in the unrecognized field. + z := m.offset(u.unrecognized).toBytes() + var emap map[int32]Extension + var e Extension + for _, r := range u.extensionRanges { + if uint64(r.Start) <= tag && tag <= uint64(r.End) { + if u.extensions.IsValid() { + mp := m.offset(u.extensions).toExtensions() + emap = mp.extensionsWrite() + e = emap[int32(tag)] + z = &e.enc + break + } + if u.oldExtensions.IsValid() { + p := m.offset(u.oldExtensions).toOldExtensions() + emap = *p + if emap == nil { + emap = map[int32]Extension{} + *p = emap + } + e = emap[int32(tag)] + z = &e.enc + break + } + panic("no extensions field available") + } + } + + // Use wire type to skip data. + var err error + b0 := b + b, err = skipField(b, wire) + if err != nil { + return err + } + *z = encodeVarint(*z, tag<<3|uint64(wire)) + *z = append(*z, b0[:len(b0)-len(b)]...) + + if emap != nil { + emap[int32(tag)] = e + } + } + if reqMask != u.reqMask && errLater == nil { + // A required field of this message is missing. + for _, n := range u.reqFields { + if reqMask&1 == 0 { + errLater = &RequiredNotSetError{n} + } + reqMask >>= 1 + } + } + return errLater +} + +// computeUnmarshalInfo fills in u with information for use +// in unmarshaling protocol buffers of type u.typ. +func (u *unmarshalInfo) computeUnmarshalInfo() { + u.lock.Lock() + defer u.lock.Unlock() + if u.initialized != 0 { + return + } + t := u.typ + n := t.NumField() + + // Set up the "not found" value for the unrecognized byte buffer. + // This is the default for proto3. + u.unrecognized = invalidField + u.extensions = invalidField + u.oldExtensions = invalidField + + // List of the generated type and offset for each oneof field. + type oneofField struct { + ityp reflect.Type // interface type of oneof field + field field // offset in containing message + } + var oneofFields []oneofField + + for i := 0; i < n; i++ { + f := t.Field(i) + if f.Name == "XXX_unrecognized" { + // The byte slice used to hold unrecognized input is special. + if f.Type != reflect.TypeOf(([]byte)(nil)) { + panic("bad type for XXX_unrecognized field: " + f.Type.Name()) + } + u.unrecognized = toField(&f) + continue + } + if f.Name == "XXX_InternalExtensions" { + // Ditto here. + if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) { + panic("bad type for XXX_InternalExtensions field: " + f.Type.Name()) + } + u.extensions = toField(&f) + if f.Tag.Get("protobuf_messageset") == "1" { + u.isMessageSet = true + } + continue + } + if f.Name == "XXX_extensions" { + // An older form of the extensions field. + if f.Type != reflect.TypeOf((map[int32]Extension)(nil)) { + panic("bad type for XXX_extensions field: " + f.Type.Name()) + } + u.oldExtensions = toField(&f) + continue + } + if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" { + continue + } + + oneof := f.Tag.Get("protobuf_oneof") + if oneof != "" { + oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)}) + // The rest of oneof processing happens below. + continue + } + + tags := f.Tag.Get("protobuf") + tagArray := strings.Split(tags, ",") + if len(tagArray) < 2 { + panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags) + } + tag, err := strconv.Atoi(tagArray[1]) + if err != nil { + panic("protobuf tag field not an integer: " + tagArray[1]) + } + + name := "" + for _, tag := range tagArray[3:] { + if strings.HasPrefix(tag, "name=") { + name = tag[5:] + } + } + + // Extract unmarshaling function from the field (its type and tags). + unmarshal := fieldUnmarshaler(&f) + + // Required field? + var reqMask uint64 + if tagArray[2] == "req" { + bit := len(u.reqFields) + u.reqFields = append(u.reqFields, name) + reqMask = uint64(1) << uint(bit) + // TODO: if we have more than 64 required fields, we end up + // not verifying that all required fields are present. + // Fix this, perhaps using a count of required fields? + } + + // Store the info in the correct slot in the message. + u.setTag(tag, toField(&f), unmarshal, reqMask, name) + } + + // Find any types associated with oneof fields. + // TODO: XXX_OneofFuncs returns more info than we need. Get rid of some of it? + fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs") + if fn.IsValid() { + res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{} + for i := res.Len() - 1; i >= 0; i-- { + v := res.Index(i) // interface{} + tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X + typ := tptr.Elem() // Msg_X + + f := typ.Field(0) // oneof implementers have one field + baseUnmarshal := fieldUnmarshaler(&f) + tags := strings.Split(f.Tag.Get("protobuf"), ",") + fieldNum, err := strconv.Atoi(tags[1]) + if err != nil { + panic("protobuf tag field not an integer: " + tags[1]) + } + var name string + for _, tag := range tags { + if strings.HasPrefix(tag, "name=") { + name = strings.TrimPrefix(tag, "name=") + break + } + } + + // Find the oneof field that this struct implements. + // Might take O(n^2) to process all of the oneofs, but who cares. + for _, of := range oneofFields { + if tptr.Implements(of.ityp) { + // We have found the corresponding interface for this struct. + // That lets us know where this struct should be stored + // when we encounter it during unmarshaling. + unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) + u.setTag(fieldNum, of.field, unmarshal, 0, name) + } + } + } + } + + // Get extension ranges, if any. + fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") + if fn.IsValid() { + if !u.extensions.IsValid() && !u.oldExtensions.IsValid() { + panic("a message with extensions, but no extensions field in " + t.Name()) + } + u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange) + } + + // Explicitly disallow tag 0. This will ensure we flag an error + // when decoding a buffer of all zeros. Without this code, we + // would decode and skip an all-zero buffer of even length. + // [0 0] is [tag=0/wiretype=varint varint-encoded-0]. + u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { + return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) + }, 0, "") + + // Set mask for required field check. + u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? + for len(u.dense) <= tag { + u.dense = append(u.dense, unmarshalFieldInfo{}) + } + u.dense[tag] = i + return + } + if u.sparse == nil { + u.sparse = map[uint64]unmarshalFieldInfo{} + } + u.sparse[uint64(tag)] = i +} + +// fieldUnmarshaler returns an unmarshaler for the given field. +func fieldUnmarshaler(f *reflect.StructField) unmarshaler { + if f.Type.Kind() == reflect.Map { + return makeUnmarshalMap(f) + } + return typeUnmarshaler(f.Type, f.Tag.Get("protobuf")) +} + +// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair. +func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { + tagArray := strings.Split(tags, ",") + encoding := tagArray[0] + name := "unknown" + proto3 := false + validateUTF8 := true + for _, tag := range tagArray[3:] { + if strings.HasPrefix(tag, "name=") { + name = tag[5:] + } + if tag == "proto3" { + proto3 = true + } + } + validateUTF8 = validateUTF8 && proto3 + + // Figure out packaging (pointer, slice, or both) + slice := false + pointer := false + if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { + slice = true + t = t.Elem() + } + if t.Kind() == reflect.Ptr { + pointer = true + t = t.Elem() + } + + // We'll never have both pointer and slice for basic types. + if pointer && slice && t.Kind() != reflect.Struct { + panic("both pointer and slice for basic type in " + t.Name()) + } + + switch t.Kind() { + case reflect.Bool: + if pointer { + return unmarshalBoolPtr + } + if slice { + return unmarshalBoolSlice + } + return unmarshalBoolValue + case reflect.Int32: + switch encoding { + case "fixed32": + if pointer { + return unmarshalFixedS32Ptr + } + if slice { + return unmarshalFixedS32Slice + } + return unmarshalFixedS32Value + case "varint": + // this could be int32 or enum + if pointer { + return unmarshalInt32Ptr + } + if slice { + return unmarshalInt32Slice + } + return unmarshalInt32Value + case "zigzag32": + if pointer { + return unmarshalSint32Ptr + } + if slice { + return unmarshalSint32Slice + } + return unmarshalSint32Value + } + case reflect.Int64: + switch encoding { + case "fixed64": + if pointer { + return unmarshalFixedS64Ptr + } + if slice { + return unmarshalFixedS64Slice + } + return unmarshalFixedS64Value + case "varint": + if pointer { + return unmarshalInt64Ptr + } + if slice { + return unmarshalInt64Slice + } + return unmarshalInt64Value + case "zigzag64": + if pointer { + return unmarshalSint64Ptr + } + if slice { + return unmarshalSint64Slice + } + return unmarshalSint64Value + } + case reflect.Uint32: + switch encoding { + case "fixed32": + if pointer { + return unmarshalFixed32Ptr + } + if slice { + return unmarshalFixed32Slice + } + return unmarshalFixed32Value + case "varint": + if pointer { + return unmarshalUint32Ptr + } + if slice { + return unmarshalUint32Slice + } + return unmarshalUint32Value + } + case reflect.Uint64: + switch encoding { + case "fixed64": + if pointer { + return unmarshalFixed64Ptr + } + if slice { + return unmarshalFixed64Slice + } + return unmarshalFixed64Value + case "varint": + if pointer { + return unmarshalUint64Ptr + } + if slice { + return unmarshalUint64Slice + } + return unmarshalUint64Value + } + case reflect.Float32: + if pointer { + return unmarshalFloat32Ptr + } + if slice { + return unmarshalFloat32Slice + } + return unmarshalFloat32Value + case reflect.Float64: + if pointer { + return unmarshalFloat64Ptr + } + if slice { + return unmarshalFloat64Slice + } + return unmarshalFloat64Value + case reflect.Map: + panic("map type in typeUnmarshaler in " + t.Name()) + case reflect.Slice: + if pointer { + panic("bad pointer in slice case in " + t.Name()) + } + if slice { + return unmarshalBytesSlice + } + return unmarshalBytesValue + case reflect.String: + if validateUTF8 { + if pointer { + return unmarshalUTF8StringPtr + } + if slice { + return unmarshalUTF8StringSlice + } + return unmarshalUTF8StringValue + } + if pointer { + return unmarshalStringPtr + } + if slice { + return unmarshalStringSlice + } + return unmarshalStringValue + case reflect.Struct: + // message or group field + if !pointer { + panic(fmt.Sprintf("message/group field %s:%s without pointer", t, encoding)) + } + switch encoding { + case "bytes": + if slice { + return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name) + } + return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name) + case "group": + if slice { + return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name) + } + return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name) + } + } + panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding)) +} + +// Below are all the unmarshalers for individual fields of various types. + +func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + *f.toInt64() = v + return b, nil +} + +func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + *f.toInt64Ptr() = &v + return b, nil +} + +func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + s := f.toInt64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x) + s := f.toInt64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + *f.toInt64() = v + return b, nil +} + +func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + *f.toInt64Ptr() = &v + return b, nil +} + +func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + s := f.toInt64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int64(x>>1) ^ int64(x)<<63>>63 + s := f.toInt64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + *f.toUint64() = v + return b, nil +} + +func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + *f.toUint64Ptr() = &v + return b, nil +} + +func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + s := f.toUint64Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint64(x) + s := f.toUint64Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + *f.toInt32() = v + return b, nil +} + +func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.setInt32Ptr(v) + return b, nil +} + +func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.appendInt32Slice(v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x) + f.appendInt32Slice(v) + return b, nil +} + +func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + *f.toInt32() = v + return b, nil +} + +func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.setInt32Ptr(v) + return b, nil +} + +func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.appendInt32Slice(v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := int32(x>>1) ^ int32(x)<<31>>31 + f.appendInt32Slice(v) + return b, nil +} + +func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + *f.toUint32() = v + return b, nil +} + +func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + *f.toUint32Ptr() = &v + return b, nil +} + +func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + s := f.toUint32Slice() + *s = append(*s, v) + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + v := uint32(x) + s := f.toUint32Slice() + *s = append(*s, v) + return b, nil +} + +func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + *f.toUint64() = v + return b[8:], nil +} + +func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + *f.toUint64Ptr() = &v + return b[8:], nil +} + +func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + s := f.toUint64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + s := f.toUint64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + *f.toInt64() = v + return b[8:], nil +} + +func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + *f.toInt64Ptr() = &v + return b[8:], nil +} + +func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + s := f.toInt64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 + s := f.toInt64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + *f.toUint32() = v + return b[4:], nil +} + +func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + *f.toUint32Ptr() = &v + return b[4:], nil +} + +func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + s := f.toUint32Slice() + *s = append(*s, v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 + s := f.toUint32Slice() + *s = append(*s, v) + return b[4:], nil +} + +func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + *f.toInt32() = v + return b[4:], nil +} + +func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.setInt32Ptr(v) + return b[4:], nil +} + +func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.appendInt32Slice(v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 + f.appendInt32Slice(v) + return b[4:], nil +} + +func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + // Note: any length varint is allowed, even though any sane + // encoder will use one byte. + // See https://github.com/golang/protobuf/issues/76 + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + // TODO: check if x>1? Tests seem to indicate no. + v := x != 0 + *f.toBool() = v + return b[n:], nil +} + +func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + *f.toBoolPtr() = &v + return b[n:], nil +} + +func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + x, n = decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + s := f.toBoolSlice() + *s = append(*s, v) + b = b[n:] + } + return res, nil + } + if w != WireVarint { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + v := x != 0 + s := f.toBoolSlice() + *s = append(*s, v) + return b[n:], nil +} + +func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + *f.toFloat64() = v + return b[8:], nil +} + +func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + *f.toFloat64Ptr() = &v + return b[8:], nil +} + +func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + s := f.toFloat64Slice() + *s = append(*s, v) + b = b[8:] + } + return res, nil + } + if w != WireFixed64 { + return b, errInternalBadWireType + } + if len(b) < 8 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) + s := f.toFloat64Slice() + *s = append(*s, v) + return b[8:], nil +} + +func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + *f.toFloat32() = v + return b[4:], nil +} + +func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + *f.toFloat32Ptr() = &v + return b[4:], nil +} + +func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) { + if w == WireBytes { // packed + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + res := b[x:] + b = b[:x] + for len(b) > 0 { + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + s := f.toFloat32Slice() + *s = append(*s, v) + b = b[4:] + } + return res, nil + } + if w != WireFixed32 { + return b, errInternalBadWireType + } + if len(b) < 4 { + return nil, io.ErrUnexpectedEOF + } + v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) + s := f.toFloat32Slice() + *s = append(*s, v) + return b[4:], nil +} + +func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toString() = v + return b[x:], nil +} + +func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toStringPtr() = &v + return b[x:], nil +} + +func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + s := f.toStringSlice() + *s = append(*s, v) + return b[x:], nil +} + +func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toString() = v + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + *f.toStringPtr() = &v + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := string(b[:x]) + s := f.toStringSlice() + *s = append(*s, v) + if !utf8.ValidString(v) { + return b[x:], errInvalidUTF8 + } + return b[x:], nil +} + +var emptyBuf [0]byte + +func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + // The use of append here is a trick which avoids the zeroing + // that would be required if we used a make/copy pair. + // We append to emptyBuf instead of nil because we want + // a non-nil result even when the length is 0. + v := append(emptyBuf[:], b[:x]...) + *f.toBytes() = v + return b[x:], nil +} + +func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := append(emptyBuf[:], b[:x]...) + s := f.toBytesSlice() + *s = append(*s, v) + return b[x:], nil +} + +func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + // First read the message field to see if something is there. + // The semantics of multiple submessages are weird. Instead of + // the last one winning (as it is for all other fields), multiple + // submessages are merged. + v := f.getPointer() + if v.isNil() { + v = valToPointer(reflect.New(sub.typ)) + f.setPointer(v) + } + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + return b[x:], err + } +} + +func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireBytes { + return b, errInternalBadWireType + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + v := valToPointer(reflect.New(sub.typ)) + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + f.appendPointer(v) + return b[x:], err + } +} + +func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireStartGroup { + return b, errInternalBadWireType + } + x, y := findEndGroup(b) + if x < 0 { + return nil, io.ErrUnexpectedEOF + } + v := f.getPointer() + if v.isNil() { + v = valToPointer(reflect.New(sub.typ)) + f.setPointer(v) + } + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + return b[y:], err + } +} + +func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler { + return func(b []byte, f pointer, w int) ([]byte, error) { + if w != WireStartGroup { + return b, errInternalBadWireType + } + x, y := findEndGroup(b) + if x < 0 { + return nil, io.ErrUnexpectedEOF + } + v := valToPointer(reflect.New(sub.typ)) + err := sub.unmarshal(v, b[:x]) + if err != nil { + if r, ok := err.(*RequiredNotSetError); ok { + r.field = name + "." + r.field + } else { + return nil, err + } + } + f.appendPointer(v) + return b[y:], err + } +} + +func makeUnmarshalMap(f *reflect.StructField) unmarshaler { + t := f.Type + kt := t.Key() + vt := t.Elem() + unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key")) + unmarshalVal := typeUnmarshaler(vt, f.Tag.Get("protobuf_val")) + return func(b []byte, f pointer, w int) ([]byte, error) { + // The map entry is a submessage. Figure out how big it is. + if w != WireBytes { + return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes) + } + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + b = b[n:] + if x > uint64(len(b)) { + return nil, io.ErrUnexpectedEOF + } + r := b[x:] // unused data to return + b = b[:x] // data for map entry + + // Note: we could use #keys * #values ~= 200 functions + // to do map decoding without reflection. Probably not worth it. + // Maps will be somewhat slow. Oh well. + + // Read key and value from data. + var nerr nonFatal + k := reflect.New(kt) + v := reflect.New(vt) + for len(b) > 0 { + x, n := decodeVarint(b) + if n == 0 { + return nil, io.ErrUnexpectedEOF + } + wire := int(x) & 7 + b = b[n:] + + var err error + switch x >> 3 { + case 1: + b, err = unmarshalKey(b, valToPointer(k), wire) + case 2: + b, err = unmarshalVal(b, valToPointer(v), wire) + default: + err = errInternalBadWireType // skip unknown tag + } + + if nerr.Merge(err) { + continue + } + if err != errInternalBadWireType { + return nil, err + } + + // Skip past unknown fields. + b, err = skipField(b, wire) + if err != nil { + return nil, err + } + } + + // Get map, allocate if needed. + m := f.asPointerTo(t).Elem() // an addressable map[K]T + if m.IsNil() { + m.Set(reflect.MakeMap(t)) + } + + // Insert into map. + m.SetMapIndex(k.Elem(), v.Elem()) + + return r, nerr.E + } +} + +// makeUnmarshalOneof makes an unmarshaler for oneof fields. +// for: +// message Msg { +// oneof F { +// int64 X = 1; +// float64 Y = 2; +// } +// } +// typ is the type of the concrete entry for a oneof case (e.g. Msg_X). +// ityp is the interface type of the oneof field (e.g. isMsg_F). +// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64). +// Note that this function will be called once for each case in the oneof. +func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler { + sf := typ.Field(0) + field0 := toField(&sf) + return func(b []byte, f pointer, w int) ([]byte, error) { + // Allocate holder for value. + v := reflect.New(typ) + + // Unmarshal data into holder. + // We unmarshal into the first field of the holder object. + var err error + var nerr nonFatal + b, err = unmarshal(b, valToPointer(v).offset(field0), w) + if !nerr.Merge(err) { + return nil, err + } + + // Write pointer to holder into target field. + f.asPointerTo(ityp).Elem().Set(v) + + return b, nerr.E + } +} + +// Error used by decode internally. +var errInternalBadWireType = errors.New("proto: internal error: bad wiretype") + +// skipField skips past a field of type wire and returns the remaining bytes. +func skipField(b []byte, wire int) ([]byte, error) { + switch wire { + case WireVarint: + _, k := decodeVarint(b) + if k == 0 { + return b, io.ErrUnexpectedEOF + } + b = b[k:] + case WireFixed32: + if len(b) < 4 { + return b, io.ErrUnexpectedEOF + } + b = b[4:] + case WireFixed64: + if len(b) < 8 { + return b, io.ErrUnexpectedEOF + } + b = b[8:] + case WireBytes: + m, k := decodeVarint(b) + if k == 0 || uint64(len(b)-k) < m { + return b, io.ErrUnexpectedEOF + } + b = b[uint64(k)+m:] + case WireStartGroup: + _, i := findEndGroup(b) + if i == -1 { + return b, io.ErrUnexpectedEOF + } + b = b[i:] + default: + return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire) + } + return b, nil +} + +// findEndGroup finds the index of the next EndGroup tag. +// Groups may be nested, so the "next" EndGroup tag is the first +// unpaired EndGroup. +// findEndGroup returns the indexes of the start and end of the EndGroup tag. +// Returns (-1,-1) if it can't find one. +func findEndGroup(b []byte) (int, int) { + depth := 1 + i := 0 + for { + x, n := decodeVarint(b[i:]) + if n == 0 { + return -1, -1 + } + j := i + i += n + switch x & 7 { + case WireVarint: + _, k := decodeVarint(b[i:]) + if k == 0 { + return -1, -1 + } + i += k + case WireFixed32: + if len(b)-4 < i { + return -1, -1 + } + i += 4 + case WireFixed64: + if len(b)-8 < i { + return -1, -1 + } + i += 8 + case WireBytes: + m, k := decodeVarint(b[i:]) + if k == 0 { + return -1, -1 + } + i += k + if uint64(len(b)-i) < m { + return -1, -1 + } + i += int(m) + case WireStartGroup: + depth++ + case WireEndGroup: + depth-- + if depth == 0 { + return j, i + } + default: + return -1, -1 + } + } +} + +// encodeVarint appends a varint-encoded integer to b and returns the result. +func encodeVarint(b []byte, x uint64) []byte { + for x >= 1<<7 { + b = append(b, byte(x&0x7f|0x80)) + x >>= 7 + } + return append(b, byte(x)) +} + +// decodeVarint reads a varint-encoded integer from b. +// Returns the decoded integer and the number of bytes read. +// If there is an error, it returns 0,0. +func decodeVarint(b []byte) (uint64, int) { + var x, y uint64 + if len(b) <= 0 { + goto bad + } + x = uint64(b[0]) + if x < 0x80 { + return x, 1 + } + x -= 0x80 + + if len(b) <= 1 { + goto bad + } + y = uint64(b[1]) + x += y << 7 + if y < 0x80 { + return x, 2 + } + x -= 0x80 << 7 + + if len(b) <= 2 { + goto bad + } + y = uint64(b[2]) + x += y << 14 + if y < 0x80 { + return x, 3 + } + x -= 0x80 << 14 + + if len(b) <= 3 { + goto bad + } + y = uint64(b[3]) + x += y << 21 + if y < 0x80 { + return x, 4 + } + x -= 0x80 << 21 + + if len(b) <= 4 { + goto bad + } + y = uint64(b[4]) + x += y << 28 + if y < 0x80 { + return x, 5 + } + x -= 0x80 << 28 + + if len(b) <= 5 { + goto bad + } + y = uint64(b[5]) + x += y << 35 + if y < 0x80 { + return x, 6 + } + x -= 0x80 << 35 + + if len(b) <= 6 { + goto bad + } + y = uint64(b[6]) + x += y << 42 + if y < 0x80 { + return x, 7 + } + x -= 0x80 << 42 + + if len(b) <= 7 { + goto bad + } + y = uint64(b[7]) + x += y << 49 + if y < 0x80 { + return x, 8 + } + x -= 0x80 << 49 + + if len(b) <= 8 { + goto bad + } + y = uint64(b[8]) + x += y << 56 + if y < 0x80 { + return x, 9 + } + x -= 0x80 << 56 + + if len(b) <= 9 { + goto bad + } + y = uint64(b[9]) + x += y << 63 + if y < 2 { + return x, 10 + } + +bad: + return 0, 0 +} diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go new file mode 100644 index 000000000..1aaee725b --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/text.go @@ -0,0 +1,843 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +// Functions for writing the text protocol buffer format. + +import ( + "bufio" + "bytes" + "encoding" + "errors" + "fmt" + "io" + "log" + "math" + "reflect" + "sort" + "strings" +) + +var ( + newline = []byte("\n") + spaces = []byte(" ") + endBraceNewline = []byte("}\n") + backslashN = []byte{'\\', 'n'} + backslashR = []byte{'\\', 'r'} + backslashT = []byte{'\\', 't'} + backslashDQ = []byte{'\\', '"'} + backslashBS = []byte{'\\', '\\'} + posInf = []byte("inf") + negInf = []byte("-inf") + nan = []byte("nan") +) + +type writer interface { + io.Writer + WriteByte(byte) error +} + +// textWriter is an io.Writer that tracks its indentation level. +type textWriter struct { + ind int + complete bool // if the current position is a complete line + compact bool // whether to write out as a one-liner + w writer +} + +func (w *textWriter) WriteString(s string) (n int, err error) { + if !strings.Contains(s, "\n") { + if !w.compact && w.complete { + w.writeIndent() + } + w.complete = false + return io.WriteString(w.w, s) + } + // WriteString is typically called without newlines, so this + // codepath and its copy are rare. We copy to avoid + // duplicating all of Write's logic here. + return w.Write([]byte(s)) +} + +func (w *textWriter) Write(p []byte) (n int, err error) { + newlines := bytes.Count(p, newline) + if newlines == 0 { + if !w.compact && w.complete { + w.writeIndent() + } + n, err = w.w.Write(p) + w.complete = false + return n, err + } + + frags := bytes.SplitN(p, newline, newlines+1) + if w.compact { + for i, frag := range frags { + if i > 0 { + if err := w.w.WriteByte(' '); err != nil { + return n, err + } + n++ + } + nn, err := w.w.Write(frag) + n += nn + if err != nil { + return n, err + } + } + return n, nil + } + + for i, frag := range frags { + if w.complete { + w.writeIndent() + } + nn, err := w.w.Write(frag) + n += nn + if err != nil { + return n, err + } + if i+1 < len(frags) { + if err := w.w.WriteByte('\n'); err != nil { + return n, err + } + n++ + } + } + w.complete = len(frags[len(frags)-1]) == 0 + return n, nil +} + +func (w *textWriter) WriteByte(c byte) error { + if w.compact && c == '\n' { + c = ' ' + } + if !w.compact && w.complete { + w.writeIndent() + } + err := w.w.WriteByte(c) + w.complete = c == '\n' + return err +} + +func (w *textWriter) indent() { w.ind++ } + +func (w *textWriter) unindent() { + if w.ind == 0 { + log.Print("proto: textWriter unindented too far") + return + } + w.ind-- +} + +func writeName(w *textWriter, props *Properties) error { + if _, err := w.WriteString(props.OrigName); err != nil { + return err + } + if props.Wire != "group" { + return w.WriteByte(':') + } + return nil +} + +func requiresQuotes(u string) bool { + // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. + for _, ch := range u { + switch { + case ch == '.' || ch == '/' || ch == '_': + continue + case '0' <= ch && ch <= '9': + continue + case 'A' <= ch && ch <= 'Z': + continue + case 'a' <= ch && ch <= 'z': + continue + default: + return true + } + } + return false +} + +// isAny reports whether sv is a google.protobuf.Any message +func isAny(sv reflect.Value) bool { + type wkt interface { + XXX_WellKnownType() string + } + t, ok := sv.Addr().Interface().(wkt) + return ok && t.XXX_WellKnownType() == "Any" +} + +// writeProto3Any writes an expanded google.protobuf.Any message. +// +// It returns (false, nil) if sv value can't be unmarshaled (e.g. because +// required messages are not linked in). +// +// It returns (true, error) when sv was written in expanded format or an error +// was encountered. +func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { + turl := sv.FieldByName("TypeUrl") + val := sv.FieldByName("Value") + if !turl.IsValid() || !val.IsValid() { + return true, errors.New("proto: invalid google.protobuf.Any message") + } + + b, ok := val.Interface().([]byte) + if !ok { + return true, errors.New("proto: invalid google.protobuf.Any message") + } + + parts := strings.Split(turl.String(), "/") + mt := MessageType(parts[len(parts)-1]) + if mt == nil { + return false, nil + } + m := reflect.New(mt.Elem()) + if err := Unmarshal(b, m.Interface().(Message)); err != nil { + return false, nil + } + w.Write([]byte("[")) + u := turl.String() + if requiresQuotes(u) { + writeString(w, u) + } else { + w.Write([]byte(u)) + } + if w.compact { + w.Write([]byte("]:<")) + } else { + w.Write([]byte("]: <\n")) + w.ind++ + } + if err := tm.writeStruct(w, m.Elem()); err != nil { + return true, err + } + if w.compact { + w.Write([]byte("> ")) + } else { + w.ind-- + w.Write([]byte(">\n")) + } + return true, nil +} + +func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { + if tm.ExpandAny && isAny(sv) { + if canExpand, err := tm.writeProto3Any(w, sv); canExpand { + return err + } + } + st := sv.Type() + sprops := GetProperties(st) + for i := 0; i < sv.NumField(); i++ { + fv := sv.Field(i) + props := sprops.Prop[i] + name := st.Field(i).Name + + if name == "XXX_NoUnkeyedLiteral" { + continue + } + + if strings.HasPrefix(name, "XXX_") { + // There are two XXX_ fields: + // XXX_unrecognized []byte + // XXX_extensions map[int32]proto.Extension + // The first is handled here; + // the second is handled at the bottom of this function. + if name == "XXX_unrecognized" && !fv.IsNil() { + if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { + return err + } + } + continue + } + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Field not filled in. This could be an optional field or + // a required field that wasn't filled in. Either way, there + // isn't anything we can show for it. + continue + } + if fv.Kind() == reflect.Slice && fv.IsNil() { + // Repeated field that is empty, or a bytes field that is unused. + continue + } + + if props.Repeated && fv.Kind() == reflect.Slice { + // Repeated field. + for j := 0; j < fv.Len(); j++ { + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + v := fv.Index(j) + if v.Kind() == reflect.Ptr && v.IsNil() { + // A nil message in a repeated field is not valid, + // but we can handle that more gracefully than panicking. + if _, err := w.Write([]byte("\n")); err != nil { + return err + } + continue + } + if err := tm.writeAny(w, v, props); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + continue + } + if fv.Kind() == reflect.Map { + // Map fields are rendered as a repeated struct with key/value fields. + keys := fv.MapKeys() + sort.Sort(mapKeys(keys)) + for _, key := range keys { + val := fv.MapIndex(key) + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + // open struct + if err := w.WriteByte('<'); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + // key + if _, err := w.WriteString("key:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := tm.writeAny(w, key, props.MapKeyProp); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + // nil values aren't legal, but we can avoid panicking because of them. + if val.Kind() != reflect.Ptr || !val.IsNil() { + // value + if _, err := w.WriteString("value:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := tm.writeAny(w, val, props.MapValProp); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + // close struct + w.unindent() + if err := w.WriteByte('>'); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + continue + } + if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { + // empty bytes field + continue + } + if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { + // proto3 non-repeated scalar field; skip if zero value + if isProto3Zero(fv) { + continue + } + } + + if fv.Kind() == reflect.Interface { + // Check if it is a oneof. + if st.Field(i).Tag.Get("protobuf_oneof") != "" { + // fv is nil, or holds a pointer to generated struct. + // That generated struct has exactly one field, + // which has a protobuf struct tag. + if fv.IsNil() { + continue + } + inner := fv.Elem().Elem() // interface -> *T -> T + tag := inner.Type().Field(0).Tag.Get("protobuf") + props = new(Properties) // Overwrite the outer props var, but not its pointee. + props.Parse(tag) + // Write the value in the oneof, not the oneof itself. + fv = inner.Field(0) + + // Special case to cope with malformed messages gracefully: + // If the value in the oneof is a nil pointer, don't panic + // in writeAny. + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Use errors.New so writeAny won't render quotes. + msg := errors.New("/* nil */") + fv = reflect.ValueOf(&msg).Elem() + } + } + } + + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + + // Enums have a String method, so writeAny will work fine. + if err := tm.writeAny(w, fv, props); err != nil { + return err + } + + if err := w.WriteByte('\n'); err != nil { + return err + } + } + + // Extensions (the XXX_extensions field). + pv := sv.Addr() + if _, err := extendable(pv.Interface()); err == nil { + if err := tm.writeExtensions(w, pv); err != nil { + return err + } + } + + return nil +} + +// writeAny writes an arbitrary field. +func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { + v = reflect.Indirect(v) + + // Floats have special cases. + if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { + x := v.Float() + var b []byte + switch { + case math.IsInf(x, 1): + b = posInf + case math.IsInf(x, -1): + b = negInf + case math.IsNaN(x): + b = nan + } + if b != nil { + _, err := w.Write(b) + return err + } + // Other values are handled below. + } + + // We don't attempt to serialise every possible value type; only those + // that can occur in protocol buffers. + switch v.Kind() { + case reflect.Slice: + // Should only be a []byte; repeated fields are handled in writeStruct. + if err := writeString(w, string(v.Bytes())); err != nil { + return err + } + case reflect.String: + if err := writeString(w, v.String()); err != nil { + return err + } + case reflect.Struct: + // Required/optional group/message. + var bra, ket byte = '<', '>' + if props != nil && props.Wire == "group" { + bra, ket = '{', '}' + } + if err := w.WriteByte(bra); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + if v.CanAddr() { + // Calling v.Interface on a struct causes the reflect package to + // copy the entire struct. This is racy with the new Marshaler + // since we atomically update the XXX_sizecache. + // + // Thus, we retrieve a pointer to the struct if possible to avoid + // a race since v.Interface on the pointer doesn't copy the struct. + // + // If v is not addressable, then we are not worried about a race + // since it implies that the binary Marshaler cannot possibly be + // mutating this value. + v = v.Addr() + } + if etm, ok := v.Interface().(encoding.TextMarshaler); ok { + text, err := etm.MarshalText() + if err != nil { + return err + } + if _, err = w.Write(text); err != nil { + return err + } + } else { + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + if err := tm.writeStruct(w, v); err != nil { + return err + } + } + w.unindent() + if err := w.WriteByte(ket); err != nil { + return err + } + default: + _, err := fmt.Fprint(w, v.Interface()) + return err + } + return nil +} + +// equivalent to C's isprint. +func isprint(c byte) bool { + return c >= 0x20 && c < 0x7f +} + +// writeString writes a string in the protocol buffer text format. +// It is similar to strconv.Quote except we don't use Go escape sequences, +// we treat the string as a byte sequence, and we use octal escapes. +// These differences are to maintain interoperability with the other +// languages' implementations of the text format. +func writeString(w *textWriter, s string) error { + // use WriteByte here to get any needed indent + if err := w.WriteByte('"'); err != nil { + return err + } + // Loop over the bytes, not the runes. + for i := 0; i < len(s); i++ { + var err error + // Divergence from C++: we don't escape apostrophes. + // There's no need to escape them, and the C++ parser + // copes with a naked apostrophe. + switch c := s[i]; c { + case '\n': + _, err = w.w.Write(backslashN) + case '\r': + _, err = w.w.Write(backslashR) + case '\t': + _, err = w.w.Write(backslashT) + case '"': + _, err = w.w.Write(backslashDQ) + case '\\': + _, err = w.w.Write(backslashBS) + default: + if isprint(c) { + err = w.w.WriteByte(c) + } else { + _, err = fmt.Fprintf(w.w, "\\%03o", c) + } + } + if err != nil { + return err + } + } + return w.WriteByte('"') +} + +func writeUnknownStruct(w *textWriter, data []byte) (err error) { + if !w.compact { + if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { + return err + } + } + b := NewBuffer(data) + for b.index < len(b.buf) { + x, err := b.DecodeVarint() + if err != nil { + _, err := fmt.Fprintf(w, "/* %v */\n", err) + return err + } + wire, tag := x&7, x>>3 + if wire == WireEndGroup { + w.unindent() + if _, err := w.Write(endBraceNewline); err != nil { + return err + } + continue + } + if _, err := fmt.Fprint(w, tag); err != nil { + return err + } + if wire != WireStartGroup { + if err := w.WriteByte(':'); err != nil { + return err + } + } + if !w.compact || wire == WireStartGroup { + if err := w.WriteByte(' '); err != nil { + return err + } + } + switch wire { + case WireBytes: + buf, e := b.DecodeRawBytes(false) + if e == nil { + _, err = fmt.Fprintf(w, "%q", buf) + } else { + _, err = fmt.Fprintf(w, "/* %v */", e) + } + case WireFixed32: + x, err = b.DecodeFixed32() + err = writeUnknownInt(w, x, err) + case WireFixed64: + x, err = b.DecodeFixed64() + err = writeUnknownInt(w, x, err) + case WireStartGroup: + err = w.WriteByte('{') + w.indent() + case WireVarint: + x, err = b.DecodeVarint() + err = writeUnknownInt(w, x, err) + default: + _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) + } + if err != nil { + return err + } + if err = w.WriteByte('\n'); err != nil { + return err + } + } + return nil +} + +func writeUnknownInt(w *textWriter, x uint64, err error) error { + if err == nil { + _, err = fmt.Fprint(w, x) + } else { + _, err = fmt.Fprintf(w, "/* %v */", err) + } + return err +} + +type int32Slice []int32 + +func (s int32Slice) Len() int { return len(s) } +func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// writeExtensions writes all the extensions in pv. +// pv is assumed to be a pointer to a protocol message struct that is extendable. +func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { + emap := extensionMaps[pv.Type().Elem()] + ep, _ := extendable(pv.Interface()) + + // Order the extensions by ID. + // This isn't strictly necessary, but it will give us + // canonical output, which will also make testing easier. + m, mu := ep.extensionsRead() + if m == nil { + return nil + } + mu.Lock() + ids := make([]int32, 0, len(m)) + for id := range m { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) + mu.Unlock() + + for _, extNum := range ids { + ext := m[extNum] + var desc *ExtensionDesc + if emap != nil { + desc = emap[extNum] + } + if desc == nil { + // Unknown extension. + if err := writeUnknownStruct(w, ext.enc); err != nil { + return err + } + continue + } + + pb, err := GetExtension(ep, desc) + if err != nil { + return fmt.Errorf("failed getting extension: %v", err) + } + + // Repeated extensions will appear as a slice. + if !desc.repeated() { + if err := tm.writeExtension(w, desc.Name, pb); err != nil { + return err + } + } else { + v := reflect.ValueOf(pb) + for i := 0; i < v.Len(); i++ { + if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { + return err + } + } + } + } + return nil +} + +func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { + if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + return nil +} + +func (w *textWriter) writeIndent() { + if !w.complete { + return + } + remain := w.ind * 2 + for remain > 0 { + n := remain + if n > len(spaces) { + n = len(spaces) + } + w.w.Write(spaces[:n]) + remain -= n + } + w.complete = false +} + +// TextMarshaler is a configurable text format marshaler. +type TextMarshaler struct { + Compact bool // use compact text format (one line). + ExpandAny bool // expand google.protobuf.Any messages of known types +} + +// Marshal writes a given protocol buffer in text format. +// The only errors returned are from w. +func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { + val := reflect.ValueOf(pb) + if pb == nil || val.IsNil() { + w.Write([]byte("")) + return nil + } + var bw *bufio.Writer + ww, ok := w.(writer) + if !ok { + bw = bufio.NewWriter(w) + ww = bw + } + aw := &textWriter{ + w: ww, + complete: true, + compact: tm.Compact, + } + + if etm, ok := pb.(encoding.TextMarshaler); ok { + text, err := etm.MarshalText() + if err != nil { + return err + } + if _, err = aw.Write(text); err != nil { + return err + } + if bw != nil { + return bw.Flush() + } + return nil + } + // Dereference the received pointer so we don't have outer < and >. + v := reflect.Indirect(val) + if err := tm.writeStruct(aw, v); err != nil { + return err + } + if bw != nil { + return bw.Flush() + } + return nil +} + +// Text is the same as Marshal, but returns the string directly. +func (tm *TextMarshaler) Text(pb Message) string { + var buf bytes.Buffer + tm.Marshal(&buf, pb) + return buf.String() +} + +var ( + defaultTextMarshaler = TextMarshaler{} + compactTextMarshaler = TextMarshaler{Compact: true} +) + +// TODO: consider removing some of the Marshal functions below. + +// MarshalText writes a given protocol buffer in text format. +// The only errors returned are from w. +func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } + +// MarshalTextString is the same as MarshalText, but returns the string directly. +func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } + +// CompactText writes a given protocol buffer in compact text format (one line). +func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } + +// CompactTextString is the same as CompactText, but returns the string directly. +func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go new file mode 100644 index 000000000..bb55a3af2 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/text_parser.go @@ -0,0 +1,880 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package proto + +// Functions for parsing the Text protocol buffer format. +// TODO: message sets. + +import ( + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "unicode/utf8" +) + +// Error string emitted when deserializing Any and fields are already set +const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" + +type ParseError struct { + Message string + Line int // 1-based line number + Offset int // 0-based byte offset from start of input +} + +func (p *ParseError) Error() string { + if p.Line == 1 { + // show offset only for first line + return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) + } + return fmt.Sprintf("line %d: %v", p.Line, p.Message) +} + +type token struct { + value string + err *ParseError + line int // line number + offset int // byte number from start of input, not start of line + unquoted string // the unquoted version of value, if it was a quoted string +} + +func (t *token) String() string { + if t.err == nil { + return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) + } + return fmt.Sprintf("parse error: %v", t.err) +} + +type textParser struct { + s string // remaining input + done bool // whether the parsing is finished (success or error) + backed bool // whether back() was called + offset, line int + cur token +} + +func newTextParser(s string) *textParser { + p := new(textParser) + p.s = s + p.line = 1 + p.cur.line = 1 + return p +} + +func (p *textParser) errorf(format string, a ...interface{}) *ParseError { + pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} + p.cur.err = pe + p.done = true + return pe +} + +// Numbers and identifiers are matched by [-+._A-Za-z0-9] +func isIdentOrNumberChar(c byte) bool { + switch { + case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': + return true + case '0' <= c && c <= '9': + return true + } + switch c { + case '-', '+', '.', '_': + return true + } + return false +} + +func isWhitespace(c byte) bool { + switch c { + case ' ', '\t', '\n', '\r': + return true + } + return false +} + +func isQuote(c byte) bool { + switch c { + case '"', '\'': + return true + } + return false +} + +func (p *textParser) skipWhitespace() { + i := 0 + for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { + if p.s[i] == '#' { + // comment; skip to end of line or input + for i < len(p.s) && p.s[i] != '\n' { + i++ + } + if i == len(p.s) { + break + } + } + if p.s[i] == '\n' { + p.line++ + } + i++ + } + p.offset += i + p.s = p.s[i:len(p.s)] + if len(p.s) == 0 { + p.done = true + } +} + +func (p *textParser) advance() { + // Skip whitespace + p.skipWhitespace() + if p.done { + return + } + + // Start of non-whitespace + p.cur.err = nil + p.cur.offset, p.cur.line = p.offset, p.line + p.cur.unquoted = "" + switch p.s[0] { + case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': + // Single symbol + p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] + case '"', '\'': + // Quoted string + i := 1 + for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { + if p.s[i] == '\\' && i+1 < len(p.s) { + // skip escaped char + i++ + } + i++ + } + if i >= len(p.s) || p.s[i] != p.s[0] { + p.errorf("unmatched quote") + return + } + unq, err := unquoteC(p.s[1:i], rune(p.s[0])) + if err != nil { + p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) + return + } + p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] + p.cur.unquoted = unq + default: + i := 0 + for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { + i++ + } + if i == 0 { + p.errorf("unexpected byte %#x", p.s[0]) + return + } + p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] + } + p.offset += len(p.cur.value) +} + +var ( + errBadUTF8 = errors.New("proto: bad UTF-8") +) + +func unquoteC(s string, quote rune) (string, error) { + // This is based on C++'s tokenizer.cc. + // Despite its name, this is *not* parsing C syntax. + // For instance, "\0" is an invalid quoted string. + + // Avoid allocation in trivial cases. + simple := true + for _, r := range s { + if r == '\\' || r == quote { + simple = false + break + } + } + if simple { + return s, nil + } + + buf := make([]byte, 0, 3*len(s)/2) + for len(s) > 0 { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", errBadUTF8 + } + s = s[n:] + if r != '\\' { + if r < utf8.RuneSelf { + buf = append(buf, byte(r)) + } else { + buf = append(buf, string(r)...) + } + continue + } + + ch, tail, err := unescape(s) + if err != nil { + return "", err + } + buf = append(buf, ch...) + s = tail + } + return string(buf), nil +} + +func unescape(s string) (ch string, tail string, err error) { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", "", errBadUTF8 + } + s = s[n:] + switch r { + case 'a': + return "\a", s, nil + case 'b': + return "\b", s, nil + case 'f': + return "\f", s, nil + case 'n': + return "\n", s, nil + case 'r': + return "\r", s, nil + case 't': + return "\t", s, nil + case 'v': + return "\v", s, nil + case '?': + return "?", s, nil // trigraph workaround + case '\'', '"', '\\': + return string(r), s, nil + case '0', '1', '2', '3', '4', '5', '6', '7': + if len(s) < 2 { + return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) + } + ss := string(r) + s[:2] + s = s[2:] + i, err := strconv.ParseUint(ss, 8, 8) + if err != nil { + return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) + } + return string([]byte{byte(i)}), s, nil + case 'x', 'X', 'u', 'U': + var n int + switch r { + case 'x', 'X': + n = 2 + case 'u': + n = 4 + case 'U': + n = 8 + } + if len(s) < n { + return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) + } + ss := s[:n] + s = s[n:] + i, err := strconv.ParseUint(ss, 16, 64) + if err != nil { + return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) + } + if r == 'x' || r == 'X' { + return string([]byte{byte(i)}), s, nil + } + if i > utf8.MaxRune { + return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) + } + return string(i), s, nil + } + return "", "", fmt.Errorf(`unknown escape \%c`, r) +} + +// Back off the parser by one token. Can only be done between calls to next(). +// It makes the next advance() a no-op. +func (p *textParser) back() { p.backed = true } + +// Advances the parser and returns the new current token. +func (p *textParser) next() *token { + if p.backed || p.done { + p.backed = false + return &p.cur + } + p.advance() + if p.done { + p.cur.value = "" + } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { + // Look for multiple quoted strings separated by whitespace, + // and concatenate them. + cat := p.cur + for { + p.skipWhitespace() + if p.done || !isQuote(p.s[0]) { + break + } + p.advance() + if p.cur.err != nil { + return &p.cur + } + cat.value += " " + p.cur.value + cat.unquoted += p.cur.unquoted + } + p.done = false // parser may have seen EOF, but we want to return cat + p.cur = cat + } + return &p.cur +} + +func (p *textParser) consumeToken(s string) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != s { + p.back() + return p.errorf("expected %q, found %q", s, tok.value) + } + return nil +} + +// Return a RequiredNotSetError indicating which required field was not set. +func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { + st := sv.Type() + sprops := GetProperties(st) + for i := 0; i < st.NumField(); i++ { + if !isNil(sv.Field(i)) { + continue + } + + props := sprops.Prop[i] + if props.Required { + return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} + } + } + return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen +} + +// Returns the index in the struct for the named field, as well as the parsed tag properties. +func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { + i, ok := sprops.decoderOrigNames[name] + if ok { + return i, sprops.Prop[i], true + } + return -1, nil, false +} + +// Consume a ':' from the input stream (if the next token is a colon), +// returning an error if a colon is needed but not present. +func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ":" { + // Colon is optional when the field is a group or message. + needColon := true + switch props.Wire { + case "group": + needColon = false + case "bytes": + // A "bytes" field is either a message, a string, or a repeated field; + // those three become *T, *string and []T respectively, so we can check for + // this field being a pointer to a non-string. + if typ.Kind() == reflect.Ptr { + // *T or *string + if typ.Elem().Kind() == reflect.String { + break + } + } else if typ.Kind() == reflect.Slice { + // []T or []*T + if typ.Elem().Kind() != reflect.Ptr { + break + } + } else if typ.Kind() == reflect.String { + // The proto3 exception is for a string field, + // which requires a colon. + break + } + needColon = false + } + if needColon { + return p.errorf("expected ':', found %q", tok.value) + } + p.back() + } + return nil +} + +func (p *textParser) readStruct(sv reflect.Value, terminator string) error { + st := sv.Type() + sprops := GetProperties(st) + reqCount := sprops.reqCount + var reqFieldErr error + fieldSet := make(map[string]bool) + // A struct is a sequence of "name: value", terminated by one of + // '>' or '}', or the end of the input. A name may also be + // "[extension]" or "[type/url]". + // + // The whole struct can also be an expanded Any message, like: + // [type/url] < ... struct contents ... > + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + if tok.value == "[" { + // Looks like an extension or an Any. + // + // TODO: Check whether we need to handle + // namespace rooted names (e.g. ".something.Foo"). + extName, err := p.consumeExtName() + if err != nil { + return err + } + + if s := strings.LastIndex(extName, "/"); s >= 0 { + // If it contains a slash, it's an Any type URL. + messageName := extName[s+1:] + mt := MessageType(messageName) + if mt == nil { + return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) + } + tok = p.next() + if tok.err != nil { + return tok.err + } + // consume an optional colon + if tok.value == ":" { + tok = p.next() + if tok.err != nil { + return tok.err + } + } + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + v := reflect.New(mt.Elem()) + if pe := p.readStruct(v.Elem(), terminator); pe != nil { + return pe + } + b, err := Marshal(v.Interface().(Message)) + if err != nil { + return p.errorf("failed to marshal message of type %q: %v", messageName, err) + } + if fieldSet["type_url"] { + return p.errorf(anyRepeatedlyUnpacked, "type_url") + } + if fieldSet["value"] { + return p.errorf(anyRepeatedlyUnpacked, "value") + } + sv.FieldByName("TypeUrl").SetString(extName) + sv.FieldByName("Value").SetBytes(b) + fieldSet["type_url"] = true + fieldSet["value"] = true + continue + } + + var desc *ExtensionDesc + // This could be faster, but it's functional. + // TODO: Do something smarter than a linear scan. + for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { + if d.Name == extName { + desc = d + break + } + } + if desc == nil { + return p.errorf("unrecognized extension %q", extName) + } + + props := &Properties{} + props.Parse(desc.Tag) + + typ := reflect.TypeOf(desc.ExtensionType) + if err := p.checkForColon(props, typ); err != nil { + return err + } + + rep := desc.repeated() + + // Read the extension structure, and set it in + // the value we're constructing. + var ext reflect.Value + if !rep { + ext = reflect.New(typ).Elem() + } else { + ext = reflect.New(typ.Elem()).Elem() + } + if err := p.readAny(ext, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } + ep := sv.Addr().Interface().(Message) + if !rep { + SetExtension(ep, desc, ext.Interface()) + } else { + old, err := GetExtension(ep, desc) + var sl reflect.Value + if err == nil { + sl = reflect.ValueOf(old) // existing slice + } else { + sl = reflect.MakeSlice(typ, 0, 1) + } + sl = reflect.Append(sl, ext) + SetExtension(ep, desc, sl.Interface()) + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + continue + } + + // This is a normal, non-extension field. + name := tok.value + var dst reflect.Value + fi, props, ok := structFieldByName(sprops, name) + if ok { + dst = sv.Field(fi) + } else if oop, ok := sprops.OneofTypes[name]; ok { + // It is a oneof. + props = oop.Prop + nv := reflect.New(oop.Type.Elem()) + dst = nv.Elem().Field(0) + field := sv.Field(oop.Field) + if !field.IsNil() { + return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) + } + field.Set(nv) + } + if !dst.IsValid() { + return p.errorf("unknown field name %q in %v", name, st) + } + + if dst.Kind() == reflect.Map { + // Consume any colon. + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Construct the map if it doesn't already exist. + if dst.IsNil() { + dst.Set(reflect.MakeMap(dst.Type())) + } + key := reflect.New(dst.Type().Key()).Elem() + val := reflect.New(dst.Type().Elem()).Elem() + + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // However, implementations may omit key or value, and technically + // we should support them in any order. See b/28924776 for a time + // this went wrong. + + tok := p.next() + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + switch tok.value { + case "key": + if err := p.consumeToken(":"); err != nil { + return err + } + if err := p.readAny(key, props.MapKeyProp); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + case "value": + if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil { + return err + } + if err := p.readAny(val, props.MapValProp); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + default: + p.back() + return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) + } + } + + dst.SetMapIndex(key, val) + continue + } + + // Check that it's not already set if it's not a repeated field. + if !props.Repeated && fieldSet[name] { + return p.errorf("non-repeated field %q was repeated", name) + } + + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Parse into the field. + fieldSet[name] = true + if err := p.readAny(dst, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } + if props.Required { + reqCount-- + } + + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + + } + + if reqCount > 0 { + return p.missingRequiredFieldError(sv) + } + return reqFieldErr +} + +// consumeExtName consumes extension name or expanded Any type URL and the +// following ']'. It returns the name or URL consumed. +func (p *textParser) consumeExtName() (string, error) { + tok := p.next() + if tok.err != nil { + return "", tok.err + } + + // If extension name or type url is quoted, it's a single token. + if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { + name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) + if err != nil { + return "", err + } + return name, p.consumeToken("]") + } + + // Consume everything up to "]" + var parts []string + for tok.value != "]" { + parts = append(parts, tok.value) + tok = p.next() + if tok.err != nil { + return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) + } + if p.done && tok.value != "]" { + return "", p.errorf("unclosed type_url or extension name") + } + } + return strings.Join(parts, ""), nil +} + +// consumeOptionalSeparator consumes an optional semicolon or comma. +// It is used in readStruct to provide backward compatibility. +func (p *textParser) consumeOptionalSeparator() error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ";" && tok.value != "," { + p.back() + } + return nil +} + +func (p *textParser) readAny(v reflect.Value, props *Properties) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == "" { + return p.errorf("unexpected EOF") + } + + switch fv := v; fv.Kind() { + case reflect.Slice: + at := v.Type() + if at.Elem().Kind() == reflect.Uint8 { + // Special case for []byte + if tok.value[0] != '"' && tok.value[0] != '\'' { + // Deliberately written out here, as the error after + // this switch statement would write "invalid []byte: ...", + // which is not as user-friendly. + return p.errorf("invalid string: %v", tok.value) + } + bytes := []byte(tok.unquoted) + fv.Set(reflect.ValueOf(bytes)) + return nil + } + // Repeated field. + if tok.value == "[" { + // Repeated field with list notation, like [1,2,3]. + for { + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + err := p.readAny(fv.Index(fv.Len()-1), props) + if err != nil { + return err + } + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == "]" { + break + } + if tok.value != "," { + return p.errorf("Expected ']' or ',' found %q", tok.value) + } + } + return nil + } + // One value of the repeated field. + p.back() + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + return p.readAny(fv.Index(fv.Len()-1), props) + case reflect.Bool: + // true/1/t/True or false/f/0/False. + switch tok.value { + case "true", "1", "t", "True": + fv.SetBool(true) + return nil + case "false", "0", "f", "False": + fv.SetBool(false) + return nil + } + case reflect.Float32, reflect.Float64: + v := tok.value + // Ignore 'f' for compatibility with output generated by C++, but don't + // remove 'f' when the value is "-inf" or "inf". + if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { + v = v[:len(v)-1] + } + if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { + fv.SetFloat(f) + return nil + } + case reflect.Int32: + if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { + fv.SetInt(x) + return nil + } + + if len(props.Enum) == 0 { + break + } + m, ok := enumValueMaps[props.Enum] + if !ok { + break + } + x, ok := m[tok.value] + if !ok { + break + } + fv.SetInt(int64(x)) + return nil + case reflect.Int64: + if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { + fv.SetInt(x) + return nil + } + + case reflect.Ptr: + // A basic field (indirected through pointer), or a repeated message/group + p.back() + fv.Set(reflect.New(fv.Type().Elem())) + return p.readAny(fv.Elem(), props) + case reflect.String: + if tok.value[0] == '"' || tok.value[0] == '\'' { + fv.SetString(tok.unquoted) + return nil + } + case reflect.Struct: + var terminator string + switch tok.value { + case "{": + terminator = "}" + case "<": + terminator = ">" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + // TODO: Handle nested messages which implement encoding.TextUnmarshaler. + return p.readStruct(fv, terminator) + case reflect.Uint32: + if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { + fv.SetUint(uint64(x)) + return nil + } + case reflect.Uint64: + if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { + fv.SetUint(x) + return nil + } + } + return p.errorf("invalid %v: %v", v.Type(), tok.value) +} + +// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb +// before starting to unmarshal, so any existing data in pb is always removed. +// If a required field is not set and no other error occurs, +// UnmarshalText returns *RequiredNotSetError. +func UnmarshalText(s string, pb Message) error { + if um, ok := pb.(encoding.TextUnmarshaler); ok { + return um.UnmarshalText([]byte(s)) + } + pb.Reset() + v := reflect.ValueOf(pb) + return newTextParser(s).readStruct(v.Elem(), "") +} diff --git a/vendor/github.com/googollee/go-engine.io/README.md b/vendor/github.com/googollee/go-engine.io/README.md deleted file mode 100644 index c5d603f57..000000000 --- a/vendor/github.com/googollee/go-engine.io/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# go-engine.io - -[![GoDoc](http://godoc.org/github.com/googollee/go-engine.io?status.svg)](http://godoc.org/github.com/googollee/go-engine.io) [![Build Status](https://travis-ci.org/googollee/go-engine.io.svg)](https://travis-ci.org/googollee/go-engine.io) - -go-engine.io is the implement of engine.io in golang, which is transport-based cross-browser/cross-device bi-directional communication layer for [go-socket.io](https://github.com/googollee/go-socket.io). - -It is compatible with node.js implement, and supported long-polling and websocket transport. - -## Install - -Install the package with: - -```bash -go get github.com/googollee/go-engine.io -``` - -Import it with: - -```go -import "github.com/googollee/go-engine.io" -``` - -and use `engineio` as the package name inside the code. - -## Example - -Please check example folder for details. - -```go -package main - -import ( - "encoding/hex" - "io/ioutil" - "log" - "net/http" - - "github.com/googollee/go-engine.io" -) - -func main() { - server, err := engineio.NewServer(nil) - if err != nil { - log.Fatal(err) - } - - go func() { - for { - conn, _ := server.Accept() - go func() { - defer conn.Close() - for i := 0; i < 10; i++ { - t, r, _ := conn.NextReader() - b, _ := ioutil.ReadAll(r) - r.Close() - if t == engineio.MessageText { - log.Println(t, string(b)) - } else { - log.Println(t, hex.EncodeToString(b)) - } - w, _ := conn.NextWriter(t) - w.Write([]byte("pong")) - w.Close() - } - }() - } - }() - - http.Handle("/engine.io/", server) - http.Handle("/", http.FileServer(http.Dir("./asset"))) - log.Println("Serving at localhost:5000...") - log.Fatal(http.ListenAndServe(":5000", nil)) -} -``` - -## License - -The 3-clause BSD License - see LICENSE for more details \ No newline at end of file diff --git a/vendor/github.com/googollee/go-engine.io/polling/server.go b/vendor/github.com/googollee/go-engine.io/polling/server.go index 7cf72f239..7de1acbc2 100644 --- a/vendor/github.com/googollee/go-engine.io/polling/server.go +++ b/vendor/github.com/googollee/go-engine.io/polling/server.go @@ -60,8 +60,8 @@ func (p *Polling) Close() error { if p.getState() != stateNormal { return nil } - close(p.sendChan) p.setState(stateClosing) + close(p.sendChan) if p.getLocker.TryLock() { if p.postLocker.TryLock() { p.callback.OnClose(p) diff --git a/vendor/github.com/googollee/go-engine.io/server.go b/vendor/github.com/googollee/go-engine.io/server.go index 45f4a74d8..24a14206d 100644 --- a/vendor/github.com/googollee/go-engine.io/server.go +++ b/vendor/github.com/googollee/go-engine.io/server.go @@ -5,11 +5,12 @@ import ( "crypto/md5" "encoding/base64" "fmt" - "github.com/googollee/go-engine.io/polling" - "github.com/googollee/go-engine.io/websocket" "net/http" "sync/atomic" "time" + + "github.com/googollee/go-engine.io/polling" + "github.com/googollee/go-engine.io/websocket" ) type config struct { @@ -78,6 +79,16 @@ func (s *Server) SetMaxConnection(n int) { s.config.MaxConnection = n } +// GetMaxConnection returns the current max connection +func (s *Server) GetMaxConnection() int { + return s.config.MaxConnection +} + +// Count returns a count of current number of active connections in session +func (s *Server) Count() int { + return int(atomic.LoadInt32(&s.currentConnection)) +} + // SetAllowRequest sets the middleware function when establish connection. If it return non-nil, connection won't be established. Default will allow all request. func (s *Server) SetAllowRequest(f func(*http.Request) error) { s.config.AllowRequest = f @@ -122,6 +133,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { n := atomic.AddInt32(&s.currentConnection, 1) if int(n) > s.config.MaxConnection { + atomic.AddInt32(&s.currentConnection, -1) http.Error(w, "too many connections", http.StatusServiceUnavailable) return } @@ -131,6 +143,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { var err error conn, err = newServerConn(sid, w, r, s) if err != nil { + atomic.AddInt32(&s.currentConnection, -1) http.Error(w, err.Error(), http.StatusBadRequest) return } diff --git a/vendor/github.com/googollee/go-engine.io/server_conn.go b/vendor/github.com/googollee/go-engine.io/server_conn.go index 571a227e4..ae85459fd 100644 --- a/vendor/github.com/googollee/go-engine.io/server_conn.go +++ b/vendor/github.com/googollee/go-engine.io/server_conn.go @@ -78,6 +78,7 @@ type serverConn struct { pingTimeout time.Duration pingInterval time.Duration pingChan chan bool + pingLocker sync.Mutex } var InvalidError = errors.New("invalid transport") @@ -147,8 +148,14 @@ func (c *serverConn) NextWriter(t MessageType) (io.WriteCloser, error) { default: return nil, io.EOF } + c.writerLocker.Lock() ret, err := c.getCurrent().NextWriter(message.MessageType(t), parser.MESSAGE) - return ret, err + if err != nil { + c.writerLocker.Unlock() + return ret, err + } + writer := newConnWriter(ret, &c.writerLocker) + return writer, err } func (c *serverConn) Close() error { @@ -200,6 +207,7 @@ func (c *serverConn) OnPacket(r *parser.PacketDecoder) { case parser.CLOSE: c.getCurrent().Close() case parser.PING: + c.writerLocker.Lock() t := c.getCurrent() u := c.getUpgrade() newWriter := t.NextWriter @@ -213,8 +221,14 @@ func (c *serverConn) OnPacket(r *parser.PacketDecoder) { io.Copy(w, r) w.Close() } + c.writerLocker.Unlock() fallthrough case parser.PONG: + c.pingLocker.Lock() + defer c.pingLocker.Unlock() + if s := c.getState(); s != stateNormal && s != stateUpgrading { + return + } c.pingChan <- true case parser.MESSAGE: closeChan := make(chan struct{}) @@ -245,7 +259,9 @@ func (c *serverConn) OnClose(server transport.Server) { } c.setState(stateClosed) close(c.readerChan) + c.pingLocker.Lock() close(c.pingChan) + c.pingLocker.Unlock() c.callback.onClose(c.id) } diff --git a/vendor/github.com/googollee/go-socket.io/README.md b/vendor/github.com/googollee/go-socket.io/README.md deleted file mode 100644 index f49ce3f61..000000000 --- a/vendor/github.com/googollee/go-socket.io/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# socket.io - -[![GoDoc](http://godoc.org/github.com/googollee/go-socket.io?status.svg)](http://godoc.org/github.com/googollee/go-socket.io) [![Build Status](https://travis-ci.org/googollee/go-socket.io.svg)](https://travis-ci.org/googollee/go-socket.io) - -go-socket.io is an implementation of [socket.io](http://socket.io) in golang, which is a realtime application framework. - -It is compatible with latest implementation of socket.io in node.js, and supports room and namespace. - -* for compatability with socket.io 0.9.x, please use branch 0.9.x * - -## Install - -Install the package with: - -```bash -go get github.com/googollee/go-socket.io -``` - -Import it with: - -```go -import "github.com/googollee/go-socket.io" -``` - -and use `socketio` as the package name inside the code. - -## Example - -Please check the example folder for details. - -```go -package main - -import ( - "log" - "net/http" - - "github.com/googollee/go-socket.io" -) - -func main() { - server, err := socketio.NewServer(nil) - if err != nil { - log.Fatal(err) - } - server.On("connection", func(so socketio.Socket) { - log.Println("on connection") - so.Join("chat") - so.On("chat message", func(msg string) { - log.Println("emit:", so.Emit("chat message", msg)) - so.BroadcastTo("chat", "chat message", msg) - }) - so.On("disconnection", func() { - log.Println("on disconnect") - }) - }) - server.On("error", func(so socketio.Socket, err error) { - log.Println("error:", err) - }) - - http.Handle("/socket.io/", server) - http.Handle("/", http.FileServer(http.Dir("./asset"))) - log.Println("Serving at localhost:5000...") - log.Fatal(http.ListenAndServe(":5000", nil)) -} -``` - -## License - -The 3-clause BSD License - see LICENSE for more details diff --git a/vendor/github.com/googollee/go-socket.io/adapter.go b/vendor/github.com/googollee/go-socket.io/adapter.go index 12f9e481e..32b1ae889 100644 --- a/vendor/github.com/googollee/go-socket.io/adapter.go +++ b/vendor/github.com/googollee/go-socket.io/adapter.go @@ -1,57 +1,79 @@ package socketio -// BroadcastAdaptor is the adaptor to handle broadcast. +import "sync" + +// BroadcastAdaptor is the adaptor to handle broadcasts. type BroadcastAdaptor interface { - // Join lets socket join the t room. + // Join causes the socket to join a room. Join(room string, socket Socket) error - // Leave let socket leave the room. + // Leave causes the socket to leave a room. Leave(room string, socket Socket) error - // Send will send the message with args to room. If ignore is not nil, it won't send to the socket ignore. - Send(ignore Socket, room, message string, args ...interface{}) error + // Send will send an event with args to the room. If "ignore" is not nil, the event will be excluded from being sent to "ignore". + Send(ignore Socket, room, event string, args ...interface{}) error + + //Len socket in room + Len(room string) int } var newBroadcast = newBroadcastDefault -type broadcast map[string]map[string]Socket +type broadcast struct { + m map[string]map[string]Socket + sync.RWMutex +} func newBroadcastDefault() BroadcastAdaptor { - return make(broadcast) + return &broadcast{ + m: make(map[string]map[string]Socket), + } } -func (b broadcast) Join(room string, socket Socket) error { - sockets, ok := b[room] +func (b *broadcast) Join(room string, socket Socket) error { + b.Lock() + sockets, ok := b.m[room] if !ok { sockets = make(map[string]Socket) } sockets[socket.Id()] = socket - b[room] = sockets + b.m[room] = sockets + b.Unlock() return nil } -func (b broadcast) Leave(room string, socket Socket) error { - sockets, ok := b[room] +func (b *broadcast) Leave(room string, socket Socket) error { + b.Lock() + defer b.Unlock() + sockets, ok := b.m[room] if !ok { return nil } delete(sockets, socket.Id()) if len(sockets) == 0 { - delete(b, room) + delete(b.m, room) return nil } - b[room] = sockets + b.m[room] = sockets return nil } -func (b broadcast) Send(ignore Socket, room, message string, args ...interface{}) error { - sockets := b[room] +func (b *broadcast) Send(ignore Socket, room, event string, args ...interface{}) error { + b.RLock() + sockets := b.m[room] for id, s := range sockets { if ignore != nil && ignore.Id() == id { continue } - s.Emit(message, args...) + s.Emit(event, args...) } + b.RUnlock() return nil } + +func (b *broadcast) Len(room string) int { + b.RLock() + defer b.RUnlock() + return len(b.m[room]) +} diff --git a/vendor/github.com/googollee/go-socket.io/attachment.go b/vendor/github.com/googollee/go-socket.io/attachment.go index 9a6573d48..2f04c0823 100644 --- a/vendor/github.com/googollee/go-socket.io/attachment.go +++ b/vendor/github.com/googollee/go-socket.io/attachment.go @@ -8,7 +8,7 @@ import ( "reflect" ) -// Attachment is an attachment handler used in emit args. All attachments will send as binary in transport layer. When use attachment, make sure use as pointer. +// Attachment is an attachment handler used in emit args. All attachments will be sent as binary data in the transport layer. When using an attachment, make sure it is a pointer. // // For example: // @@ -30,8 +30,6 @@ import ( // b, _ := ioutil.ReadAll(arg.File.Data) // }) type Attachment struct { - - // Data is the ReadWriter of the attachment data. Data io.ReadWriter num int } diff --git a/vendor/github.com/googollee/go-socket.io/caller.go b/vendor/github.com/googollee/go-socket.io/caller.go index 3c1112593..15666b440 100644 --- a/vendor/github.com/googollee/go-socket.io/caller.go +++ b/vendor/github.com/googollee/go-socket.io/caller.go @@ -61,6 +61,11 @@ func (c *caller) Call(so Socket, args []interface{}) []reflect.Value { } else { a = make([]reflect.Value, len(args)) } + + if len(args) != len(c.Args) { + return []reflect.Value{reflect.ValueOf([]interface{}{}), reflect.ValueOf(errors.New("Arguments do not match"))} + } + for i, arg := range args { v := reflect.ValueOf(arg) if c.Args[i].Kind() != reflect.Ptr { @@ -73,9 +78,5 @@ func (c *caller) Call(so Socket, args []interface{}) []reflect.Value { a[i+diff] = v } - if len(args) != len(c.Args) { - return []reflect.Value{reflect.ValueOf([]interface{}{}), reflect.ValueOf(errors.New("Arguments do not match"))} - } - return c.Func.Call(a) } diff --git a/vendor/github.com/googollee/go-socket.io/handler.go b/vendor/github.com/googollee/go-socket.io/handler.go index c69f0b259..b6a689d55 100644 --- a/vendor/github.com/googollee/go-socket.io/handler.go +++ b/vendor/github.com/googollee/go-socket.io/handler.go @@ -3,12 +3,14 @@ package socketio import ( "fmt" "reflect" + "sync" ) type baseHandler struct { events map[string]*caller name string broadcast BroadcastAdaptor + evMu sync.Mutex } func newBaseHandler(name string, broadcast BroadcastAdaptor) *baseHandler { @@ -16,21 +18,25 @@ func newBaseHandler(name string, broadcast BroadcastAdaptor) *baseHandler { events: make(map[string]*caller), name: name, broadcast: broadcast, + evMu: sync.Mutex{}, } } -// On registers the function f to handle message. -func (h *baseHandler) On(message string, f interface{}) error { +// On registers the function f to handle an event. +func (h *baseHandler) On(event string, f interface{}) error { c, err := newCaller(f) if err != nil { return err } - h.events[message] = c + h.evMu.Lock() + h.events[event] = c + h.evMu.Unlock() return nil } type socketHandler struct { *baseHandler + acksmu sync.Mutex acks map[int]*caller socket *socket rooms map[string]struct{} @@ -38,13 +44,16 @@ type socketHandler struct { func newSocketHandler(s *socket, base *baseHandler) *socketHandler { events := make(map[string]*caller) + base.evMu.Lock() for k, v := range base.events { events[k] = v } + base.evMu.Unlock() return &socketHandler{ baseHandler: &baseHandler{ events: events, broadcast: base.broadcast, + evMu: base.evMu, }, acks: make(map[int]*caller), socket: s, @@ -52,7 +61,7 @@ func newSocketHandler(s *socket, base *baseHandler) *socketHandler { } } -func (h *socketHandler) Emit(message string, args ...interface{}) error { +func (h *socketHandler) Emit(event string, args ...interface{}) error { var c *caller if l := len(args); l > 0 { fv := reflect.ValueOf(args[l-1]) @@ -65,13 +74,15 @@ func (h *socketHandler) Emit(message string, args ...interface{}) error { args = args[:l-1] } } - args = append([]interface{}{message}, args...) + args = append([]interface{}{event}, args...) if c != nil { id, err := h.socket.sendId(args) if err != nil { return err } + h.acksmu.Lock() h.acks[id] = c + h.acksmu.Unlock() return nil } return h.socket.send(args) @@ -112,12 +123,12 @@ func (h *socketHandler) LeaveAll() error { return nil } -func (h *baseHandler) BroadcastTo(room, message string, args ...interface{}) error { - return h.broadcast.Send(nil, h.broadcastName(room), message, args...) +func (h *baseHandler) BroadcastTo(room, event string, args ...interface{}) error { + return h.broadcast.Send(nil, h.broadcastName(room), event, args...) } -func (h *socketHandler) BroadcastTo(room, message string, args ...interface{}) error { - return h.baseHandler.broadcast.Send(h.socket, h.broadcastName(room), message, args...) +func (h *socketHandler) BroadcastTo(room, event string, args ...interface{}) error { + return h.baseHandler.broadcast.Send(h.socket, h.broadcastName(room), event, args...) } func (h *baseHandler) broadcastName(room string) string { @@ -125,6 +136,12 @@ func (h *baseHandler) broadcastName(room string) string { } func (h *socketHandler) onPacket(decoder *decoder, packet *packet) ([]interface{}, error) { + defer func() { + if decoder != nil { + decoder.Close() + } + }() + var message string switch packet.Type { case _CONNECT: @@ -134,21 +151,28 @@ func (h *socketHandler) onPacket(decoder *decoder, packet *packet) ([]interface{ case _ERROR: message = "error" case _ACK: + fallthrough case _BINARY_ACK: return nil, h.onAck(packet.Id, decoder, packet) default: - message = decoder.Message() + if decoder != nil { + message = decoder.Message() + } } + h.evMu.Lock() c, ok := h.events[message] + h.evMu.Unlock() if !ok { // If the message is not recognized by the server, the decoder.currentCloser // needs to be closed otherwise the server will be stuck until the e - decoder.Close() + if decoder != nil { + decoder.Close() + } return nil, nil } args := c.GetArgs() olen := len(args) - if olen > 0 { + if olen > 0 && decoder != nil { packet.Data = &args if err := decoder.DecodeData(packet); err != nil { return nil, err @@ -176,11 +200,14 @@ func (h *socketHandler) onPacket(decoder *decoder, packet *packet) ([]interface{ } func (h *socketHandler) onAck(id int, decoder *decoder, packet *packet) error { + h.acksmu.Lock() c, ok := h.acks[id] if !ok { + h.acksmu.Unlock() return nil } delete(h.acks, id) + h.acksmu.Unlock() args := c.GetArgs() packet.Data = &args diff --git a/vendor/github.com/googollee/go-socket.io/main.go b/vendor/github.com/googollee/go-socket.io/main.go index c3d941c76..f01ed76d0 100644 --- a/vendor/github.com/googollee/go-socket.io/main.go +++ b/vendor/github.com/googollee/go-socket.io/main.go @@ -1,6 +1,6 @@ /* -go-socket.io is the implement of socket.io in golang. +go-socket.io is a server implementation of socket.io in golang. -It is compatible with node.js implement. +It is compatible with the official Node.js implementation. */ package socketio diff --git a/vendor/github.com/googollee/go-socket.io/namespace.go b/vendor/github.com/googollee/go-socket.io/namespace.go index 7bd553a99..f2e1004e3 100644 --- a/vendor/github.com/googollee/go-socket.io/namespace.go +++ b/vendor/github.com/googollee/go-socket.io/namespace.go @@ -1,16 +1,16 @@ package socketio -// Namespace is the name space of socket.io handler. +// Namespace is the name space of a socket.io handler. type Namespace interface { - // Name returns the name of namespace. + // Name returns the name of the namespace. Name() string // Of returns the namespace with given name. Of(name string) Namespace - // On registers the function f to handle message. - On(message string, f interface{}) error + // On registers the function f to handle an event. + On(event string, f interface{}) error } type namespace struct { diff --git a/vendor/github.com/googollee/go-socket.io/parser.go b/vendor/github.com/googollee/go-socket.io/parser.go index a4c7f7b3e..8555e6d61 100644 --- a/vendor/github.com/googollee/go-socket.io/parser.go +++ b/vendor/github.com/googollee/go-socket.io/parser.go @@ -296,9 +296,7 @@ func (d *decoder) DecodeData(v *packet) error { if d.current == nil { return nil } - defer func() { - d.Close() - }() + decoder := json.NewDecoder(d.current) if err := decoder.Decode(v.Data); err != nil { return err diff --git a/vendor/github.com/googollee/go-socket.io/server.go b/vendor/github.com/googollee/go-socket.io/server.go index 946f1722f..02fd43863 100644 --- a/vendor/github.com/googollee/go-socket.io/server.go +++ b/vendor/github.com/googollee/go-socket.io/server.go @@ -13,7 +13,7 @@ type Server struct { eio *engineio.Server } -// NewServer returns the server supported given transports. If transports is nil, server will use ["polling", "websocket"] as default. +// NewServer returns the server supported given transports. If transports is nil, the server will use ["polling", "websocket"] as default. func NewServer(transportNames []string) (*Server, error) { eio, err := engineio.NewServer(transportNames) if err != nil { @@ -27,59 +27,74 @@ func NewServer(transportNames []string) (*Server, error) { return ret, nil } -// SetPingTimeout sets the timeout of ping. When time out, server will close connection. Default is 60s. +// SetPingTimeout sets the timeout of a connection ping. When it times out, the server will close the connection with the client. Default is 60s. func (s *Server) SetPingTimeout(t time.Duration) { s.eio.SetPingTimeout(t) } -// SetPingInterval sets the interval of ping. Default is 25s. +// SetPingInterval sets the interval of pings. Default is 25s. func (s *Server) SetPingInterval(t time.Duration) { s.eio.SetPingInterval(t) } -// SetMaxConnection sets the max connetion. Default is 1000. +// SetMaxConnection sets the maximum number of connections with clients. Default is 1000. func (s *Server) SetMaxConnection(n int) { s.eio.SetMaxConnection(n) } -// SetAllowRequest sets the middleware function when establish connection. If it return non-nil, connection won't be established. Default will allow all request. +// GetMaxConnection returns the current max connection +func (s *Server) GetMaxConnection() int { + return s.eio.GetMaxConnection() +} + +// Count returns the current number of connected clients in session +func (s *Server) Count() int { + return s.eio.Count() +} + +// LenRoom returns the current number of connected clients in room +func (s *Server) LenRoom(room string) int { + return s.namespace.broadcast.Len(room) +} + +// SetAllowRequest sets the middleware function when a connection is established. If a non-nil value is returned, the connection won't be established. Default will allow all connections. func (s *Server) SetAllowRequest(f func(*http.Request) error) { s.eio.SetAllowRequest(f) } -// SetAllowUpgrades sets whether server allows transport upgrade. Default is true. +// SetAllowUpgrades sets whether server allows transport upgrades. Default is true. func (s *Server) SetAllowUpgrades(allow bool) { s.eio.SetAllowUpgrades(allow) } -// SetCookie sets the name of cookie which used by engine.io. Default is "io". +// SetCookie sets the name of the cookie used by engine.io. Default is "io". func (s *Server) SetCookie(prefix string) { s.eio.SetCookie(prefix) } -// SetNewId sets the callback func to generate new connection id. By default, id is generated from remote addr + current time stamp +// SetNewId sets the callback func to generate new connection id. By default, id is generated from remote address + current time stamp func (s *Server) SetNewId(f func(*http.Request) string) { s.eio.SetNewId(f) } -// SetSessionsManager sets the sessions as server's session manager. Default sessions is single process manager. You can custom it as load balance. +// SetSessionsManager sets the sessions as server's session manager. Default sessions is a single process manager. You can customize it as a load balancer. func (s *Server) SetSessionManager(sessions engineio.Sessions) { s.eio.SetSessionManager(sessions) } -// SetAdaptor sets the adaptor of broadcast. Default is in-process broadcast implement. +// SetAdaptor sets the adaptor of broadcast. Default is an in-process broadcast implementation. func (s *Server) SetAdaptor(adaptor BroadcastAdaptor) { s.namespace = newNamespace(adaptor) } -// ServeHTTP handles http request. +// ServeHTTP handles http requests. func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { s.eio.ServeHTTP(w, r) } -// Server level broadcasts function. -func (s *Server) BroadcastTo(room, message string, args ...interface{}) { - s.namespace.BroadcastTo(room, message, args...) +// BroadcastTo is a server level broadcast function. +func (s *Server) BroadcastTo(room, event string, args ...interface{}) { + s.namespace.BroadcastTo(room, event, args...) } func (s *Server) loop() { diff --git a/vendor/github.com/googollee/go-socket.io/socket.go b/vendor/github.com/googollee/go-socket.io/socket.go index c075fa6a7..2c6fa4828 100644 --- a/vendor/github.com/googollee/go-socket.io/socket.go +++ b/vendor/github.com/googollee/go-socket.io/socket.go @@ -2,6 +2,7 @@ package socketio import ( "net/http" + "sync" "github.com/googollee/go-engine.io" ) @@ -18,11 +19,11 @@ type Socket interface { // Request returns the first http request when established connection. Request() *http.Request - // On registers the function f to handle message. - On(message string, f interface{}) error + // On registers the function f to handle an event. + On(event string, f interface{}) error - // Emit emits the message with given args. - Emit(message string, args ...interface{}) error + // Emit emits an event with given args. + Emit(event string, args ...interface{}) error // Join joins the room. Join(room string) error @@ -30,8 +31,11 @@ type Socket interface { // Leave leaves the room. Leave(room string) error - // BroadcastTo broadcasts the message to the room with given args. - BroadcastTo(room, message string, args ...interface{}) error + // Disconnect disconnect the socket. + Disconnect() + + // BroadcastTo broadcasts an event to the room with given args. + BroadcastTo(room, event string, args ...interface{}) error } type socket struct { @@ -39,6 +43,7 @@ type socket struct { conn engineio.Conn namespace string id int + mu sync.Mutex } func newSocket(conn engineio.Conn, base *baseHandler) *socket { @@ -57,16 +62,20 @@ func (s *socket) Request() *http.Request { return s.conn.Request() } -func (s *socket) Emit(message string, args ...interface{}) error { - if err := s.socketHandler.Emit(message, args...); err != nil { +func (s *socket) Emit(event string, args ...interface{}) error { + if err := s.socketHandler.Emit(event, args...); err != nil { return err } - if message == "disconnect" { + if event == "disconnect" { s.conn.Close() } return nil } +func (s *socket) Disconnect() { + s.conn.Close() +} + func (s *socket) send(args []interface{}) error { packet := packet{ Type: _EVENT, @@ -89,6 +98,7 @@ func (s *socket) sendConnect() error { } func (s *socket) sendId(args []interface{}) (int, error) { + s.mu.Lock() packet := packet{ Type: _EVENT, Id: s.id, @@ -99,6 +109,8 @@ func (s *socket) sendId(args []interface{}) (int, error) { if s.id < 0 { s.id = 0 } + s.mu.Unlock() + encoder := newEncoder(s.conn) err := encoder.Encode(packet) if err != nil { diff --git a/vendor/github.com/gorilla/websocket/AUTHORS b/vendor/github.com/gorilla/websocket/AUTHORS index b003eca0c..1931f4006 100644 --- a/vendor/github.com/gorilla/websocket/AUTHORS +++ b/vendor/github.com/gorilla/websocket/AUTHORS @@ -4,5 +4,6 @@ # Please keep the list sorted. Gary Burd +Google LLC (https://opensource.google.com/) Joachim Bauch diff --git a/vendor/github.com/gorilla/websocket/README.md b/vendor/github.com/gorilla/websocket/README.md deleted file mode 100644 index 9ad75a0f5..000000000 --- a/vendor/github.com/gorilla/websocket/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# Gorilla WebSocket - -Gorilla WebSocket is a [Go](http://golang.org/) implementation of the -[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. - -### Documentation - -* [API Reference](http://godoc.org/github.com/gorilla/websocket) -* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) -* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) - -### Status - -The Gorilla WebSocket package provides a complete and tested implementation of -the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The -package API is stable. - -### Installation - - go get github.com/gorilla/websocket - -### Protocol Compliance - -The Gorilla WebSocket package passes the server tests in the [Autobahn Test -Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn -subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). - -### Gorilla WebSocket compared with other packages - - - - - - - - - - - - - - - - - - -
github.com/gorillagolang.org/x/net
RFC 6455 Features
Passes Autobahn Test SuiteYesNo
Receive fragmented messageYesNo, see note 1
Send close messageYesNo
Send pings and receive pongsYesNo
Get the type of a received data messageYesYes, see note 2
Other Features
Limit size of received messageYesNo
Read message using io.ReaderYesNo, see note 3
Write message using io.WriteCloserYesNo, see note 3
- -Notes: - -1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). -2. The application can get the type of a received data message by implementing - a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) - function. -3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. - Read returns when the input buffer is full or a frame boundary is - encountered. Each call to Write sends a single frame message. The Gorilla - io.Reader and io.WriteCloser operate on a single WebSocket message. - diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go index c25d24f80..2e32fd506 100644 --- a/vendor/github.com/gorilla/websocket/client.go +++ b/vendor/github.com/gorilla/websocket/client.go @@ -5,10 +5,15 @@ package websocket import ( + "bytes" + "context" "crypto/tls" "errors" + "io" + "io/ioutil" "net" "net/http" + "net/http/httptrace" "net/url" "strings" "time" @@ -18,6 +23,8 @@ import ( // invalid. var ErrBadHandshake = errors.New("websocket: bad handshake") +var errInvalidCompression = errors.New("websocket: invalid compression negotiation") + // NewClient creates a new client connection using the given net connection. // The URL u specifies the host and request URI. Use requestHeader to specify // the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies @@ -27,50 +34,17 @@ var ErrBadHandshake = errors.New("websocket: bad handshake") // If the WebSocket handshake fails, ErrBadHandshake is returned along with a // non-nil *http.Response so that callers can handle redirects, authentication, // etc. +// +// Deprecated: Use Dialer instead. func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) { - challengeKey, err := generateChallengeKey() - if err != nil { - return nil, nil, err - } - acceptKey := computeAcceptKey(challengeKey) - - c = newConn(netConn, false, readBufSize, writeBufSize) - p := c.writeBuf[:0] - p = append(p, "GET "...) - p = append(p, u.RequestURI()...) - p = append(p, " HTTP/1.1\r\nHost: "...) - p = append(p, u.Host...) - // "Upgrade" is capitalized for servers that do not use case insensitive - // comparisons on header tokens. - p = append(p, "\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: "...) - p = append(p, challengeKey...) - p = append(p, "\r\n"...) - for k, vs := range requestHeader { - for _, v := range vs { - p = append(p, k...) - p = append(p, ": "...) - p = append(p, v...) - p = append(p, "\r\n"...) - } - } - p = append(p, "\r\n"...) - - if _, err := netConn.Write(p); err != nil { - return nil, nil, err - } - - resp, err := http.ReadResponse(c.br, &http.Request{Method: "GET", URL: u}) - if err != nil { - return nil, nil, err - } - if resp.StatusCode != 101 || - !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || - !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || - resp.Header.Get("Sec-Websocket-Accept") != acceptKey { - return nil, resp, ErrBadHandshake + d := Dialer{ + ReadBufferSize: readBufSize, + WriteBufferSize: writeBufSize, + NetDial: func(net, addr string) (net.Conn, error) { + return netConn, nil + }, } - c.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") - return c, resp, nil + return d.Dial(u.String(), requestHeader) } // A Dialer contains options for connecting to WebSocket server. @@ -79,6 +53,16 @@ type Dialer struct { // NetDial is nil, net.Dial is used. NetDial func(network, addr string) (net.Conn, error) + // NetDialContext specifies the dial function for creating TCP connections. If + // NetDialContext is nil, net.DialContext is used. + NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error) + + // Proxy specifies a function to return a proxy for a given + // Request. If the function returns a non-nil error, the + // request is aborted with the provided error. + // If Proxy is nil or returns a nil *URL, no proxy is used. + Proxy func(*http.Request) (*url.URL, error) + // TLSClientConfig specifies the TLS configuration to use with tls.Client. // If nil, the default configuration is used. TLSClientConfig *tls.Config @@ -86,100 +70,230 @@ type Dialer struct { // HandshakeTimeout specifies the duration for the handshake to complete. HandshakeTimeout time.Duration - // Input and output buffer sizes. If the buffer size is zero, then a - // default value of 4096 is used. + // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer + // size is zero, then a useful default size is used. The I/O buffer sizes + // do not limit the size of the messages that can be sent or received. ReadBufferSize, WriteBufferSize int + // WriteBufferPool is a pool of buffers for write operations. If the value + // is not set, then write buffers are allocated to the connection for the + // lifetime of the connection. + // + // A pool is most useful when the application has a modest volume of writes + // across a large number of connections. + // + // Applications should use a single pool for each unique value of + // WriteBufferSize. + WriteBufferPool BufferPool + // Subprotocols specifies the client's requested subprotocols. Subprotocols []string -} - -var errMalformedURL = errors.New("malformed ws or wss URL") -// parseURL parses the URL. The url.Parse function is not used here because -// url.Parse mangles the path. -func parseURL(s string) (*url.URL, error) { - // From the RFC: - // - // ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ] - // wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ] - // - // We don't use the net/url parser here because the dialer interface does - // not provide a way for applications to work around percent deocding in - // the net/url parser. - - var u url.URL - switch { - case strings.HasPrefix(s, "ws://"): - u.Scheme = "ws" - s = s[len("ws://"):] - case strings.HasPrefix(s, "wss://"): - u.Scheme = "wss" - s = s[len("wss://"):] - default: - return nil, errMalformedURL - } + // EnableCompression specifies if the client should attempt to negotiate + // per message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool - u.Host = s - u.Opaque = "/" - if i := strings.Index(s, "/"); i >= 0 { - u.Host = s[:i] - u.Opaque = s[i:] - } + // Jar specifies the cookie jar. + // If Jar is nil, cookies are not sent in requests and ignored + // in responses. + Jar http.CookieJar +} - return &u, nil +// Dial creates a new client connection by calling DialContext with a background context. +func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { + return d.DialContext(context.Background(), urlStr, requestHeader) } +var errMalformedURL = errors.New("malformed ws or wss URL") + func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { hostPort = u.Host hostNoPort = u.Host if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") { hostNoPort = hostNoPort[:i] } else { - if u.Scheme == "wss" { + switch u.Scheme { + case "wss": hostPort += ":443" - } else { + case "https": + hostPort += ":443" + default: hostPort += ":80" } } return hostPort, hostNoPort } -// DefaultDialer is a dialer with all fields set to the default zero values. -var DefaultDialer *Dialer +// DefaultDialer is a dialer with all fields set to the default values. +var DefaultDialer = &Dialer{ + Proxy: http.ProxyFromEnvironment, + HandshakeTimeout: 45 * time.Second, +} + +// nilDialer is dialer to use when receiver is nil. +var nilDialer = *DefaultDialer -// Dial creates a new client connection. Use requestHeader to specify the +// DialContext creates a new client connection. Use requestHeader to specify the // origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie). // Use the response.Header to get the selected subprotocol // (Sec-WebSocket-Protocol) and cookies (Set-Cookie). // +// The context will be used in the request and in the Dialer +// // If the WebSocket handshake fails, ErrBadHandshake is returned along with a // non-nil *http.Response so that callers can handle redirects, authentication, -// etc. -func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { - u, err := parseURL(urlStr) +// etcetera. The response body may not contain the entire response and does not +// need to be closed by the application. +func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { + if d == nil { + d = &nilDialer + } + + challengeKey, err := generateChallengeKey() if err != nil { return nil, nil, err } - hostPort, hostNoPort := hostPortNoPort(u) + u, err := url.Parse(urlStr) + if err != nil { + return nil, nil, err + } - if d == nil { - d = &Dialer{} + switch u.Scheme { + case "ws": + u.Scheme = "http" + case "wss": + u.Scheme = "https" + default: + return nil, nil, errMalformedURL + } + + if u.User != nil { + // User name and password are not allowed in websocket URIs. + return nil, nil, errMalformedURL + } + + req := &http.Request{ + Method: "GET", + URL: u, + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Header: make(http.Header), + Host: u.Host, + } + req = req.WithContext(ctx) + + // Set the cookies present in the cookie jar of the dialer + if d.Jar != nil { + for _, cookie := range d.Jar.Cookies(u) { + req.AddCookie(cookie) + } + } + + // Set the request headers using the capitalization for names and values in + // RFC examples. Although the capitalization shouldn't matter, there are + // servers that depend on it. The Header.Set method is not used because the + // method canonicalizes the header names. + req.Header["Upgrade"] = []string{"websocket"} + req.Header["Connection"] = []string{"Upgrade"} + req.Header["Sec-WebSocket-Key"] = []string{challengeKey} + req.Header["Sec-WebSocket-Version"] = []string{"13"} + if len(d.Subprotocols) > 0 { + req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")} + } + for k, vs := range requestHeader { + switch { + case k == "Host": + if len(vs) > 0 { + req.Host = vs[0] + } + case k == "Upgrade" || + k == "Connection" || + k == "Sec-Websocket-Key" || + k == "Sec-Websocket-Version" || + k == "Sec-Websocket-Extensions" || + (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0): + return nil, nil, errors.New("websocket: duplicate header not allowed: " + k) + case k == "Sec-Websocket-Protocol": + req.Header["Sec-WebSocket-Protocol"] = vs + default: + req.Header[k] = vs + } + } + + if d.EnableCompression { + req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"} } - var deadline time.Time if d.HandshakeTimeout != 0 { - deadline = time.Now().Add(d.HandshakeTimeout) + var cancel func() + ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout) + defer cancel() + } + + // Get network dial function. + var netDial func(network, add string) (net.Conn, error) + + if d.NetDialContext != nil { + netDial = func(network, addr string) (net.Conn, error) { + return d.NetDialContext(ctx, network, addr) + } + } else if d.NetDial != nil { + netDial = d.NetDial + } else { + netDialer := &net.Dialer{} + netDial = func(network, addr string) (net.Conn, error) { + return netDialer.DialContext(ctx, network, addr) + } } - netDial := d.NetDial - if netDial == nil { - netDialer := &net.Dialer{Deadline: deadline} - netDial = netDialer.Dial + // If needed, wrap the dial function to set the connection deadline. + if deadline, ok := ctx.Deadline(); ok { + forwardDial := netDial + netDial = func(network, addr string) (net.Conn, error) { + c, err := forwardDial(network, addr) + if err != nil { + return nil, err + } + err = c.SetDeadline(deadline) + if err != nil { + c.Close() + return nil, err + } + return c, nil + } + } + + // If needed, wrap the dial function to connect through a proxy. + if d.Proxy != nil { + proxyURL, err := d.Proxy(req) + if err != nil { + return nil, nil, err + } + if proxyURL != nil { + dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial)) + if err != nil { + return nil, nil, err + } + netDial = dialer.Dial + } + } + + hostPort, hostNoPort := hostPortNoPort(u) + trace := httptrace.ContextClientTrace(ctx) + if trace != nil && trace.GetConn != nil { + trace.GetConn(hostPort) } netConn, err := netDial("tcp", hostPort) + if trace != nil && trace.GotConn != nil { + trace.GotConn(httptrace.GotConnInfo{ + Conn: netConn, + }) + } if err != nil { return nil, nil, err } @@ -190,46 +304,92 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re } }() - if err := netConn.SetDeadline(deadline); err != nil { - return nil, nil, err - } - - if u.Scheme == "wss" { - cfg := d.TLSClientConfig - if cfg == nil { - cfg = &tls.Config{ServerName: hostNoPort} - } else if cfg.ServerName == "" { - shallowCopy := *cfg - cfg = &shallowCopy + if u.Scheme == "https" { + cfg := cloneTLSConfig(d.TLSClientConfig) + if cfg.ServerName == "" { cfg.ServerName = hostNoPort } tlsConn := tls.Client(netConn, cfg) netConn = tlsConn - if err := tlsConn.Handshake(); err != nil { - return nil, nil, err + + var err error + if trace != nil { + err = doHandshakeWithTrace(trace, tlsConn, cfg) + } else { + err = doHandshake(tlsConn, cfg) } - if !cfg.InsecureSkipVerify { - if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { - return nil, nil, err - } + + if err != nil { + return nil, nil, err } } - if len(d.Subprotocols) > 0 { - h := http.Header{} - for k, v := range requestHeader { - h[k] = v + conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil) + + if err := req.Write(netConn); err != nil { + return nil, nil, err + } + + if trace != nil && trace.GotFirstResponseByte != nil { + if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 { + trace.GotFirstResponseByte() } - h.Set("Sec-Websocket-Protocol", strings.Join(d.Subprotocols, ", ")) - requestHeader = h } - conn, resp, err := NewClient(netConn, u, requestHeader, d.ReadBufferSize, d.WriteBufferSize) + resp, err := http.ReadResponse(conn.br, req) if err != nil { - return nil, resp, err + return nil, nil, err } + if d.Jar != nil { + if rc := resp.Cookies(); len(rc) > 0 { + d.Jar.SetCookies(u, rc) + } + } + + if resp.StatusCode != 101 || + !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || + !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || + resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) { + // Before closing the network connection on return from this + // function, slurp up some of the response to aid application + // debugging. + buf := make([]byte, 1024) + n, _ := io.ReadFull(resp.Body, buf) + resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n])) + return nil, resp, ErrBadHandshake + } + + for _, ext := range parseExtensions(resp.Header) { + if ext[""] != "permessage-deflate" { + continue + } + _, snct := ext["server_no_context_takeover"] + _, cnct := ext["client_no_context_takeover"] + if !snct || !cnct { + return nil, resp, errInvalidCompression + } + conn.newCompressionWriter = compressNoContextTakeover + conn.newDecompressionReader = decompressNoContextTakeover + break + } + + resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) + conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") + netConn.SetDeadline(time.Time{}) netConn = nil // to avoid close in defer. return conn, resp, nil } + +func doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error { + if err := tlsConn.Handshake(); err != nil { + return err + } + if !cfg.InsecureSkipVerify { + if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/gorilla/websocket/client_clone.go b/vendor/github.com/gorilla/websocket/client_clone.go new file mode 100644 index 000000000..4f0d94372 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client_clone.go @@ -0,0 +1,16 @@ +// Copyright 2013 The Gorilla WebSocket 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.8 + +package websocket + +import "crypto/tls" + +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return cfg.Clone() +} diff --git a/vendor/github.com/gorilla/websocket/client_clone_legacy.go b/vendor/github.com/gorilla/websocket/client_clone_legacy.go new file mode 100644 index 000000000..babb007fb --- /dev/null +++ b/vendor/github.com/gorilla/websocket/client_clone_legacy.go @@ -0,0 +1,38 @@ +// Copyright 2013 The Gorilla WebSocket 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.8 + +package websocket + +import "crypto/tls" + +// cloneTLSConfig clones all public fields except the fields +// SessionTicketsDisabled and SessionTicketKey. This avoids copying the +// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a +// config in active use. +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return &tls.Config{ + Rand: cfg.Rand, + Time: cfg.Time, + Certificates: cfg.Certificates, + NameToCertificate: cfg.NameToCertificate, + GetCertificate: cfg.GetCertificate, + RootCAs: cfg.RootCAs, + NextProtos: cfg.NextProtos, + ServerName: cfg.ServerName, + ClientAuth: cfg.ClientAuth, + ClientCAs: cfg.ClientCAs, + InsecureSkipVerify: cfg.InsecureSkipVerify, + CipherSuites: cfg.CipherSuites, + PreferServerCipherSuites: cfg.PreferServerCipherSuites, + ClientSessionCache: cfg.ClientSessionCache, + MinVersion: cfg.MinVersion, + MaxVersion: cfg.MaxVersion, + CurvePreferences: cfg.CurvePreferences, + } +} diff --git a/vendor/github.com/gorilla/websocket/compression.go b/vendor/github.com/gorilla/websocket/compression.go new file mode 100644 index 000000000..813ffb1e8 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/compression.go @@ -0,0 +1,148 @@ +// Copyright 2017 The Gorilla WebSocket 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 websocket + +import ( + "compress/flate" + "errors" + "io" + "strings" + "sync" +) + +const ( + minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6 + maxCompressionLevel = flate.BestCompression + defaultCompressionLevel = 1 +) + +var ( + flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool + flateReaderPool = sync.Pool{New: func() interface{} { + return flate.NewReader(nil) + }} +) + +func decompressNoContextTakeover(r io.Reader) io.ReadCloser { + const tail = + // Add four bytes as specified in RFC + "\x00\x00\xff\xff" + + // Add final block to squelch unexpected EOF error from flate reader. + "\x01\x00\x00\xff\xff" + + fr, _ := flateReaderPool.Get().(io.ReadCloser) + fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) + return &flateReadWrapper{fr} +} + +func isValidCompressionLevel(level int) bool { + return minCompressionLevel <= level && level <= maxCompressionLevel +} + +func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { + p := &flateWriterPools[level-minCompressionLevel] + tw := &truncWriter{w: w} + fw, _ := p.Get().(*flate.Writer) + if fw == nil { + fw, _ = flate.NewWriter(tw, level) + } else { + fw.Reset(tw) + } + return &flateWriteWrapper{fw: fw, tw: tw, p: p} +} + +// truncWriter is an io.Writer that writes all but the last four bytes of the +// stream to another io.Writer. +type truncWriter struct { + w io.WriteCloser + n int + p [4]byte +} + +func (w *truncWriter) Write(p []byte) (int, error) { + n := 0 + + // fill buffer first for simplicity. + if w.n < len(w.p) { + n = copy(w.p[w.n:], p) + p = p[n:] + w.n += n + if len(p) == 0 { + return n, nil + } + } + + m := len(p) + if m > len(w.p) { + m = len(w.p) + } + + if nn, err := w.w.Write(w.p[:m]); err != nil { + return n + nn, err + } + + copy(w.p[:], w.p[m:]) + copy(w.p[len(w.p)-m:], p[len(p)-m:]) + nn, err := w.w.Write(p[:len(p)-m]) + return n + nn, err +} + +type flateWriteWrapper struct { + fw *flate.Writer + tw *truncWriter + p *sync.Pool +} + +func (w *flateWriteWrapper) Write(p []byte) (int, error) { + if w.fw == nil { + return 0, errWriteClosed + } + return w.fw.Write(p) +} + +func (w *flateWriteWrapper) Close() error { + if w.fw == nil { + return errWriteClosed + } + err1 := w.fw.Flush() + w.p.Put(w.fw) + w.fw = nil + if w.tw.p != [4]byte{0, 0, 0xff, 0xff} { + return errors.New("websocket: internal error, unexpected bytes at end of flate stream") + } + err2 := w.tw.w.Close() + if err1 != nil { + return err1 + } + return err2 +} + +type flateReadWrapper struct { + fr io.ReadCloser +} + +func (r *flateReadWrapper) Read(p []byte) (int, error) { + if r.fr == nil { + return 0, io.ErrClosedPipe + } + n, err := r.fr.Read(p) + if err == io.EOF { + // Preemptively place the reader back in the pool. This helps with + // scenarios where the application does not call NextReader() soon after + // this final read. + r.Close() + } + return n, err +} + +func (r *flateReadWrapper) Close() error { + if r.fr == nil { + return io.ErrClosedPipe + } + err := r.fr.Close() + flateReaderPool.Put(r.fr) + r.fr = nil + return err +} diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go index 86c35e5fc..d2a21c148 100644 --- a/vendor/github.com/gorilla/websocket/conn.go +++ b/vendor/github.com/gorilla/websocket/conn.go @@ -13,15 +13,25 @@ import ( "math/rand" "net" "strconv" + "sync" "time" + "unicode/utf8" ) const ( + // Frame header byte 0 bits from Section 5.2 of RFC 6455 + finalBit = 1 << 7 + rsv1Bit = 1 << 6 + rsv2Bit = 1 << 5 + rsv3Bit = 1 << 4 + + // Frame header byte 1 bits from Section 5.2 of RFC 6455 + maskBit = 1 << 7 + maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask maxControlFramePayloadSize = 125 - finalBit = 1 << 7 - maskBit = 1 << 7 - writeWait = time.Second + + writeWait = time.Second defaultReadBufferSize = 4096 defaultWriteBufferSize = 4096 @@ -43,6 +53,8 @@ const ( CloseMessageTooBig = 1009 CloseMandatoryExtension = 1010 CloseInternalServerErr = 1011 + CloseServiceRestart = 1012 + CloseTryAgainLater = 1013 CloseTLSHandshake = 1015 ) @@ -64,7 +76,7 @@ const ( // is UTF-8 encoded text. PingMessage = 9 - // PongMessage denotes a ping control message. The optional message payload + // PongMessage denotes a pong control message. The optional message payload // is UTF-8 encoded text. PongMessage = 10 ) @@ -88,24 +100,91 @@ func (e *netError) Error() string { return e.msg } func (e *netError) Temporary() bool { return e.temporary } func (e *netError) Timeout() bool { return e.timeout } -// closeError represents close frame. -type closeError struct { - code int - text string +// CloseError represents a close message. +type CloseError struct { + // Code is defined in RFC 6455, section 11.7. + Code int + + // Text is the optional text payload. + Text string +} + +func (e *CloseError) Error() string { + s := []byte("websocket: close ") + s = strconv.AppendInt(s, int64(e.Code), 10) + switch e.Code { + case CloseNormalClosure: + s = append(s, " (normal)"...) + case CloseGoingAway: + s = append(s, " (going away)"...) + case CloseProtocolError: + s = append(s, " (protocol error)"...) + case CloseUnsupportedData: + s = append(s, " (unsupported data)"...) + case CloseNoStatusReceived: + s = append(s, " (no status)"...) + case CloseAbnormalClosure: + s = append(s, " (abnormal closure)"...) + case CloseInvalidFramePayloadData: + s = append(s, " (invalid payload data)"...) + case ClosePolicyViolation: + s = append(s, " (policy violation)"...) + case CloseMessageTooBig: + s = append(s, " (message too big)"...) + case CloseMandatoryExtension: + s = append(s, " (mandatory extension missing)"...) + case CloseInternalServerErr: + s = append(s, " (internal server error)"...) + case CloseTLSHandshake: + s = append(s, " (TLS handshake error)"...) + } + if e.Text != "" { + s = append(s, ": "...) + s = append(s, e.Text...) + } + return string(s) } -func (e *closeError) Error() string { - return "websocket: close " + strconv.Itoa(e.code) + " " + e.text +// IsCloseError returns boolean indicating whether the error is a *CloseError +// with one of the specified codes. +func IsCloseError(err error, codes ...int) bool { + if e, ok := err.(*CloseError); ok { + for _, code := range codes { + if e.Code == code { + return true + } + } + } + return false +} + +// IsUnexpectedCloseError returns boolean indicating whether the error is a +// *CloseError with a code not in the list of expected codes. +func IsUnexpectedCloseError(err error, expectedCodes ...int) bool { + if e, ok := err.(*CloseError); ok { + for _, code := range expectedCodes { + if e.Code == code { + return false + } + } + return true + } + return false } var ( - errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true} - errUnexpectedEOF = &closeError{code: CloseAbnormalClosure, text: io.ErrUnexpectedEOF.Error()} + errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true} + errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()} errBadWriteOpCode = errors.New("websocket: bad write message type") errWriteClosed = errors.New("websocket: write closed") errInvalidControlFrame = errors.New("websocket: invalid control frame") ) +func newMaskKey() [4]byte { + n := rand.Uint32() + return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} +} + func hideTempErr(err error) error { if e, ok := err.(net.Error); ok && e.Temporary() { err = &netError{msg: e.Error(), timeout: e.Timeout()} @@ -121,72 +200,121 @@ func isData(frameType int) bool { return frameType == TextMessage || frameType == BinaryMessage } -func maskBytes(key [4]byte, pos int, b []byte) int { - for i := range b { - b[i] ^= key[pos&3] - pos++ - } - return pos & 3 +var validReceivedCloseCodes = map[int]bool{ + // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number + + CloseNormalClosure: true, + CloseGoingAway: true, + CloseProtocolError: true, + CloseUnsupportedData: true, + CloseNoStatusReceived: false, + CloseAbnormalClosure: false, + CloseInvalidFramePayloadData: true, + ClosePolicyViolation: true, + CloseMessageTooBig: true, + CloseMandatoryExtension: true, + CloseInternalServerErr: true, + CloseServiceRestart: true, + CloseTryAgainLater: true, + CloseTLSHandshake: false, } -func newMaskKey() [4]byte { - n := rand.Uint32() - return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} +func isValidReceivedCloseCode(code int) bool { + return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999) +} + +// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this +// interface. The type of the value stored in a pool is not specified. +type BufferPool interface { + // Get gets a value from the pool or returns nil if the pool is empty. + Get() interface{} + // Put adds a value to the pool. + Put(interface{}) } -// Conn represents a WebSocket connection. +// writePoolData is the type added to the write buffer pool. This wrapper is +// used to prevent applications from peeking at and depending on the values +// added to the pool. +type writePoolData struct{ buf []byte } + +// The Conn type represents a WebSocket connection. type Conn struct { conn net.Conn isServer bool subprotocol string // Write fields - mu chan bool // used as mutex to protect write to conn and closeSent - closeSent bool // true if close message was sent + mu chan bool // used as mutex to protect write to conn + writeBuf []byte // frame is constructed in this buffer. + writePool BufferPool + writeBufSize int + writeDeadline time.Time + writer io.WriteCloser // the current writer returned to the application + isWriting bool // for best-effort concurrent write detection + + writeErrMu sync.Mutex + writeErr error - // Message writer fields. - writeErr error - writeBuf []byte // frame is constructed in this buffer. - writePos int // end of data in writeBuf. - writeFrameType int // type of the current frame. - writeSeq int // incremented to invalidate message writers. - writeDeadline time.Time + enableWriteCompression bool + compressionLevel int + newCompressionWriter func(io.WriteCloser, int) io.WriteCloser // Read fields + reader io.ReadCloser // the current reader returned to the application readErr error br *bufio.Reader readRemaining int64 // bytes remaining in current frame. readFinal bool // true the current message has more frames. - readSeq int // incremented to invalidate message readers. readLength int64 // Message size. readLimit int64 // Maximum message size. readMaskPos int readMaskKey [4]byte handlePong func(string) error handlePing func(string) error + handleClose func(int, string) error + readErrCount int + messageReader *messageReader // the current low-level reader + + readDecompress bool // whether last read frame had RSV1 set + newDecompressionReader func(io.Reader) io.ReadCloser } -func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn { - mu := make(chan bool, 1) - mu <- true +func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn { - if readBufferSize == 0 { - readBufferSize = defaultReadBufferSize + if br == nil { + if readBufferSize == 0 { + readBufferSize = defaultReadBufferSize + } else if readBufferSize < maxControlFramePayloadSize { + // must be large enough for control frame + readBufferSize = maxControlFramePayloadSize + } + br = bufio.NewReaderSize(conn, readBufferSize) } - if writeBufferSize == 0 { + + if writeBufferSize <= 0 { writeBufferSize = defaultWriteBufferSize } + writeBufferSize += maxFrameHeaderSize + if writeBuf == nil && writeBufferPool == nil { + writeBuf = make([]byte, writeBufferSize) + } + + mu := make(chan bool, 1) + mu <- true c := &Conn{ - isServer: isServer, - br: bufio.NewReaderSize(conn, readBufferSize), - conn: conn, - mu: mu, - readFinal: true, - writeBuf: make([]byte, writeBufferSize+maxFrameHeaderSize), - writeFrameType: noFrame, - writePos: maxFrameHeaderSize, + isServer: isServer, + br: br, + conn: conn, + mu: mu, + readFinal: true, + writeBuf: writeBuf, + writePool: writeBufferPool, + writeBufSize: writeBufferSize, + enableWriteCompression: true, + compressionLevel: defaultCompressionLevel, } + c.SetCloseHandler(nil) c.SetPingHandler(nil) c.SetPongHandler(nil) return c @@ -197,7 +325,8 @@ func (c *Conn) Subprotocol() string { return c.subprotocol } -// Close closes the underlying network connection without sending or waiting for a close frame. +// Close closes the underlying network connection without sending or waiting +// for a close message. func (c *Conn) Close() error { return c.conn.Close() } @@ -214,28 +343,47 @@ func (c *Conn) RemoteAddr() net.Addr { // Write methods -func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error { +func (c *Conn) writeFatal(err error) error { + err = hideTempErr(err) + c.writeErrMu.Lock() + if c.writeErr == nil { + c.writeErr = err + } + c.writeErrMu.Unlock() + return err +} + +func (c *Conn) read(n int) ([]byte, error) { + p, err := c.br.Peek(n) + if err == io.EOF { + err = errUnexpectedEOF + } + c.br.Discard(len(p)) + return p, err +} + +func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error { <-c.mu defer func() { c.mu <- true }() - if c.closeSent { - return ErrCloseSent - } else if frameType == CloseMessage { - c.closeSent = true + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err } c.conn.SetWriteDeadline(deadline) - for _, buf := range bufs { - if len(buf) > 0 { - n, err := c.conn.Write(buf) - if n != len(buf) { - // Close on partial write. - c.conn.Close() - } - if err != nil { - return err - } - } + if len(buf1) == 0 { + _, err = c.conn.Write(buf0) + } else { + err = c.writeBufs(buf0, buf1) + } + if err != nil { + return c.writeFatal(err) + } + if frameType == CloseMessage { + c.writeFatal(ErrCloseSent) } return nil } @@ -285,63 +433,119 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er } defer func() { c.mu <- true }() - if c.closeSent { - return ErrCloseSent - } else if messageType == CloseMessage { - c.closeSent = true + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err } c.conn.SetWriteDeadline(deadline) - n, err := c.conn.Write(buf) - if n != 0 && n != len(buf) { - c.conn.Close() + _, err = c.conn.Write(buf) + if err != nil { + return c.writeFatal(err) + } + if messageType == CloseMessage { + c.writeFatal(ErrCloseSent) } return err } -// NextWriter returns a writer for the next message to send. The writer's -// Close method flushes the complete message to the network. +func (c *Conn) prepWrite(messageType int) error { + // Close previous writer if not already closed by the application. It's + // probably better to return an error in this situation, but we cannot + // change this without breaking existing applications. + if c.writer != nil { + c.writer.Close() + c.writer = nil + } + + if !isControl(messageType) && !isData(messageType) { + return errBadWriteOpCode + } + + c.writeErrMu.Lock() + err := c.writeErr + c.writeErrMu.Unlock() + if err != nil { + return err + } + + if c.writeBuf == nil { + wpd, ok := c.writePool.Get().(writePoolData) + if ok { + c.writeBuf = wpd.buf + } else { + c.writeBuf = make([]byte, c.writeBufSize) + } + } + return nil +} + +// NextWriter returns a writer for the next message to send. The writer's Close +// method flushes the complete message to the network. // // There can be at most one open writer on a connection. NextWriter closes the // previous writer if the application has not already done so. // -// The NextWriter method and the writers returned from the method cannot be -// accessed by more than one goroutine at a time. +// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and +// PongMessage) are supported. func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) { - if c.writeErr != nil { - return nil, c.writeErr + if err := c.prepWrite(messageType); err != nil { + return nil, err } - if c.writeFrameType != noFrame { - if err := c.flushFrame(true, nil); err != nil { - return nil, err - } + mw := &messageWriter{ + c: c, + frameType: messageType, + pos: maxFrameHeaderSize, } - - if !isControl(messageType) && !isData(messageType) { - return nil, errBadWriteOpCode + c.writer = mw + if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) { + w := c.newCompressionWriter(c.writer, c.compressionLevel) + mw.compress = true + c.writer = w } + return c.writer, nil +} + +type messageWriter struct { + c *Conn + compress bool // whether next call to flushFrame should set RSV1 + pos int // end of data in writeBuf. + frameType int // type of the current frame. + err error +} - c.writeFrameType = messageType - return messageWriter{c, c.writeSeq}, nil +func (w *messageWriter) fatal(err error) error { + if w.err != nil { + w.err = err + w.c.writer = nil + } + return err } -func (c *Conn) flushFrame(final bool, extra []byte) error { - length := c.writePos - maxFrameHeaderSize + len(extra) +// flushFrame writes buffered data and extra as a frame to the network. The +// final argument indicates that this is the last frame in the message. +func (w *messageWriter) flushFrame(final bool, extra []byte) error { + c := w.c + length := w.pos - maxFrameHeaderSize + len(extra) // Check for invalid control frames. - if isControl(c.writeFrameType) && + if isControl(w.frameType) && (!final || length > maxControlFramePayloadSize) { - c.writeSeq++ - c.writeFrameType = noFrame - c.writePos = maxFrameHeaderSize - return errInvalidControlFrame + return w.fatal(errInvalidControlFrame) } - b0 := byte(c.writeFrameType) + b0 := byte(w.frameType) if final { b0 |= finalBit } + if w.compress { + b0 |= rsv1Bit + } + w.compress = false + b1 := byte(0) if !c.isServer { b1 |= maskBit @@ -373,49 +577,54 @@ func (c *Conn) flushFrame(final bool, extra []byte) error { if !c.isServer { key := newMaskKey() copy(c.writeBuf[maxFrameHeaderSize-4:], key[:]) - maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:c.writePos]) + maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos]) if len(extra) > 0 { - c.writeErr = errors.New("websocket: internal error, extra used in client mode") - return c.writeErr + return c.writeFatal(errors.New("websocket: internal error, extra used in client mode")) } } - // Write the buffers to the connection. - c.writeErr = c.write(c.writeFrameType, c.writeDeadline, c.writeBuf[framePos:c.writePos], extra) + // Write the buffers to the connection with best-effort detection of + // concurrent writes. See the concurrency section in the package + // documentation for more info. - // Setup for next frame. - c.writePos = maxFrameHeaderSize - c.writeFrameType = continuationFrame - if final { - c.writeSeq++ - c.writeFrameType = noFrame + if c.isWriting { + panic("concurrent write to websocket connection") } - return c.writeErr -} + c.isWriting = true -type messageWriter struct { - c *Conn - seq int -} + err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra) -func (w messageWriter) err() error { - c := w.c - if c.writeSeq != w.seq { - return errWriteClosed + if !c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = false + + if err != nil { + return w.fatal(err) } - if c.writeErr != nil { - return c.writeErr + + if final { + c.writer = nil + if c.writePool != nil { + c.writePool.Put(writePoolData{buf: c.writeBuf}) + c.writeBuf = nil + } + return nil } + + // Setup for next frame. + w.pos = maxFrameHeaderSize + w.frameType = continuationFrame return nil } -func (w messageWriter) ncopy(max int) (int, error) { - n := len(w.c.writeBuf) - w.c.writePos +func (w *messageWriter) ncopy(max int) (int, error) { + n := len(w.c.writeBuf) - w.pos if n <= 0 { - if err := w.c.flushFrame(false, nil); err != nil { + if err := w.flushFrame(false, nil); err != nil { return 0, err } - n = len(w.c.writeBuf) - w.c.writePos + n = len(w.c.writeBuf) - w.pos } if n > max { n = max @@ -423,14 +632,14 @@ func (w messageWriter) ncopy(max int) (int, error) { return n, nil } -func (w messageWriter) write(final bool, p []byte) (int, error) { - if err := w.err(); err != nil { - return 0, err +func (w *messageWriter) Write(p []byte) (int, error) { + if w.err != nil { + return 0, w.err } if len(p) > 2*len(w.c.writeBuf) && w.c.isServer { // Don't buffer large messages. - err := w.c.flushFrame(final, p) + err := w.flushFrame(false, p) if err != nil { return 0, err } @@ -443,20 +652,16 @@ func (w messageWriter) write(final bool, p []byte) (int, error) { if err != nil { return 0, err } - copy(w.c.writeBuf[w.c.writePos:], p[:n]) - w.c.writePos += n + copy(w.c.writeBuf[w.pos:], p[:n]) + w.pos += n p = p[n:] } return nn, nil } -func (w messageWriter) Write(p []byte) (int, error) { - return w.write(false, p) -} - -func (w messageWriter) WriteString(p string) (int, error) { - if err := w.err(); err != nil { - return 0, err +func (w *messageWriter) WriteString(p string) (int, error) { + if w.err != nil { + return 0, w.err } nn := len(p) @@ -465,27 +670,27 @@ func (w messageWriter) WriteString(p string) (int, error) { if err != nil { return 0, err } - copy(w.c.writeBuf[w.c.writePos:], p[:n]) - w.c.writePos += n + copy(w.c.writeBuf[w.pos:], p[:n]) + w.pos += n p = p[n:] } return nn, nil } -func (w messageWriter) ReadFrom(r io.Reader) (nn int64, err error) { - if err := w.err(); err != nil { - return 0, err +func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) { + if w.err != nil { + return 0, w.err } for { - if w.c.writePos == len(w.c.writeBuf) { - err = w.c.flushFrame(false, nil) + if w.pos == len(w.c.writeBuf) { + err = w.flushFrame(false, nil) if err != nil { break } } var n int - n, err = r.Read(w.c.writeBuf[w.c.writePos:]) - w.c.writePos += n + n, err = r.Read(w.c.writeBuf[w.pos:]) + w.pos += n nn += int64(n) if err != nil { if err == io.EOF { @@ -497,30 +702,64 @@ func (w messageWriter) ReadFrom(r io.Reader) (nn int64, err error) { return nn, err } -func (w messageWriter) Close() error { - if err := w.err(); err != nil { +func (w *messageWriter) Close() error { + if w.err != nil { + return w.err + } + if err := w.flushFrame(true, nil); err != nil { return err } - return w.c.flushFrame(true, nil) + w.err = errWriteClosed + return nil +} + +// WritePreparedMessage writes prepared message into connection. +func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error { + frameType, frameData, err := pm.frame(prepareKey{ + isServer: c.isServer, + compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType), + compressionLevel: c.compressionLevel, + }) + if err != nil { + return err + } + if c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = true + err = c.write(frameType, c.writeDeadline, frameData, nil) + if !c.isWriting { + panic("concurrent write to websocket connection") + } + c.isWriting = false + return err } // WriteMessage is a helper method for getting a writer using NextWriter, // writing the message and closing the writer. func (c *Conn) WriteMessage(messageType int, data []byte) error { - wr, err := c.NextWriter(messageType) + + if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) { + // Fast path with no allocations and single frame. + + if err := c.prepWrite(messageType); err != nil { + return err + } + mw := messageWriter{c: c, frameType: messageType, pos: maxFrameHeaderSize} + n := copy(c.writeBuf[mw.pos:], data) + mw.pos += n + data = data[n:] + return mw.flushFrame(true, data) + } + + w, err := c.NextWriter(messageType) if err != nil { return err } - w := wr.(messageWriter) - if _, err := w.write(true, data); err != nil { + if _, err = w.Write(data); err != nil { return err } - if c.writeSeq == w.seq { - if err := c.flushFrame(true, nil); err != nil { - return err - } - } - return nil + return w.Close() } // SetWriteDeadline sets the write deadline on the underlying network @@ -534,24 +773,7 @@ func (c *Conn) SetWriteDeadline(t time.Time) error { // Read methods -// readFull is like io.ReadFull except that io.EOF is never returned. -func (c *Conn) readFull(p []byte) (err error) { - var n int - for n < len(p) && err == nil { - var nn int - nn, err = c.br.Read(p[n:]) - n += nn - } - if n == len(p) { - err = nil - } else if err == io.EOF { - err = errUnexpectedEOF - } - return -} - func (c *Conn) advanceFrame() (int, error) { - // 1. Skip remainder of previous frame. if c.readRemaining > 0 { @@ -562,19 +784,24 @@ func (c *Conn) advanceFrame() (int, error) { // 2. Read and parse first two bytes of frame header. - var b [8]byte - if err := c.readFull(b[:2]); err != nil { + p, err := c.read(2) + if err != nil { return noFrame, err } - final := b[0]&finalBit != 0 - frameType := int(b[0] & 0xf) - reserved := int((b[0] >> 4) & 0x7) - mask := b[1]&maskBit != 0 - c.readRemaining = int64(b[1] & 0x7f) + final := p[0]&finalBit != 0 + frameType := int(p[0] & 0xf) + mask := p[1]&maskBit != 0 + c.readRemaining = int64(p[1] & 0x7f) - if reserved != 0 { - return noFrame, c.handleProtocolError("unexpected reserved bits " + strconv.Itoa(reserved)) + c.readDecompress = false + if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 { + c.readDecompress = true + p[0] &^= rsv1Bit + } + + if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 { + return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16)) } switch frameType { @@ -603,15 +830,17 @@ func (c *Conn) advanceFrame() (int, error) { switch c.readRemaining { case 126: - if err := c.readFull(b[:2]); err != nil { + p, err := c.read(2) + if err != nil { return noFrame, err } - c.readRemaining = int64(binary.BigEndian.Uint16(b[:2])) + c.readRemaining = int64(binary.BigEndian.Uint16(p)) case 127: - if err := c.readFull(b[:8]); err != nil { + p, err := c.read(8) + if err != nil { return noFrame, err } - c.readRemaining = int64(binary.BigEndian.Uint64(b[:8])) + c.readRemaining = int64(binary.BigEndian.Uint64(p)) } // 4. Handle frame masking. @@ -622,9 +851,11 @@ func (c *Conn) advanceFrame() (int, error) { if mask { c.readMaskPos = 0 - if err := c.readFull(c.readMaskKey[:]); err != nil { + p, err := c.read(len(c.readMaskKey)) + if err != nil { return noFrame, err } + copy(c.readMaskKey[:], p) } // 5. For text and binary messages, enforce read limit and return. @@ -644,9 +875,9 @@ func (c *Conn) advanceFrame() (int, error) { var payload []byte if c.readRemaining > 0 { - payload = make([]byte, c.readRemaining) + payload, err = c.read(int(c.readRemaining)) c.readRemaining = 0 - if err := c.readFull(payload); err != nil { + if err != nil { return noFrame, err } if c.isServer { @@ -666,19 +897,22 @@ func (c *Conn) advanceFrame() (int, error) { return noFrame, err } case CloseMessage: - c.WriteControl(CloseMessage, []byte{}, time.Now().Add(writeWait)) closeCode := CloseNoStatusReceived closeText := "" if len(payload) >= 2 { closeCode = int(binary.BigEndian.Uint16(payload)) + if !isValidReceivedCloseCode(closeCode) { + return noFrame, c.handleProtocolError("invalid close code") + } closeText = string(payload[2:]) + if !utf8.ValidString(closeText) { + return noFrame, c.handleProtocolError("invalid utf8 payload in close frame") + } } - switch closeCode { - case CloseNormalClosure, CloseGoingAway: - return noFrame, io.EOF - default: - return noFrame, &closeError{code: closeCode, text: closeText} + if err := c.handleClose(closeCode, closeText); err != nil { + return noFrame, err } + return noFrame, &CloseError{Code: closeCode, Text: closeText} } return frameType, nil @@ -695,11 +929,18 @@ func (c *Conn) handleProtocolError(message string) error { // There can be at most one open reader on a connection. NextReader discards // the previous message if the application has not already consumed it. // -// The NextReader method and the readers returned from the method cannot be -// accessed by more than one goroutine at a time. +// Applications must break out of the application's read loop when this method +// returns a non-nil error value. Errors returned from this method are +// permanent. Once this method returns a non-nil error, all subsequent calls to +// this method return the same error. func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { + // Close previous reader, only relevant for decompression. + if c.reader != nil { + c.reader.Close() + c.reader = nil + } - c.readSeq++ + c.messageReader = nil c.readLength = 0 for c.readErr == nil { @@ -709,59 +950,77 @@ func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { break } if frameType == TextMessage || frameType == BinaryMessage { - return frameType, messageReader{c, c.readSeq}, nil + c.messageReader = &messageReader{c} + c.reader = c.messageReader + if c.readDecompress { + c.reader = c.newDecompressionReader(c.reader) + } + return frameType, c.reader, nil } } - return noFrame, nil, c.readErr -} -type messageReader struct { - c *Conn - seq int + // Applications that do handle the error returned from this method spin in + // tight loop on connection failure. To help application developers detect + // this error, panic on repeated reads to the failed connection. + c.readErrCount++ + if c.readErrCount >= 1000 { + panic("repeated read on failed websocket connection") + } + + return noFrame, nil, c.readErr } -func (r messageReader) Read(b []byte) (int, error) { +type messageReader struct{ c *Conn } - if r.seq != r.c.readSeq { +func (r *messageReader) Read(b []byte) (int, error) { + c := r.c + if c.messageReader != r { return 0, io.EOF } - for r.c.readErr == nil { + for c.readErr == nil { - if r.c.readRemaining > 0 { - if int64(len(b)) > r.c.readRemaining { - b = b[:r.c.readRemaining] + if c.readRemaining > 0 { + if int64(len(b)) > c.readRemaining { + b = b[:c.readRemaining] } - n, err := r.c.br.Read(b) - r.c.readErr = hideTempErr(err) - if r.c.isServer { - r.c.readMaskPos = maskBytes(r.c.readMaskKey, r.c.readMaskPos, b[:n]) + n, err := c.br.Read(b) + c.readErr = hideTempErr(err) + if c.isServer { + c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n]) } - r.c.readRemaining -= int64(n) - return n, r.c.readErr + c.readRemaining -= int64(n) + if c.readRemaining > 0 && c.readErr == io.EOF { + c.readErr = errUnexpectedEOF + } + return n, c.readErr } - if r.c.readFinal { - r.c.readSeq++ + if c.readFinal { + c.messageReader = nil return 0, io.EOF } - frameType, err := r.c.advanceFrame() + frameType, err := c.advanceFrame() switch { case err != nil: - r.c.readErr = hideTempErr(err) + c.readErr = hideTempErr(err) case frameType == TextMessage || frameType == BinaryMessage: - r.c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") + c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") } } - err := r.c.readErr - if err == io.EOF && r.seq == r.c.readSeq { + err := c.readErr + if err == io.EOF && c.messageReader == r { err = errUnexpectedEOF } return 0, err } +func (r *messageReader) Close() error { + return nil +} + // ReadMessage is a helper method for getting a reader using NextReader and // reading from that reader to a buffer. func (c *Conn) ReadMessage() (messageType int, p []byte, err error) { @@ -783,27 +1042,82 @@ func (c *Conn) SetReadDeadline(t time.Time) error { } // SetReadLimit sets the maximum size for a message read from the peer. If a -// message exceeds the limit, the connection sends a close frame to the peer +// message exceeds the limit, the connection sends a close message to the peer // and returns ErrReadLimit to the application. func (c *Conn) SetReadLimit(limit int64) { c.readLimit = limit } +// CloseHandler returns the current close handler +func (c *Conn) CloseHandler() func(code int, text string) error { + return c.handleClose +} + +// SetCloseHandler sets the handler for close messages received from the peer. +// The code argument to h is the received close code or CloseNoStatusReceived +// if the close message is empty. The default close handler sends a close +// message back to the peer. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// close messages as described in the section on Control Messages above. +// +// The connection read methods return a CloseError when a close message is +// received. Most applications should handle close messages as part of their +// normal error handling. Applications should only set a close handler when the +// application must perform some action before sending a close message back to +// the peer. +func (c *Conn) SetCloseHandler(h func(code int, text string) error) { + if h == nil { + h = func(code int, text string) error { + message := FormatCloseMessage(code, "") + c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) + return nil + } + } + c.handleClose = h +} + +// PingHandler returns the current ping handler +func (c *Conn) PingHandler() func(appData string) error { + return c.handlePing +} + // SetPingHandler sets the handler for ping messages received from the peer. -// The default ping handler sends a pong to the peer. -func (c *Conn) SetPingHandler(h func(string) error) { +// The appData argument to h is the PING message application data. The default +// ping handler sends a pong to the peer. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// ping messages as described in the section on Control Messages above. +func (c *Conn) SetPingHandler(h func(appData string) error) { if h == nil { h = func(message string) error { - c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) - return nil + err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) + if err == ErrCloseSent { + return nil + } else if e, ok := err.(net.Error); ok && e.Temporary() { + return nil + } + return err } } c.handlePing = h } -// SetPongHandler sets then handler for pong messages received from the peer. -// The default pong handler does nothing. -func (c *Conn) SetPongHandler(h func(string) error) { +// PongHandler returns the current pong handler +func (c *Conn) PongHandler() func(appData string) error { + return c.handlePong +} + +// SetPongHandler sets the handler for pong messages received from the peer. +// The appData argument to h is the PONG message application data. The default +// pong handler does nothing. +// +// The handler function is called from the NextReader, ReadMessage and message +// reader Read methods. The application must read the connection to process +// pong messages as described in the section on Control Messages above. +func (c *Conn) SetPongHandler(h func(appData string) error) { if h == nil { h = func(string) error { return nil } } @@ -816,8 +1130,34 @@ func (c *Conn) UnderlyingConn() net.Conn { return c.conn } +// EnableWriteCompression enables and disables write compression of +// subsequent text and binary messages. This function is a noop if +// compression was not negotiated with the peer. +func (c *Conn) EnableWriteCompression(enable bool) { + c.enableWriteCompression = enable +} + +// SetCompressionLevel sets the flate compression level for subsequent text and +// binary messages. This function is a noop if compression was not negotiated +// with the peer. See the compress/flate package for a description of +// compression levels. +func (c *Conn) SetCompressionLevel(level int) error { + if !isValidCompressionLevel(level) { + return errors.New("websocket: invalid compression level") + } + c.compressionLevel = level + return nil +} + // FormatCloseMessage formats closeCode and text as a WebSocket close message. +// An empty message is returned for code CloseNoStatusReceived. func FormatCloseMessage(closeCode int, text string) []byte { + if closeCode == CloseNoStatusReceived { + // Return empty message because it's illegal to send + // CloseNoStatusReceived. Return non-nil value in case application + // checks for nil. + return []byte{} + } buf := make([]byte, 2+len(text)) binary.BigEndian.PutUint16(buf, uint16(closeCode)) copy(buf[2:], text) diff --git a/vendor/github.com/gorilla/websocket/conn_write.go b/vendor/github.com/gorilla/websocket/conn_write.go new file mode 100644 index 000000000..a509a21f8 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn_write.go @@ -0,0 +1,15 @@ +// Copyright 2016 The Gorilla WebSocket 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.8 + +package websocket + +import "net" + +func (c *Conn) writeBufs(bufs ...[]byte) error { + b := net.Buffers(bufs) + _, err := b.WriteTo(c.conn) + return err +} diff --git a/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/vendor/github.com/gorilla/websocket/conn_write_legacy.go new file mode 100644 index 000000000..37edaff5a --- /dev/null +++ b/vendor/github.com/gorilla/websocket/conn_write_legacy.go @@ -0,0 +1,18 @@ +// Copyright 2016 The Gorilla WebSocket 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.8 + +package websocket + +func (c *Conn) writeBufs(bufs ...[]byte) error { + for _, buf := range bufs { + if len(buf) > 0 { + if _, err := c.conn.Write(buf); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go index 0d2bd912b..dcce1a63c 100644 --- a/vendor/github.com/gorilla/websocket/doc.go +++ b/vendor/github.com/gorilla/websocket/doc.go @@ -6,9 +6,8 @@ // // Overview // -// The Conn type represents a WebSocket connection. A server application uses -// the Upgrade function from an Upgrader object with a HTTP request handler -// to get a pointer to a Conn: +// The Conn type represents a WebSocket connection. A server application calls +// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn: // // var upgrader = websocket.Upgrader{ // ReadBufferSize: 1024, @@ -24,17 +23,19 @@ // ... Use conn to send and receive messages. // } // -// Call the connection WriteMessage and ReadMessages methods to send and +// Call the connection's WriteMessage and ReadMessage methods to send and // receive messages as a slice of bytes. This snippet of code shows how to echo // messages using these methods: // // for { // messageType, p, err := conn.ReadMessage() // if err != nil { +// log.Println(err) // return // } -// if err = conn.WriteMessage(messageType, p); err != nil { -// return err +// if err := conn.WriteMessage(messageType, p); err != nil { +// log.Println(err) +// return // } // } // @@ -46,8 +47,7 @@ // method to get an io.WriteCloser, write the message to the writer and close // the writer when done. To receive a message, call the connection NextReader // method to get an io.Reader and read until io.EOF is returned. This snippet -// snippet shows how to echo messages using the NextWriter and NextReader -// methods: +// shows how to echo messages using the NextWriter and NextReader methods: // // for { // messageType, r, err := conn.NextReader() @@ -86,31 +86,29 @@ // and pong. Call the connection WriteControl, WriteMessage or NextWriter // methods to send a control message to the peer. // -// Connections handle received ping and pong messages by invoking a callback -// function set with SetPingHandler and SetPongHandler methods. These callback -// functions can be invoked from the ReadMessage method, the NextReader method -// or from a call to the data message reader returned from NextReader. -// -// Connections handle received close messages by returning an error from the -// ReadMessage method, the NextReader method or from a call to the data message -// reader returned from NextReader. -// -// Concurrency +// Connections handle received close messages by calling the handler function +// set with the SetCloseHandler method and by returning a *CloseError from the +// NextReader, ReadMessage or the message Read method. The default close +// handler sends a close message to the peer. // -// Connections do not support concurrent calls to the write methods -// (NextWriter, SetWriteDeadline, WriteMessage) or concurrent calls to the read -// methods methods (NextReader, SetReadDeadline, ReadMessage). Connections do -// support a concurrent reader and writer. +// Connections handle received ping messages by calling the handler function +// set with the SetPingHandler method. The default ping handler sends a pong +// message to the peer. // -// The Close and WriteControl methods can be called concurrently with all other -// methods. +// Connections handle received pong messages by calling the handler function +// set with the SetPongHandler method. The default pong handler does nothing. +// If an application sends ping messages, then the application should set a +// pong handler to receive the corresponding pong. // -// Read is Required +// The control message handler functions are called from the NextReader, +// ReadMessage and message reader Read methods. The default close and ping +// handlers can block these methods for a short time when the handler writes to +// the connection. // -// The application must read the connection to process ping and close messages -// sent from the peer. If the application is not otherwise interested in -// messages from the peer, then the application should start a goroutine to read -// and discard messages from the peer. A simple example is: +// The application must read the connection to process close, ping and pong +// messages sent from the peer. If the application is not otherwise interested +// in messages from the peer, then the application should start a goroutine to +// read and discard messages from the peer. A simple example is: // // func readLoop(c *websocket.Conn) { // for { @@ -121,6 +119,20 @@ // } // } // +// Concurrency +// +// Connections support one concurrent reader and one concurrent writer. +// +// Applications are responsible for ensuring that no more than one goroutine +// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, +// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and +// that no more than one goroutine calls the read methods (NextReader, +// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) +// concurrently. +// +// The Close and WriteControl methods can be called concurrently with all other +// methods. +// // Origin Considerations // // Web browsers allow Javascript applications to open a WebSocket connection to @@ -132,17 +144,37 @@ // method fails the WebSocket handshake with HTTP status 403. // // If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail -// the handshake if the Origin request header is present and not equal to the -// Host request header. +// the handshake if the Origin request header is present and the Origin host is +// not equal to the Host request header. +// +// The deprecated package-level Upgrade function does not perform origin +// checking. The application is responsible for checking the Origin header +// before calling the Upgrade function. +// +// Compression EXPERIMENTAL +// +// Per message compression extensions (RFC 7692) are experimentally supported +// by this package in a limited capacity. Setting the EnableCompression option +// to true in Dialer or Upgrader will attempt to negotiate per message deflate +// support. +// +// var upgrader = websocket.Upgrader{ +// EnableCompression: true, +// } +// +// If compression was successfully negotiated with the connection's peer, any +// message received in compressed form will be automatically decompressed. +// All Read methods will return uncompressed bytes. +// +// Per message compression of messages written to a connection can be enabled +// or disabled by calling the corresponding Conn method: // -// An application can allow connections from any origin by specifying a -// function that always returns true: +// conn.EnableWriteCompression(false) // -// var upgrader = websocket.Upgrader{ -// CheckOrigin: func(r *http.Request) bool { return true }, -// } +// Currently this package does not support compression with "context takeover". +// This means that messages must be compressed and decompressed in isolation, +// without retaining sliding window or dictionary state across messages. For +// more details refer to RFC 7692. // -// The deprecated Upgrade function does not enforce an origin policy. It's the -// application's responsibility to check the Origin header before calling -// Upgrade. +// Use of compression is experimental and may result in decreased performance. package websocket diff --git a/vendor/github.com/gorilla/websocket/json.go b/vendor/github.com/gorilla/websocket/json.go index 18e62f225..dc2c1f641 100644 --- a/vendor/github.com/gorilla/websocket/json.go +++ b/vendor/github.com/gorilla/websocket/json.go @@ -9,12 +9,14 @@ import ( "io" ) -// WriteJSON is deprecated, use c.WriteJSON instead. +// WriteJSON writes the JSON encoding of v as a message. +// +// Deprecated: Use c.WriteJSON instead. func WriteJSON(c *Conn, v interface{}) error { return c.WriteJSON(v) } -// WriteJSON writes the JSON encoding of v to the connection. +// WriteJSON writes the JSON encoding of v as a message. // // See the documentation for encoding/json Marshal for details about the // conversion of Go values to JSON. @@ -31,7 +33,10 @@ func (c *Conn) WriteJSON(v interface{}) error { return err2 } -// ReadJSON is deprecated, use c.ReadJSON instead. +// ReadJSON reads the next JSON-encoded message from the connection and stores +// it in the value pointed to by v. +// +// Deprecated: Use c.ReadJSON instead. func ReadJSON(c *Conn, v interface{}) error { return c.ReadJSON(v) } @@ -48,9 +53,7 @@ func (c *Conn) ReadJSON(v interface{}) error { } err = json.NewDecoder(r).Decode(v) if err == io.EOF { - // Decode returns io.EOF when the message is empty or all whitespace. - // Convert to io.ErrUnexpectedEOF so that application can distinguish - // between an error reading the JSON value and the connection closing. + // One value is expected in the message. err = io.ErrUnexpectedEOF } return err diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go new file mode 100644 index 000000000..577fce9ef --- /dev/null +++ b/vendor/github.com/gorilla/websocket/mask.go @@ -0,0 +1,54 @@ +// Copyright 2016 The Gorilla WebSocket 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 !appengine + +package websocket + +import "unsafe" + +const wordSize = int(unsafe.Sizeof(uintptr(0))) + +func maskBytes(key [4]byte, pos int, b []byte) int { + // Mask one byte at a time for small buffers. + if len(b) < 2*wordSize { + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + return pos & 3 + } + + // Mask one byte at a time to word boundary. + if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { + n = wordSize - n + for i := range b[:n] { + b[i] ^= key[pos&3] + pos++ + } + b = b[n:] + } + + // Create aligned word size key. + var k [wordSize]byte + for i := range k { + k[i] = key[(pos+i)&3] + } + kw := *(*uintptr)(unsafe.Pointer(&k)) + + // Mask one word at a time. + n := (len(b) / wordSize) * wordSize + for i := 0; i < n; i += wordSize { + *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw + } + + // Mask one byte at a time for remaining bytes. + b = b[n:] + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + + return pos & 3 +} diff --git a/vendor/github.com/gorilla/websocket/mask_safe.go b/vendor/github.com/gorilla/websocket/mask_safe.go new file mode 100644 index 000000000..2aac060e5 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/mask_safe.go @@ -0,0 +1,15 @@ +// Copyright 2016 The Gorilla WebSocket 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 appengine + +package websocket + +func maskBytes(key [4]byte, pos int, b []byte) int { + for i := range b { + b[i] ^= key[pos&3] + pos++ + } + return pos & 3 +} diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go new file mode 100644 index 000000000..74ec565d2 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/prepared.go @@ -0,0 +1,102 @@ +// Copyright 2017 The Gorilla WebSocket 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 websocket + +import ( + "bytes" + "net" + "sync" + "time" +) + +// PreparedMessage caches on the wire representations of a message payload. +// Use PreparedMessage to efficiently send a message payload to multiple +// connections. PreparedMessage is especially useful when compression is used +// because the CPU and memory expensive compression operation can be executed +// once for a given set of compression options. +type PreparedMessage struct { + messageType int + data []byte + mu sync.Mutex + frames map[prepareKey]*preparedFrame +} + +// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage. +type prepareKey struct { + isServer bool + compress bool + compressionLevel int +} + +// preparedFrame contains data in wire representation. +type preparedFrame struct { + once sync.Once + data []byte +} + +// NewPreparedMessage returns an initialized PreparedMessage. You can then send +// it to connection using WritePreparedMessage method. Valid wire +// representation will be calculated lazily only once for a set of current +// connection options. +func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) { + pm := &PreparedMessage{ + messageType: messageType, + frames: make(map[prepareKey]*preparedFrame), + data: data, + } + + // Prepare a plain server frame. + _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false}) + if err != nil { + return nil, err + } + + // To protect against caller modifying the data argument, remember the data + // copied to the plain server frame. + pm.data = frameData[len(frameData)-len(data):] + return pm, nil +} + +func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) { + pm.mu.Lock() + frame, ok := pm.frames[key] + if !ok { + frame = &preparedFrame{} + pm.frames[key] = frame + } + pm.mu.Unlock() + + var err error + frame.once.Do(func() { + // Prepare a frame using a 'fake' connection. + // TODO: Refactor code in conn.go to allow more direct construction of + // the frame. + mu := make(chan bool, 1) + mu <- true + var nc prepareConn + c := &Conn{ + conn: &nc, + mu: mu, + isServer: key.isServer, + compressionLevel: key.compressionLevel, + enableWriteCompression: true, + writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize), + } + if key.compress { + c.newCompressionWriter = compressNoContextTakeover + } + err = c.WriteMessage(pm.messageType, pm.data) + frame.data = nc.buf.Bytes() + }) + return pm.messageType, frame.data, err +} + +type prepareConn struct { + buf bytes.Buffer + net.Conn +} + +func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) } +func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil } diff --git a/vendor/github.com/gorilla/websocket/proxy.go b/vendor/github.com/gorilla/websocket/proxy.go new file mode 100644 index 000000000..bf2478e43 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/proxy.go @@ -0,0 +1,77 @@ +// Copyright 2017 The Gorilla WebSocket 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 websocket + +import ( + "bufio" + "encoding/base64" + "errors" + "net" + "net/http" + "net/url" + "strings" +) + +type netDialerFunc func(network, addr string) (net.Conn, error) + +func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) { + return fn(network, addr) +} + +func init() { + proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) { + return &httpProxyDialer{proxyURL: proxyURL, fowardDial: forwardDialer.Dial}, nil + }) +} + +type httpProxyDialer struct { + proxyURL *url.URL + fowardDial func(network, addr string) (net.Conn, error) +} + +func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) { + hostPort, _ := hostPortNoPort(hpd.proxyURL) + conn, err := hpd.fowardDial(network, hostPort) + if err != nil { + return nil, err + } + + connectHeader := make(http.Header) + if user := hpd.proxyURL.User; user != nil { + proxyUser := user.Username() + if proxyPassword, passwordSet := user.Password(); passwordSet { + credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) + connectHeader.Set("Proxy-Authorization", "Basic "+credential) + } + } + + connectReq := &http.Request{ + Method: "CONNECT", + URL: &url.URL{Opaque: addr}, + Host: addr, + Header: connectHeader, + } + + if err := connectReq.Write(conn); err != nil { + conn.Close() + return nil, err + } + + // Read response. It's OK to use and discard buffered reader here becaue + // the remote server does not speak until spoken to. + br := bufio.NewReader(conn) + resp, err := http.ReadResponse(br, connectReq) + if err != nil { + conn.Close() + return nil, err + } + + if resp.StatusCode != 200 { + conn.Close() + f := strings.SplitN(resp.Status, " ", 2) + return nil, errors.New(f[1]) + } + return conn, nil +} diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go index e56a00493..a761824b3 100644 --- a/vendor/github.com/gorilla/websocket/server.go +++ b/vendor/github.com/gorilla/websocket/server.go @@ -7,7 +7,7 @@ package websocket import ( "bufio" "errors" - "net" + "io" "net/http" "net/url" "strings" @@ -28,14 +28,28 @@ type Upgrader struct { HandshakeTimeout time.Duration // ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer - // size is zero, then a default value of 4096 is used. The I/O buffer sizes - // do not limit the size of the messages that can be sent or received. + // size is zero, then buffers allocated by the HTTP server are used. The + // I/O buffer sizes do not limit the size of the messages that can be sent + // or received. ReadBufferSize, WriteBufferSize int + // WriteBufferPool is a pool of buffers for write operations. If the value + // is not set, then write buffers are allocated to the connection for the + // lifetime of the connection. + // + // A pool is most useful when the application has a modest volume of writes + // across a large number of connections. + // + // Applications should use a single pool for each unique value of + // WriteBufferSize. + WriteBufferPool BufferPool + // Subprotocols specifies the server's supported protocols in order of - // preference. If this field is set, then the Upgrade method negotiates a + // preference. If this field is not nil, then the Upgrade method negotiates a // subprotocol by selecting the first match in this list with a protocol - // requested by the client. + // requested by the client. If there's no match, then no protocol is + // negotiated (the Sec-Websocket-Protocol header is not included in the + // handshake response). Subprotocols []string // Error specifies the function for generating HTTP error responses. If Error @@ -43,9 +57,19 @@ type Upgrader struct { Error func(w http.ResponseWriter, r *http.Request, status int, reason error) // CheckOrigin returns true if the request Origin header is acceptable. If - // CheckOrigin is nil, the host in the Origin header must not be set or - // must match the host of the request. + // CheckOrigin is nil, then a safe default is used: return false if the + // Origin request header is present and the origin host is not equal to + // request Host header. + // + // A CheckOrigin function should carefully validate the request origin to + // prevent cross-site request forgery. CheckOrigin func(r *http.Request) bool + + // EnableCompression specify if the server should attempt to negotiate per + // message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool } func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) { @@ -53,6 +77,7 @@ func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status in if u.Error != nil { u.Error(w, r, status, err) } else { + w.Header().Set("Sec-Websocket-Version", "13") http.Error(w, http.StatusText(status), status) } return nil, err @@ -68,7 +93,7 @@ func checkSameOrigin(r *http.Request) bool { if err != nil { return false } - return u.Host == r.Host + return equalASCIIFold(u.Host, r.Host) } func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string { @@ -91,18 +116,31 @@ func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header // // The responseHeader is included in the response to the client's upgrade // request. Use the responseHeader to specify cookies (Set-Cookie) and the -// application negotiated subprotocol (Sec-Websocket-Protocol). +// application negotiated subprotocol (Sec-WebSocket-Protocol). +// +// If the upgrade fails, then Upgrade replies to the client with an HTTP error +// response. func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { - if values := r.Header["Sec-Websocket-Version"]; len(values) == 0 || values[0] != "13" { - return u.returnError(w, r, http.StatusBadRequest, "websocket: version != 13") - } + const badHandshake = "websocket: the client is not using the websocket protocol: " if !tokenListContainsValue(r.Header, "Connection", "upgrade") { - return u.returnError(w, r, http.StatusBadRequest, "websocket: could not find connection header with token 'upgrade'") + return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header") } if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { - return u.returnError(w, r, http.StatusBadRequest, "websocket: could not find upgrade header with token 'websocket'") + return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header") + } + + if r.Method != "GET" { + return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET") + } + + if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") { + return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header") + } + + if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok { + return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported") } checkOrigin := u.CheckOrigin @@ -110,50 +148,83 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade checkOrigin = checkSameOrigin } if !checkOrigin(r) { - return u.returnError(w, r, http.StatusForbidden, "websocket: origin not allowed") + return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin") } challengeKey := r.Header.Get("Sec-Websocket-Key") if challengeKey == "" { - return u.returnError(w, r, http.StatusBadRequest, "websocket: key missing or blank") + return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-WebSocket-Key' header is missing or blank") } subprotocol := u.selectSubprotocol(r, responseHeader) - var ( - netConn net.Conn - br *bufio.Reader - err error - ) + // Negotiate PMCE + var compress bool + if u.EnableCompression { + for _, ext := range parseExtensions(r.Header) { + if ext[""] != "permessage-deflate" { + continue + } + compress = true + break + } + } h, ok := w.(http.Hijacker) if !ok { return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker") } - var rw *bufio.ReadWriter - netConn, rw, err = h.Hijack() + var brw *bufio.ReadWriter + netConn, brw, err := h.Hijack() if err != nil { return u.returnError(w, r, http.StatusInternalServerError, err.Error()) } - br = rw.Reader - if br.Buffered() > 0 { + if brw.Reader.Buffered() > 0 { netConn.Close() return nil, errors.New("websocket: client sent data before handshake is complete") } - c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize) + var br *bufio.Reader + if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 { + // Reuse hijacked buffered reader as connection reader. + br = brw.Reader + } + + buf := bufioWriterBuffer(netConn, brw.Writer) + + var writeBuf []byte + if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 { + // Reuse hijacked write buffer as connection buffer. + writeBuf = buf + } + + c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf) c.subprotocol = subprotocol - p := c.writeBuf[:0] + if compress { + c.newCompressionWriter = compressNoContextTakeover + c.newDecompressionReader = decompressNoContextTakeover + } + + // Use larger of hijacked buffer and connection write buffer for header. + p := buf + if len(c.writeBuf) > len(p) { + p = c.writeBuf + } + p = p[:0] + p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...) p = append(p, computeAcceptKey(challengeKey)...) p = append(p, "\r\n"...) if c.subprotocol != "" { - p = append(p, "Sec-Websocket-Protocol: "...) + p = append(p, "Sec-WebSocket-Protocol: "...) p = append(p, c.subprotocol...) p = append(p, "\r\n"...) } + if compress { + p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...) + } for k, vs := range responseHeader { if k == "Sec-Websocket-Protocol" { continue @@ -193,13 +264,14 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade // Upgrade upgrades the HTTP server connection to the WebSocket protocol. // -// This function is deprecated, use websocket.Upgrader instead. +// Deprecated: Use websocket.Upgrader instead. // -// The application is responsible for checking the request origin before -// calling Upgrade. An example implementation of the same origin policy is: +// Upgrade does not perform origin checking. The application is responsible for +// checking the Origin header before calling Upgrade. An example implementation +// of the same origin policy check is: // // if req.Header.Get("Origin") != "http://"+req.Host { -// http.Error(w, "Origin not allowed", 403) +// http.Error(w, "Origin not allowed", http.StatusForbidden) // return // } // @@ -245,3 +317,47 @@ func Subprotocols(r *http.Request) []string { } return protocols } + +// IsWebSocketUpgrade returns true if the client requested upgrade to the +// WebSocket protocol. +func IsWebSocketUpgrade(r *http.Request) bool { + return tokenListContainsValue(r.Header, "Connection", "upgrade") && + tokenListContainsValue(r.Header, "Upgrade", "websocket") +} + +// bufioReaderSize size returns the size of a bufio.Reader. +func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int { + // This code assumes that peek on a reset reader returns + // bufio.Reader.buf[:0]. + // TODO: Use bufio.Reader.Size() after Go 1.10 + br.Reset(originalReader) + if p, err := br.Peek(0); err == nil { + return cap(p) + } + return 0 +} + +// writeHook is an io.Writer that records the last slice passed to it vio +// io.Writer.Write. +type writeHook struct { + p []byte +} + +func (wh *writeHook) Write(p []byte) (int, error) { + wh.p = p + return len(p), nil +} + +// bufioWriterBuffer grabs the buffer from a bufio.Writer. +func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte { + // This code assumes that bufio.Writer.buf[:1] is passed to the + // bufio.Writer's underlying writer. + var wh writeHook + bw.Reset(&wh) + bw.WriteByte(0) + bw.Flush() + + bw.Reset(originalWriter) + + return wh.p[:cap(wh.p)] +} diff --git a/vendor/github.com/gorilla/websocket/trace.go b/vendor/github.com/gorilla/websocket/trace.go new file mode 100644 index 000000000..834f122a0 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/trace.go @@ -0,0 +1,19 @@ +// +build go1.8 + +package websocket + +import ( + "crypto/tls" + "net/http/httptrace" +) + +func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { + if trace.TLSHandshakeStart != nil { + trace.TLSHandshakeStart() + } + err := doHandshake(tlsConn, cfg) + if trace.TLSHandshakeDone != nil { + trace.TLSHandshakeDone(tlsConn.ConnectionState(), err) + } + return err +} diff --git a/vendor/github.com/gorilla/websocket/trace_17.go b/vendor/github.com/gorilla/websocket/trace_17.go new file mode 100644 index 000000000..77d05a0b5 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/trace_17.go @@ -0,0 +1,12 @@ +// +build !go1.8 + +package websocket + +import ( + "crypto/tls" + "net/http/httptrace" +) + +func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { + return doHandshake(tlsConn, cfg) +} diff --git a/vendor/github.com/gorilla/websocket/util.go b/vendor/github.com/gorilla/websocket/util.go index ffdc265ed..354001e1e 100644 --- a/vendor/github.com/gorilla/websocket/util.go +++ b/vendor/github.com/gorilla/websocket/util.go @@ -11,21 +11,9 @@ import ( "io" "net/http" "strings" + "unicode/utf8" ) -// tokenListContainsValue returns true if the 1#token header with the given -// name contains token. -func tokenListContainsValue(header http.Header, name string, value string) bool { - for _, v := range header[name] { - for _, s := range strings.Split(v, ",") { - if strings.EqualFold(value, strings.TrimSpace(s)) { - return true - } - } - } - return false -} - var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") func computeAcceptKey(challengeKey string) string { @@ -42,3 +30,208 @@ func generateChallengeKey() (string, error) { } return base64.StdEncoding.EncodeToString(p), nil } + +// Octet types from RFC 2616. +var octetTypes [256]byte + +const ( + isTokenOctet = 1 << iota + isSpaceOctet +) + +func init() { + // From RFC 2616 + // + // OCTET = + // CHAR = + // CTL = + // CR = + // LF = + // SP = + // HT = + // <"> = + // CRLF = CR LF + // LWS = [CRLF] 1*( SP | HT ) + // TEXT = + // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> + // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT + // token = 1* + // qdtext = > + + for c := 0; c < 256; c++ { + var t byte + isCtl := c <= 31 || c == 127 + isChar := 0 <= c && c <= 127 + isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0 + if strings.IndexRune(" \t\r\n", rune(c)) >= 0 { + t |= isSpaceOctet + } + if isChar && !isCtl && !isSeparator { + t |= isTokenOctet + } + octetTypes[c] = t + } +} + +func skipSpace(s string) (rest string) { + i := 0 + for ; i < len(s); i++ { + if octetTypes[s[i]]&isSpaceOctet == 0 { + break + } + } + return s[i:] +} + +func nextToken(s string) (token, rest string) { + i := 0 + for ; i < len(s); i++ { + if octetTypes[s[i]]&isTokenOctet == 0 { + break + } + } + return s[:i], s[i:] +} + +func nextTokenOrQuoted(s string) (value string, rest string) { + if !strings.HasPrefix(s, "\"") { + return nextToken(s) + } + s = s[1:] + for i := 0; i < len(s); i++ { + switch s[i] { + case '"': + return s[:i], s[i+1:] + case '\\': + p := make([]byte, len(s)-1) + j := copy(p, s[:i]) + escape := true + for i = i + 1; i < len(s); i++ { + b := s[i] + switch { + case escape: + escape = false + p[j] = b + j++ + case b == '\\': + escape = true + case b == '"': + return string(p[:j]), s[i+1:] + default: + p[j] = b + j++ + } + } + return "", "" + } + } + return "", "" +} + +// equalASCIIFold returns true if s is equal to t with ASCII case folding. +func equalASCIIFold(s, t string) bool { + for s != "" && t != "" { + sr, size := utf8.DecodeRuneInString(s) + s = s[size:] + tr, size := utf8.DecodeRuneInString(t) + t = t[size:] + if sr == tr { + continue + } + if 'A' <= sr && sr <= 'Z' { + sr = sr + 'a' - 'A' + } + if 'A' <= tr && tr <= 'Z' { + tr = tr + 'a' - 'A' + } + if sr != tr { + return false + } + } + return s == t +} + +// tokenListContainsValue returns true if the 1#token header with the given +// name contains a token equal to value with ASCII case folding. +func tokenListContainsValue(header http.Header, name string, value string) bool { +headers: + for _, s := range header[name] { + for { + var t string + t, s = nextToken(skipSpace(s)) + if t == "" { + continue headers + } + s = skipSpace(s) + if s != "" && s[0] != ',' { + continue headers + } + if equalASCIIFold(t, value) { + return true + } + if s == "" { + continue headers + } + s = s[1:] + } + } + return false +} + +// parseExtensions parses WebSocket extensions from a header. +func parseExtensions(header http.Header) []map[string]string { + // From RFC 6455: + // + // Sec-WebSocket-Extensions = extension-list + // extension-list = 1#extension + // extension = extension-token *( ";" extension-param ) + // extension-token = registered-token + // registered-token = token + // extension-param = token [ "=" (token | quoted-string) ] + // ;When using the quoted-string syntax variant, the value + // ;after quoted-string unescaping MUST conform to the + // ;'token' ABNF. + + var result []map[string]string +headers: + for _, s := range header["Sec-Websocket-Extensions"] { + for { + var t string + t, s = nextToken(skipSpace(s)) + if t == "" { + continue headers + } + ext := map[string]string{"": t} + for { + s = skipSpace(s) + if !strings.HasPrefix(s, ";") { + break + } + var k string + k, s = nextToken(skipSpace(s[1:])) + if k == "" { + continue headers + } + s = skipSpace(s) + var v string + if strings.HasPrefix(s, "=") { + v, s = nextTokenOrQuoted(skipSpace(s[1:])) + s = skipSpace(s) + } + if s != "" && s[0] != ',' && s[0] != ';' { + continue headers + } + ext[k] = v + } + if s != "" && s[0] != ',' { + continue headers + } + result = append(result, ext) + if s == "" { + continue headers + } + s = s[1:] + } + } + return result +} diff --git a/vendor/github.com/gorilla/websocket/x_net_proxy.go b/vendor/github.com/gorilla/websocket/x_net_proxy.go new file mode 100644 index 000000000..2e668f6b8 --- /dev/null +++ b/vendor/github.com/gorilla/websocket/x_net_proxy.go @@ -0,0 +1,473 @@ +// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. +//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy + +// Package proxy provides support for a variety of protocols to proxy network +// data. +// + +package websocket + +import ( + "errors" + "io" + "net" + "net/url" + "os" + "strconv" + "strings" + "sync" +) + +type proxy_direct struct{} + +// Direct is a direct proxy: one that makes network connections directly. +var proxy_Direct = proxy_direct{} + +func (proxy_direct) Dial(network, addr string) (net.Conn, error) { + return net.Dial(network, addr) +} + +// A PerHost directs connections to a default Dialer unless the host name +// requested matches one of a number of exceptions. +type proxy_PerHost struct { + def, bypass proxy_Dialer + + bypassNetworks []*net.IPNet + bypassIPs []net.IP + bypassZones []string + bypassHosts []string +} + +// NewPerHost returns a PerHost Dialer that directs connections to either +// defaultDialer or bypass, depending on whether the connection matches one of +// the configured rules. +func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost { + return &proxy_PerHost{ + def: defaultDialer, + bypass: bypass, + } +} + +// Dial connects to the address addr on the given network through either +// defaultDialer or bypass. +func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) { + host, _, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + return p.dialerForRequest(host).Dial(network, addr) +} + +func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer { + if ip := net.ParseIP(host); ip != nil { + for _, net := range p.bypassNetworks { + if net.Contains(ip) { + return p.bypass + } + } + for _, bypassIP := range p.bypassIPs { + if bypassIP.Equal(ip) { + return p.bypass + } + } + return p.def + } + + for _, zone := range p.bypassZones { + if strings.HasSuffix(host, zone) { + return p.bypass + } + if host == zone[1:] { + // For a zone ".example.com", we match "example.com" + // too. + return p.bypass + } + } + for _, bypassHost := range p.bypassHosts { + if bypassHost == host { + return p.bypass + } + } + return p.def +} + +// AddFromString parses a string that contains comma-separated values +// specifying hosts that should use the bypass proxy. Each value is either an +// IP address, a CIDR range, a zone (*.example.com) or a host name +// (localhost). A best effort is made to parse the string and errors are +// ignored. +func (p *proxy_PerHost) AddFromString(s string) { + hosts := strings.Split(s, ",") + for _, host := range hosts { + host = strings.TrimSpace(host) + if len(host) == 0 { + continue + } + if strings.Contains(host, "/") { + // We assume that it's a CIDR address like 127.0.0.0/8 + if _, net, err := net.ParseCIDR(host); err == nil { + p.AddNetwork(net) + } + continue + } + if ip := net.ParseIP(host); ip != nil { + p.AddIP(ip) + continue + } + if strings.HasPrefix(host, "*.") { + p.AddZone(host[1:]) + continue + } + p.AddHost(host) + } +} + +// AddIP specifies an IP address that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match an IP. +func (p *proxy_PerHost) AddIP(ip net.IP) { + p.bypassIPs = append(p.bypassIPs, ip) +} + +// AddNetwork specifies an IP range that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match. +func (p *proxy_PerHost) AddNetwork(net *net.IPNet) { + p.bypassNetworks = append(p.bypassNetworks, net) +} + +// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of +// "example.com" matches "example.com" and all of its subdomains. +func (p *proxy_PerHost) AddZone(zone string) { + if strings.HasSuffix(zone, ".") { + zone = zone[:len(zone)-1] + } + if !strings.HasPrefix(zone, ".") { + zone = "." + zone + } + p.bypassZones = append(p.bypassZones, zone) +} + +// AddHost specifies a host name that will use the bypass proxy. +func (p *proxy_PerHost) AddHost(host string) { + if strings.HasSuffix(host, ".") { + host = host[:len(host)-1] + } + p.bypassHosts = append(p.bypassHosts, host) +} + +// A Dialer is a means to establish a connection. +type proxy_Dialer interface { + // Dial connects to the given address via the proxy. + Dial(network, addr string) (c net.Conn, err error) +} + +// Auth contains authentication parameters that specific Dialers may require. +type proxy_Auth struct { + User, Password string +} + +// FromEnvironment returns the dialer specified by the proxy related variables in +// the environment. +func proxy_FromEnvironment() proxy_Dialer { + allProxy := proxy_allProxyEnv.Get() + if len(allProxy) == 0 { + return proxy_Direct + } + + proxyURL, err := url.Parse(allProxy) + if err != nil { + return proxy_Direct + } + proxy, err := proxy_FromURL(proxyURL, proxy_Direct) + if err != nil { + return proxy_Direct + } + + noProxy := proxy_noProxyEnv.Get() + if len(noProxy) == 0 { + return proxy + } + + perHost := proxy_NewPerHost(proxy, proxy_Direct) + perHost.AddFromString(noProxy) + return perHost +} + +// proxySchemes is a map from URL schemes to a function that creates a Dialer +// from a URL with such a scheme. +var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error) + +// RegisterDialerType takes a URL scheme and a function to generate Dialers from +// a URL with that scheme and a forwarding Dialer. Registered schemes are used +// by FromURL. +func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) { + if proxy_proxySchemes == nil { + proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) + } + proxy_proxySchemes[scheme] = f +} + +// FromURL returns a Dialer given a URL specification and an underlying +// Dialer for it to make network requests. +func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) { + var auth *proxy_Auth + if u.User != nil { + auth = new(proxy_Auth) + auth.User = u.User.Username() + if p, ok := u.User.Password(); ok { + auth.Password = p + } + } + + switch u.Scheme { + case "socks5": + return proxy_SOCKS5("tcp", u.Host, auth, forward) + } + + // If the scheme doesn't match any of the built-in schemes, see if it + // was registered by another package. + if proxy_proxySchemes != nil { + if f, ok := proxy_proxySchemes[u.Scheme]; ok { + return f(u, forward) + } + } + + return nil, errors.New("proxy: unknown scheme: " + u.Scheme) +} + +var ( + proxy_allProxyEnv = &proxy_envOnce{ + names: []string{"ALL_PROXY", "all_proxy"}, + } + proxy_noProxyEnv = &proxy_envOnce{ + names: []string{"NO_PROXY", "no_proxy"}, + } +) + +// envOnce looks up an environment variable (optionally by multiple +// names) once. It mitigates expensive lookups on some platforms +// (e.g. Windows). +// (Borrowed from net/http/transport.go) +type proxy_envOnce struct { + names []string + once sync.Once + val string +} + +func (e *proxy_envOnce) Get() string { + e.once.Do(e.init) + return e.val +} + +func (e *proxy_envOnce) init() { + for _, n := range e.names { + e.val = os.Getenv(n) + if e.val != "" { + return + } + } +} + +// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address +// with an optional username and password. See RFC 1928 and RFC 1929. +func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) { + s := &proxy_socks5{ + network: network, + addr: addr, + forward: forward, + } + if auth != nil { + s.user = auth.User + s.password = auth.Password + } + + return s, nil +} + +type proxy_socks5 struct { + user, password string + network, addr string + forward proxy_Dialer +} + +const proxy_socks5Version = 5 + +const ( + proxy_socks5AuthNone = 0 + proxy_socks5AuthPassword = 2 +) + +const proxy_socks5Connect = 1 + +const ( + proxy_socks5IP4 = 1 + proxy_socks5Domain = 3 + proxy_socks5IP6 = 4 +) + +var proxy_socks5Errors = []string{ + "", + "general failure", + "connection forbidden", + "network unreachable", + "host unreachable", + "connection refused", + "TTL expired", + "command not supported", + "address type not supported", +} + +// Dial connects to the address addr on the given network via the SOCKS5 proxy. +func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) { + switch network { + case "tcp", "tcp6", "tcp4": + default: + return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) + } + + conn, err := s.forward.Dial(s.network, s.addr) + if err != nil { + return nil, err + } + if err := s.connect(conn, addr); err != nil { + conn.Close() + return nil, err + } + return conn, nil +} + +// connect takes an existing connection to a socks5 proxy server, +// and commands the server to extend that connection to target, +// which must be a canonical address with a host and port. +func (s *proxy_socks5) connect(conn net.Conn, target string) error { + host, portStr, err := net.SplitHostPort(target) + if err != nil { + return err + } + + port, err := strconv.Atoi(portStr) + if err != nil { + return errors.New("proxy: failed to parse port number: " + portStr) + } + if port < 1 || port > 0xffff { + return errors.New("proxy: port number out of range: " + portStr) + } + + // the size here is just an estimate + buf := make([]byte, 0, 6+len(host)) + + buf = append(buf, proxy_socks5Version) + if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { + buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword) + } else { + buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone) + } + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + if buf[0] != 5 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) + } + if buf[1] == 0xff { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") + } + + // See RFC 1929 + if buf[1] == proxy_socks5AuthPassword { + buf = buf[:0] + buf = append(buf, 1 /* password protocol version */) + buf = append(buf, uint8(len(s.user))) + buf = append(buf, s.user...) + buf = append(buf, uint8(len(s.password))) + buf = append(buf, s.password...) + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if buf[1] != 0 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") + } + } + + buf = buf[:0] + buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */) + + if ip := net.ParseIP(host); ip != nil { + if ip4 := ip.To4(); ip4 != nil { + buf = append(buf, proxy_socks5IP4) + ip = ip4 + } else { + buf = append(buf, proxy_socks5IP6) + } + buf = append(buf, ip...) + } else { + if len(host) > 255 { + return errors.New("proxy: destination host name too long: " + host) + } + buf = append(buf, proxy_socks5Domain) + buf = append(buf, byte(len(host))) + buf = append(buf, host...) + } + buf = append(buf, byte(port>>8), byte(port)) + + if _, err := conn.Write(buf); err != nil { + return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:4]); err != nil { + return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + failure := "unknown error" + if int(buf[1]) < len(proxy_socks5Errors) { + failure = proxy_socks5Errors[buf[1]] + } + + if len(failure) > 0 { + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) + } + + bytesToDiscard := 0 + switch buf[3] { + case proxy_socks5IP4: + bytesToDiscard = net.IPv4len + case proxy_socks5IP6: + bytesToDiscard = net.IPv6len + case proxy_socks5Domain: + _, err := io.ReadFull(conn, buf[:1]) + if err != nil { + return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + bytesToDiscard = int(buf[0]) + default: + return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) + } + + if cap(buf) < bytesToDiscard { + buf = make([]byte, bytesToDiscard) + } else { + buf = buf[:bytesToDiscard] + } + if _, err := io.ReadFull(conn, buf); err != nil { + return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + // Also need to discard the port number + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + return nil +} diff --git a/vendor/github.com/inconshreveable/go-update/LICENSE b/vendor/github.com/inconshreveable/go-update/LICENSE deleted file mode 100644 index 5f0d1fb6a..000000000 --- a/vendor/github.com/inconshreveable/go-update/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2014 Alan Shreve - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/github.com/inconshreveable/go-update/README.md b/vendor/github.com/inconshreveable/go-update/README.md deleted file mode 100644 index f070062c2..000000000 --- a/vendor/github.com/inconshreveable/go-update/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# go-update: Automatically update Go programs from the internet - -go-update allows a program to update itself by replacing its executable file -with a new version. It provides the flexibility to implement different updating user experiences -like auto-updating, or manual user-initiated updates. It also boasts -advanced features like binary patching and code signing verification. - -Updating your program to a new version is as easy as: - - err, errRecover := update.New().FromUrl("http://release.example.com/2.0/myprogram") - if err != nil { - fmt.Printf("Update failed: %v\n", err) - } - -## Documentation and API Reference - -Comprehensive API documentation and code examples are available in the code documentation available on godoc.org: - -[![GoDoc](https://godoc.org/github.com/inconshreveable/go-update?status.svg)](https://godoc.org/github.com/inconshreveable/go-update) - -## Features - -- Cross platform support (Windows too!) -- Binary patch application -- Checksum verification -- Code signing verification -- Support for updating arbitrary files - -## [equinox.io](https://equinox.io) -go-update provides the primitives for building self-updating applications, but there a number of other challenges -involved in a complete updating solution such as hosting, code signing, update channels, gradual rollout, -dynamically computing binary patches, tracking update metrics like versions and failures, plus more. - -I provide this service, a complete solution, free for open source projects, at [equinox.io](https://equinox.io). - -## License -Apache diff --git a/vendor/github.com/inconshreveable/go-update/download/download.go b/vendor/github.com/inconshreveable/go-update/download/download.go deleted file mode 100644 index 4552c93dd..000000000 --- a/vendor/github.com/inconshreveable/go-update/download/download.go +++ /dev/null @@ -1,235 +0,0 @@ -package download - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "net/http" - "os" - "runtime" -) - -type roundTripper struct { - RoundTripFn func(*http.Request) (*http.Response, error) -} - -func (rt *roundTripper) RoundTrip(r *http.Request) (*http.Response, error) { - return rt.RoundTripFn(r) -} - -// Download encapsulates the state and parameters to download content -// from a URL which: -// -// - Publishes the percentage of the download completed to a channel. -// - May resume a previous download that was partially completed. -// -// Create an instance with the New() factory function. -type Download struct { - // net/http.Client to use when downloading the update. - // If nil, a default http.Client is used - HttpClient *http.Client - - // As bytes are downloaded, they are written to Target. - // Download also uses the Target's Seek method to determine - // the size of partial-downloads so that it may properly - // request the remaining bytes to resume the download. - Target Target - - // Progress returns the percentage of the download - // completed as an integer between 0 and 100 - Progress chan (int) - - // HTTP Method to use in the download request. Default is "GET" - Method string - - // HTTP URL to issue the download request to - Url string -} - -// New initializes a new Download object which will download -// the content from url into target. -func New(url string, target Target, httpClient *http.Client) *Download { - return &Download{ - HttpClient: httpClient, - Progress: make(chan int), - Method: "GET", - Url: url, - Target: target, - } -} - -// Get() downloads the content of a url to a target destination. -// -// Only HTTP/1.1 servers that implement the Range header support resuming a -// partially completed download. -// -// On success, the server must return 200 and the content, or 206 when resuming a partial download. -// If the HTTP server returns a 3XX redirect, it will be followed according to d.HttpClient's redirect policy. -// -func (d *Download) Get() (err error) { - // Close the progress channel whenever this function completes - defer close(d.Progress) - - // determine the size of the download target to determine if we're resuming a partial download - offset, err := d.Target.Size() - if err != nil { - return - } - - // create the download request - req, err := http.NewRequest(d.Method, d.Url, nil) - if err != nil { - return - } - - // create an http client if one does not exist - if d.HttpClient == nil { - d.HttpClient = http.DefaultClient - } - - // we have to add headers like this so they get used across redirects - trans := d.HttpClient.Transport - if trans == nil { - trans = http.DefaultTransport - } - - d.HttpClient.Transport = &roundTripper{ - RoundTripFn: func(r *http.Request) (*http.Response, error) { - // add header for download continuation - if offset > 0 { - r.Header.Add("Range", fmt.Sprintf("%d-", offset)) - } - - // ask for gzipped content so that net/http won't unzip it for us - // and destroy the content length header we need for progress calculations - r.Header.Add("Accept-Encoding", "gzip") - - return trans.RoundTrip(r) - }, - } - - // issue the download request - resp, err := d.HttpClient.Do(req) - if err != nil { - return - } - defer resp.Body.Close() - - switch resp.StatusCode { - // ok - case 200, 206: - - // server error - default: - err = fmt.Errorf("Non 2XX response when downloading update: %s", resp.Status) - return - } - - // Determine how much we have to download - // net/http sets this to -1 when it is unknown - clength := resp.ContentLength - - // Read the content from the response body - rd := resp.Body - - // meter the rate at which we download content for - // progress reporting if we know how much to expect - if clength > 0 { - rd = &meteredReader{rd: rd, totalSize: clength, progress: d.Progress} - } - - // Decompress the content if necessary - if resp.Header.Get("Content-Encoding") == "gzip" { - rd, err = gzip.NewReader(rd) - if err != nil { - return - } - } - - // Download the update - _, err = io.Copy(d.Target, rd) - if err != nil { - return - } - - return -} - -// meteredReader wraps a ReadCloser. Calls to a meteredReader's Read() method -// publish updates to a progress channel with the percentage read so far. -type meteredReader struct { - rd io.ReadCloser - totalSize int64 - progress chan int - totalRead int64 - ticks int64 -} - -func (m *meteredReader) Close() error { - return m.rd.Close() -} - -func (m *meteredReader) Read(b []byte) (n int, err error) { - chunkSize := (m.totalSize / 100) + 1 - lenB := int64(len(b)) - - var nChunk int - for start := int64(0); start < lenB; start += int64(nChunk) { - end := start + chunkSize - if end > lenB { - end = lenB - } - - nChunk, err = m.rd.Read(b[start:end]) - - n += nChunk - m.totalRead += int64(nChunk) - - if m.totalRead > (m.ticks * chunkSize) { - m.ticks += 1 - // try to send on channel, but don't block if it's full - select { - case m.progress <- int(m.ticks + 1): - default: - } - - // give the progress channel consumer a chance to run - runtime.Gosched() - } - - if err != nil { - return - } - } - - return -} - -// A Target is what you can supply to Download, -// it's just an io.Writer with a Size() method so that -// the a Download can "resume" an interrupted download -type Target interface { - io.Writer - Size() (int, error) -} - -type FileTarget struct { - *os.File -} - -func (t *FileTarget) Size() (int, error) { - if fi, err := t.File.Stat(); err != nil { - return 0, err - } else { - return int(fi.Size()), nil - } -} - -type MemoryTarget struct { - bytes.Buffer -} - -func (t *MemoryTarget) Size() (int, error) { - return t.Buffer.Len(), nil -} diff --git a/vendor/github.com/inconshreveable/go-update/hide_noop.go b/vendor/github.com/inconshreveable/go-update/hide_noop.go deleted file mode 100644 index 370775608..000000000 --- a/vendor/github.com/inconshreveable/go-update/hide_noop.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !windows - -package update - -func hideFile(path string) error { - return nil -} diff --git a/vendor/github.com/inconshreveable/go-update/hide_windows.go b/vendor/github.com/inconshreveable/go-update/hide_windows.go deleted file mode 100644 index c368b9cc4..000000000 --- a/vendor/github.com/inconshreveable/go-update/hide_windows.go +++ /dev/null @@ -1,19 +0,0 @@ -package update - -import ( - "syscall" - "unsafe" -) - -func hideFile(path string) error { - kernel32 := syscall.NewLazyDLL("kernel32.dll") - setFileAttributes := kernel32.NewProc("SetFileAttributesW") - - r1, _, err := setFileAttributes.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), 2) - - if r1 == 0 { - return err - } else { - return nil - } -} diff --git a/vendor/github.com/inconshreveable/go-update/update.go b/vendor/github.com/inconshreveable/go-update/update.go deleted file mode 100644 index 5f692f23b..000000000 --- a/vendor/github.com/inconshreveable/go-update/update.go +++ /dev/null @@ -1,491 +0,0 @@ -/* -go-update allows a program to update itself by replacing its executable file -with a new version. It provides the flexibility to implement different updating user experiences -like auto-updating, or manual user-initiated updates. It also boasts -advanced features like binary patching and code signing verification. - -Updating your program to a new version is as easy as: - - err, errRecover := update.New().FromUrl("http://release.example.com/2.0/myprogram") - if err != nil { - fmt.Printf("Update failed: %v\n", err) - } - -You may also choose to update from other data sources such as a file or an io.Reader: - - err, errRecover := update.New().FromFile("/path/to/update") - -Binary Diff Patching - -Binary diff updates are supported and easy to use: - - up := update.New().ApplyPatch(update.PATCHTYPE_BSDIFF) - err, errRecover := up.FromUrl("http://release.example.com/2.0/mypatch") - -Checksum Verification - -You should also verify the checksum of new updates as well as verify -the digital signature of an update. Note that even when you choose to apply -a patch, the checksum is verified against the complete update after that patch -has been applied. - - up := update.New().ApplyPatch(update.PATCHTYPE_BSDIFF).VerifyChecksum(checksum) - err, errRecover := up.FromUrl("http://release.example.com/2.0/mypatch") - -Updating other files - -Updating arbitrary files is also supported. You may update files which are -not the currently running program: - - up := update.New().Target("/usr/local/bin/some-program") - err, errRecover := up.FromUrl("http://release.example.com/2.0/some-program") - -Code Signing - -Truly secure updates use code signing to verify that the update was issued by a trusted party. -To do this, you'll need to generate a public/private key pair. You can do this with openssl, -or the equinox.io client (https://equinox.io/client) can easily generate one for you: - - # with equinox client - equinox genkey --private-key=private.pem --public-key=public.pem - - # with openssl - openssl genrsa -out private.pem 2048 - openssl rsa -in private.pem -out public.pem -pubout - -Once you have your key pair, you can instruct your program to validate its updates -with the public key: - - const publicKey = `-----BEGIN PUBLIC KEY----- - ... - -----END PUBLIC KEY-----` - - up, err := update.New().VerifySignatureWithPEM(publicKey) - if err != nil { - return fmt.Errorf("Bad public key: '%v': %v", publicKey, err) - } - -Once you've configured your program this way, it will disallow all updates unless they -are properly signed. You must now pass in the signature to verify with: - - up.VerifySignature(signature).FromUrl("http://dl.example.com/update") - -Error Handling and Recovery - -To perform an update, the process must be able to read its executable file and to write -to the directory that contains its executable file. It can be useful to check whether the process -has the necessary permissions to perform an update before trying to apply one. Use the -CanUpdate call to provide a useful message to the user if the update can't proceed without -elevated permissions: - - up := update.New().Target("/etc/hosts") - err := up.CanUpdate() - if err != nil { - fmt.Printf("Can't update because: '%v'. Try as root or Administrator\n", err) - return - } - err, errRecover := up.FromUrl("https://example.com/new/hosts") - -Although exceedingly unlikely, the update operation itself is not atomic and can fail -in such a way that a user's computer is left in an inconsistent state. If that happens, -go-update attempts to recover to leave the system in a good state. If the recovery step -fails (even more unlikely), a second error, referred to as "errRecover" will be non-nil -so that you may inform your users of the bad news. You should handle this case as shown -here: - - err, errRecover := up.FromUrl("https://example.com/update") - if err != nil { - fmt.Printf("Update failed: %v\n", err) - if errRecover != nil { - fmt.Printf("Failed to recover bad update: %v!\n", errRecover) - fmt.Printf("Program exectuable may be missing!\n") - } - } - -Subpackages - -Sub-package check contains the client functionality for a simple protocol for negotiating -whether a new update is available, where it is, and the metadata needed for verifying it. - -Sub-package download contains functionality for downloading from an HTTP endpoint -while outputting a progress meter and supports resuming partial downloads. -*/ -package update - -import ( - "bytes" - "crypto" - "crypto/rsa" - "crypto/sha256" - _ "crypto/sha512" // for tls cipher support - "crypto/x509" - "encoding/pem" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "path/filepath" - - "github.com/inconshreveable/go-update/download" - "github.com/kardianos/osext" - "github.com/kr/binarydist" -) - -// The type of a binary patch, if any. Only bsdiff is supported -type PatchType string - -const ( - PATCHTYPE_BSDIFF PatchType = "bsdiff" - PATCHTYPE_NONE = "" -) - -type Update struct { - // empty string means "path of the current executable" - TargetPath string - - // type of patch to apply. PATCHTYPE_NONE means "not a patch" - PatchType - - // sha256 checksum of the new binary to verify against - Checksum []byte - - // public key to use for signature verification - PublicKey *rsa.PublicKey - - // signature to use for signature verification - Signature []byte - - // configurable http client can be passed to download - HTTPClient *http.Client -} - -func (u *Update) getPath() (string, error) { - if u.TargetPath == "" { - return osext.Executable() - } else { - return u.TargetPath, nil - } -} - -// New creates a new Update object. -// A default update object assumes the complete binary -// content will be used for update (not a patch) and that -// the intended target is the running executable. -// -// Use this as the start of a chain of calls on the Update -// object to build up your configuration. Example: -// -// up := update.New().ApplyPatch(update.PATCHTYPE_BSDIFF).VerifyChecksum(checksum) -// -func New() *Update { - return &Update{ - TargetPath: "", - PatchType: PATCHTYPE_NONE, - } -} - -// Target configures the update to update the file at the given path. -// The emptry string means 'the executable file of the running program'. -func (u *Update) Target(path string) *Update { - u.TargetPath = path - return u -} - -// ApplyPatch configures the update to treat the contents of the update -// as a patch to apply to the existing to target. You must specify the -// format of the patch. Only PATCHTYPE_BSDIFF is supported at the moment. -func (u *Update) ApplyPatch(patchType PatchType) *Update { - u.PatchType = patchType - return u -} - -// VerifyChecksum configures the update to verify that the -// the update has the given sha256 checksum. -func (u *Update) VerifyChecksum(checksum []byte) *Update { - u.Checksum = checksum - return u -} - -// VerifySignature configures the update to verify the given -// signature of the update. You must also call one of the -// VerifySignatureWith* functions to specify a public key -// to use for verification. -func (u *Update) VerifySignature(signature []byte) *Update { - u.Signature = signature - return u -} - -// VerifySignatureWith configures the update to use the given RSA -// public key to verify the update's signature. You must also call -// VerifySignature() with a signature to check. -// -// You'll probably want to use VerifySignatureWithPEM instead of -// parsing the public key yourself. -func (u *Update) VerifySignatureWith(publicKey *rsa.PublicKey) *Update { - u.PublicKey = publicKey - return u -} - -// VerifySignatureWithPEM configures the update to use the given PEM-formatted -// RSA public key to verify the update's signature. You must also call -// VerifySignature() with a signature to check. -// -// A PEM formatted public key typically begins with -// -----BEGIN PUBLIC KEY----- -func (u *Update) VerifySignatureWithPEM(publicKeyPEM []byte) (*Update, error) { - block, _ := pem.Decode(publicKeyPEM) - if block == nil { - return u, fmt.Errorf("Couldn't parse PEM data") - } - - pub, err := x509.ParsePKIXPublicKey(block.Bytes) - if err != nil { - return u, err - } - - var ok bool - u.PublicKey, ok = pub.(*rsa.PublicKey) - if !ok { - return u, fmt.Errorf("Public key isn't an RSA public key") - } - - return u, nil -} - -// FromUrl updates the target with the contents of the given URL. -func (u *Update) FromUrl(url string) (err error, errRecover error) { - target := new(download.MemoryTarget) - err = download.New(url, target, u.HTTPClient).Get() - if err != nil { - return - } - - return u.FromStream(target) -} - -// FromFile updates the target the contents of the given file. -func (u *Update) FromFile(path string) (err error, errRecover error) { - // open the new updated contents - fp, err := os.Open(path) - if err != nil { - return - } - defer fp.Close() - - // do the update - return u.FromStream(fp) -} - -// FromStream updates the target file with the contents of the supplied io.Reader. -// -// FromStream performs the following actions to ensure a safe cross-platform update: -// -// 1. If configured, applies the contents of the io.Reader as a binary patch. -// -// 2. If configured, computes the sha256 checksum and verifies it matches. -// -// 3. If configured, verifies the RSA signature with a public key. -// -// 4. Creates a new file, /path/to/.target.new with mode 0755 with the contents of the updated file -// -// 5. Renames /path/to/target to /path/to/.target.old -// -// 6. Renames /path/to/.target.new to /path/to/target -// -// 7. If the rename is successful, deletes /path/to/.target.old, returns no error -// -// 8. If the rename fails, attempts to rename /path/to/.target.old back to /path/to/target -// If this operation fails, it is reported in the errRecover return value so as not to -// mask the original error that caused the recovery attempt. -// -// On Windows, the removal of /path/to/.target.old always fails, so instead, -// we just make the old file hidden instead. -func (u *Update) FromStream(updateWith io.Reader) (err error, errRecover error) { - updatePath, err := u.getPath() - if err != nil { - return - } - - var newBytes []byte - // apply a patch if requested - switch u.PatchType { - case PATCHTYPE_BSDIFF: - newBytes, err = applyPatch(updateWith, updatePath) - if err != nil { - return - } - case PATCHTYPE_NONE: - // no patch to apply, go on through - newBytes, err = ioutil.ReadAll(updateWith) - if err != nil { - return - } - default: - err = fmt.Errorf("Unrecognized patch type: %s", u.PatchType) - return - } - - // verify checksum if requested - if u.Checksum != nil { - if err = verifyChecksum(newBytes, u.Checksum); err != nil { - return - } - } - - // verify signature if requested - if u.Signature != nil || u.PublicKey != nil { - if u.Signature == nil { - err = fmt.Errorf("No public key specified to verify signature") - return - } - - if u.PublicKey == nil { - err = fmt.Errorf("No signature to verify!") - return - } - - if err = verifySignature(newBytes, u.Signature, u.PublicKey); err != nil { - return - } - } - - // get the directory the executable exists in - updateDir := filepath.Dir(updatePath) - filename := filepath.Base(updatePath) - - // Copy the contents of of newbinary to a the new executable file - newPath := filepath.Join(updateDir, fmt.Sprintf(".%s.new", filename)) - fp, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755) - if err != nil { - return - } - defer fp.Close() - _, err = io.Copy(fp, bytes.NewReader(newBytes)) - - // if we don't call fp.Close(), windows won't let us move the new executable - // because the file will still be "in use" - fp.Close() - - // this is where we'll move the executable to so that we can swap in the updated replacement - oldPath := filepath.Join(updateDir, fmt.Sprintf(".%s.old", filename)) - - // delete any existing old exec file - this is necessary on Windows for two reasons: - // 1. after a successful update, Windows can't remove the .old file because the process is still running - // 2. windows rename operations fail if the destination file already exists - _ = os.Remove(oldPath) - - // move the existing executable to a new file in the same directory - err = os.Rename(updatePath, oldPath) - if err != nil { - return - } - - // move the new exectuable in to become the new program - err = os.Rename(newPath, updatePath) - - if err != nil { - // copy unsuccessful - errRecover = os.Rename(oldPath, updatePath) - } else { - // copy successful, remove the old binary - errRemove := os.Remove(oldPath) - - // windows has trouble with removing old binaries, so hide it instead - if errRemove != nil { - _ = hideFile(oldPath) - } - } - - return -} - -// CanUpdate() determines whether the process has the correct permissions to -// perform the requested update. If the update can proceed, it returns nil, otherwise -// it returns the error that would occur if an update were attempted. -func (u *Update) CanUpdate() (err error) { - // get the directory the file exists in - path, err := u.getPath() - if err != nil { - return - } - - fileDir := filepath.Dir(path) - fileName := filepath.Base(path) - - // attempt to open a file in the file's directory - newPath := filepath.Join(fileDir, fmt.Sprintf(".%s.new", fileName)) - fp, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755) - if err != nil { - return - } - fp.Close() - - _ = os.Remove(newPath) - return -} - -func applyPatch(patch io.Reader, updatePath string) ([]byte, error) { - // open the file to update - old, err := os.Open(updatePath) - if err != nil { - return nil, err - } - defer old.Close() - - // apply the patch - applied := new(bytes.Buffer) - if err = binarydist.Patch(old, applied, patch); err != nil { - return nil, err - } - - return applied.Bytes(), nil -} - -func verifyChecksum(updated []byte, expectedChecksum []byte) error { - checksum, err := ChecksumForBytes(updated) - if err != nil { - return err - } - - if !bytes.Equal(expectedChecksum, checksum) { - return fmt.Errorf("Updated file has wrong checksum. Expected: %x, got: %x", expectedChecksum, checksum) - } - - return nil -} - -// ChecksumForFile returns the sha256 checksum for the given file -func ChecksumForFile(path string) ([]byte, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - - return ChecksumForReader(f) -} - -// ChecksumForReader returns the sha256 checksum for the entire -// contents of the given reader. -func ChecksumForReader(rd io.Reader) ([]byte, error) { - h := sha256.New() - if _, err := io.Copy(h, rd); err != nil { - return nil, err - } - return h.Sum(nil), nil -} - -// ChecksumForBytes returns the sha256 checksum for the given bytes -func ChecksumForBytes(source []byte) ([]byte, error) { - return ChecksumForReader(bytes.NewReader(source)) -} - -func verifySignature(source, signature []byte, publicKey *rsa.PublicKey) error { - checksum, err := ChecksumForBytes(source) - if err != nil { - return err - } - - return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, checksum, signature) -} diff --git a/vendor/github.com/itsjamie/gin-cors/README.md b/vendor/github.com/itsjamie/gin-cors/README.md deleted file mode 100644 index f5693fc93..000000000 --- a/vendor/github.com/itsjamie/gin-cors/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# CORS for Gin [![GoDoc](https://godoc.org/github.com/itsjamie/gin-cors?status.svg)](https://godoc.org/github.com/itsjamie/gin-cors) [![Build Status](https://travis-ci.org/itsjamie/gin-cors.svg?branch=master)](https://travis-ci.org/itsjamie/gin-cors) [![Coverage Status](https://coveralls.io/repos/itsjamie/gin-cors/badge.svg?branch=master)](https://coveralls.io/r/itsjamie/gin-cors?branch=master) - -gin-cors is a middleware written in [Go (Golang)](http://golang.org) specifically for the [Gin Framework](https://gin-gonic.github.io/gin/) that implements the [Cross Origin Resource Sharing specification](http://www.w3.org/TR/cors/) from the W3C. Implementing CORS headers enable pages within a modern web browser to consume resources (such as REST APIs) from servers that are on a different domain. - -## Getting Started -To use this library, add the following code into your Gin router setup: - -```go -import "github.com/itsjamie/gin-cors" - -// Initialize a new Gin router -router := gin.New() - -// Apply the middleware to the router (works with groups too) -router.Use(cors.Middleware(cors.Config{ - Origins: "*", - Methods: "GET, PUT, POST, DELETE", - RequestHeaders: "Origin, Authorization, Content-Type", - ExposedHeaders: "", - MaxAge: 50 * time.Second, - Credentials: true, - ValidateHeaders: false, -})) -``` - -## Setup Options -The middleware can be configured with four options, which match the HTTP headers that it generates: - -Parameter | Type | Details --------------------|-----------------|---------------------------------- -Origins | *string* | A comma delimited list of origins which have access. For example: ```"http://localhost, http://api.server.com, http://files.server.com"``` -RequestHeaders | *string* | A comma delimited list of allowed HTTP that is passed to the browser in the **Access-Control-Allow-Headers** header. -ExposeHeaders | *string* | A comma delimited list of HTTP headers that should be exposed to the CORS client via the **Access-Control-Expose-Headers** header. -Methods | *string* | A comma delimited list of allowed HTTP methods that is passed to the browser in the **Access-Control-Allow-Methods**. -MaxAge | *time.Duration* | The amount of time a preflight request should be cached, if not specified, the header **Access-Control-Max-Age** will not be set. -Credentials | *bool* | This is passed in the **Access-Control-Allow-Credentials** header. If ```true``` Cookies, HTTP authentication and the client-side SSL certificates will be sent on previous interactions with the origin. -ValidateHeaders | *bool* | If ```false``` we skip validating the requested headers/methods with the list of allowed ones, and instead just respond with all what we support, it is up to the client implementating CORS to deny the request. This is an optimization allowed by the specification. - - -## CORS Resources - -* [HTML Rocks Tutorial: Using CORS](http://www.html5rocks.com/en/tutorials/cors/) -* [Mozilla Developer Network: CORS Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) -* [CORS Specification from W3C](http://www.w3.org/TR/cors/) - -## Special Thanks -Special thanks to [benpate](https://github.com/benpate) for providing a foundation to work from. - -## License -The code is licensed under the MIT License. See LICENSE file for more details. diff --git a/vendor/github.com/itsjamie/gin-cors/cors.go b/vendor/github.com/itsjamie/gin-cors/cors.go index e9090f5d6..50d1f88d0 100644 --- a/vendor/github.com/itsjamie/gin-cors/cors.go +++ b/vendor/github.com/itsjamie/gin-cors/cors.go @@ -120,6 +120,7 @@ func Middleware(config Config) gin.HandlerFunc { return func(context *gin.Context) { // Read the Origin header from the HTTP request currentOrigin := context.Request.Header.Get(OriginKey) + context.Writer.Header().Add("Vary", OriginKey) // CORS headers are added whenever the browser request includes an "Origin" header // However, if no Origin is supplied, they should never be added. @@ -150,12 +151,14 @@ func Middleware(config Config) gin.HandlerFunc { if valid { - // Allowed origins cannot be the string "*" cannot be used for a resource that supports credentials. if config.Credentials { context.Writer.Header().Set(AllowCredentialsKey, config.credentials) + // Allowed origins cannot be the string "*" cannot be used for a resource that supports credentials. context.Writer.Header().Set(AllowOriginKey, currentOrigin) - } else { + } else if forceOriginMatch { context.Writer.Header().Set(AllowOriginKey, "*") + } else { + context.Writer.Header().Set(AllowOriginKey, currentOrigin) } //If this is a preflight request, we are finished, quit. @@ -232,11 +235,11 @@ func validateRequestHeaders(requestHeaders string, config Config) bool { return true } - headers := strings.Split(requestHeaders, ", ") + headers := strings.Split(requestHeaders, ",") for _, header := range headers { match := false - header = strings.ToLower(header) + header = strings.ToLower(strings.Trim(header, " \t\r\n")) for _, value := range config.requestHeaders { if value == header { diff --git a/vendor/github.com/json-iterator/go/LICENSE b/vendor/github.com/json-iterator/go/LICENSE new file mode 100644 index 000000000..2cf4f5ab2 --- /dev/null +++ b/vendor/github.com/json-iterator/go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 json-iterator + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/json-iterator/go/adapter.go b/vendor/github.com/json-iterator/go/adapter.go new file mode 100644 index 000000000..e674d0f39 --- /dev/null +++ b/vendor/github.com/json-iterator/go/adapter.go @@ -0,0 +1,150 @@ +package jsoniter + +import ( + "bytes" + "io" +) + +// RawMessage to make replace json with jsoniter +type RawMessage []byte + +// Unmarshal adapts to json/encoding Unmarshal API +// +// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. +// Refer to https://godoc.org/encoding/json#Unmarshal for more information +func Unmarshal(data []byte, v interface{}) error { + return ConfigDefault.Unmarshal(data, v) +} + +// UnmarshalFromString convenient method to read from string instead of []byte +func UnmarshalFromString(str string, v interface{}) error { + return ConfigDefault.UnmarshalFromString(str, v) +} + +// Get quick method to get value from deeply nested JSON structure +func Get(data []byte, path ...interface{}) Any { + return ConfigDefault.Get(data, path...) +} + +// Marshal adapts to json/encoding Marshal API +// +// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API +// Refer to https://godoc.org/encoding/json#Marshal for more information +func Marshal(v interface{}) ([]byte, error) { + return ConfigDefault.Marshal(v) +} + +// MarshalIndent same as json.MarshalIndent. Prefix is not supported. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + return ConfigDefault.MarshalIndent(v, prefix, indent) +} + +// MarshalToString convenient method to write as string instead of []byte +func MarshalToString(v interface{}) (string, error) { + return ConfigDefault.MarshalToString(v) +} + +// NewDecoder adapts to json/stream NewDecoder API. +// +// NewDecoder returns a new decoder that reads from r. +// +// Instead of a json/encoding Decoder, an Decoder is returned +// Refer to https://godoc.org/encoding/json#NewDecoder for more information +func NewDecoder(reader io.Reader) *Decoder { + return ConfigDefault.NewDecoder(reader) +} + +// Decoder reads and decodes JSON values from an input stream. +// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) +type Decoder struct { + iter *Iterator +} + +// Decode decode JSON into interface{} +func (adapter *Decoder) Decode(obj interface{}) error { + if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil { + if !adapter.iter.loadMore() { + return io.EOF + } + } + adapter.iter.ReadVal(obj) + err := adapter.iter.Error + if err == io.EOF { + return nil + } + return adapter.iter.Error +} + +// More is there more? +func (adapter *Decoder) More() bool { + iter := adapter.iter + if iter.Error != nil { + return false + } + c := iter.nextToken() + if c == 0 { + return false + } + iter.unreadByte() + return c != ']' && c != '}' +} + +// Buffered remaining buffer +func (adapter *Decoder) Buffered() io.Reader { + remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail] + return bytes.NewReader(remaining) +} + +// UseNumber causes the Decoder to unmarshal a number into an interface{} as a +// Number instead of as a float64. +func (adapter *Decoder) UseNumber() { + cfg := adapter.iter.cfg.configBeforeFrozen + cfg.UseNumber = true + adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) +} + +// DisallowUnknownFields causes the Decoder to return an error when the destination +// is a struct and the input contains object keys which do not match any +// non-ignored, exported fields in the destination. +func (adapter *Decoder) DisallowUnknownFields() { + cfg := adapter.iter.cfg.configBeforeFrozen + cfg.DisallowUnknownFields = true + adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) +} + +// NewEncoder same as json.NewEncoder +func NewEncoder(writer io.Writer) *Encoder { + return ConfigDefault.NewEncoder(writer) +} + +// Encoder same as json.Encoder +type Encoder struct { + stream *Stream +} + +// Encode encode interface{} as JSON to io.Writer +func (adapter *Encoder) Encode(val interface{}) error { + adapter.stream.WriteVal(val) + adapter.stream.WriteRaw("\n") + adapter.stream.Flush() + return adapter.stream.Error +} + +// SetIndent set the indention. Prefix is not supported +func (adapter *Encoder) SetIndent(prefix, indent string) { + config := adapter.stream.cfg.configBeforeFrozen + config.IndentionStep = len(indent) + adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) +} + +// SetEscapeHTML escape html by default, set to false to disable +func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { + config := adapter.stream.cfg.configBeforeFrozen + config.EscapeHTML = escapeHTML + adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) +} + +// Valid reports whether data is a valid JSON encoding. +func Valid(data []byte) bool { + return ConfigDefault.Valid(data) +} diff --git a/vendor/github.com/json-iterator/go/any.go b/vendor/github.com/json-iterator/go/any.go new file mode 100644 index 000000000..daecfed61 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any.go @@ -0,0 +1,321 @@ +package jsoniter + +import ( + "errors" + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "strconv" + "unsafe" +) + +// Any generic object representation. +// The lazy json implementation holds []byte and parse lazily. +type Any interface { + LastError() error + ValueType() ValueType + MustBeValid() Any + ToBool() bool + ToInt() int + ToInt32() int32 + ToInt64() int64 + ToUint() uint + ToUint32() uint32 + ToUint64() uint64 + ToFloat32() float32 + ToFloat64() float64 + ToString() string + ToVal(val interface{}) + Get(path ...interface{}) Any + Size() int + Keys() []string + GetInterface() interface{} + WriteTo(stream *Stream) +} + +type baseAny struct{} + +func (any *baseAny) Get(path ...interface{}) Any { + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} +} + +func (any *baseAny) Size() int { + return 0 +} + +func (any *baseAny) Keys() []string { + return []string{} +} + +func (any *baseAny) ToVal(obj interface{}) { + panic("not implemented") +} + +// WrapInt32 turn int32 into Any interface +func WrapInt32(val int32) Any { + return &int32Any{baseAny{}, val} +} + +// WrapInt64 turn int64 into Any interface +func WrapInt64(val int64) Any { + return &int64Any{baseAny{}, val} +} + +// WrapUint32 turn uint32 into Any interface +func WrapUint32(val uint32) Any { + return &uint32Any{baseAny{}, val} +} + +// WrapUint64 turn uint64 into Any interface +func WrapUint64(val uint64) Any { + return &uint64Any{baseAny{}, val} +} + +// WrapFloat64 turn float64 into Any interface +func WrapFloat64(val float64) Any { + return &floatAny{baseAny{}, val} +} + +// WrapString turn string into Any interface +func WrapString(val string) Any { + return &stringAny{baseAny{}, val} +} + +// Wrap turn a go object into Any interface +func Wrap(val interface{}) Any { + if val == nil { + return &nilAny{} + } + asAny, isAny := val.(Any) + if isAny { + return asAny + } + typ := reflect2.TypeOf(val) + switch typ.Kind() { + case reflect.Slice: + return wrapArray(val) + case reflect.Struct: + return wrapStruct(val) + case reflect.Map: + return wrapMap(val) + case reflect.String: + return WrapString(val.(string)) + case reflect.Int: + if strconv.IntSize == 32 { + return WrapInt32(int32(val.(int))) + } + return WrapInt64(int64(val.(int))) + case reflect.Int8: + return WrapInt32(int32(val.(int8))) + case reflect.Int16: + return WrapInt32(int32(val.(int16))) + case reflect.Int32: + return WrapInt32(val.(int32)) + case reflect.Int64: + return WrapInt64(val.(int64)) + case reflect.Uint: + if strconv.IntSize == 32 { + return WrapUint32(uint32(val.(uint))) + } + return WrapUint64(uint64(val.(uint))) + case reflect.Uintptr: + if ptrSize == 32 { + return WrapUint32(uint32(val.(uintptr))) + } + return WrapUint64(uint64(val.(uintptr))) + case reflect.Uint8: + return WrapUint32(uint32(val.(uint8))) + case reflect.Uint16: + return WrapUint32(uint32(val.(uint16))) + case reflect.Uint32: + return WrapUint32(uint32(val.(uint32))) + case reflect.Uint64: + return WrapUint64(val.(uint64)) + case reflect.Float32: + return WrapFloat64(float64(val.(float32))) + case reflect.Float64: + return WrapFloat64(val.(float64)) + case reflect.Bool: + if val.(bool) == true { + return &trueAny{} + } + return &falseAny{} + } + return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} +} + +// ReadAny read next JSON element as an Any object. It is a better json.RawMessage. +func (iter *Iterator) ReadAny() Any { + return iter.readAny() +} + +func (iter *Iterator) readAny() Any { + c := iter.nextToken() + switch c { + case '"': + iter.unreadByte() + return &stringAny{baseAny{}, iter.ReadString()} + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + return &nilAny{} + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + return &trueAny{} + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + return &falseAny{} + case '{': + return iter.readObjectAny() + case '[': + return iter.readArrayAny() + case '-': + return iter.readNumberAny(false) + case 0: + return &invalidAny{baseAny{}, errors.New("input is empty")} + default: + return iter.readNumberAny(true) + } +} + +func (iter *Iterator) readNumberAny(positive bool) Any { + iter.startCapture(iter.head - 1) + iter.skipNumber() + lazyBuf := iter.stopCapture() + return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readObjectAny() Any { + iter.startCapture(iter.head - 1) + iter.skipObject() + lazyBuf := iter.stopCapture() + return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readArrayAny() Any { + iter.startCapture(iter.head - 1) + iter.skipArray() + lazyBuf := iter.stopCapture() + return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func locateObjectField(iter *Iterator, target string) []byte { + var found []byte + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + if field == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + return true + }) + return found +} + +func locateArrayElement(iter *Iterator, target int) []byte { + var found []byte + n := 0 + iter.ReadArrayCB(func(iter *Iterator) bool { + if n == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + n++ + return true + }) + return found +} + +func locatePath(iter *Iterator, path []interface{}) Any { + for i, pathKeyObj := range path { + switch pathKey := pathKeyObj.(type) { + case string: + valueBytes := locateObjectField(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int: + valueBytes := locateArrayElement(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int32: + if '*' == pathKey { + return iter.readAny().Get(path[i:]...) + } + return newInvalidAny(path[i:]) + default: + return newInvalidAny(path[i:]) + } + } + if iter.Error != nil && iter.Error != io.EOF { + return &invalidAny{baseAny{}, iter.Error} + } + return iter.readAny() +} + +var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem() + +func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ == anyType { + return &directAnyCodec{} + } + if typ.Implements(anyType) { + return &anyCodec{ + valType: typ, + } + } + return nil +} + +func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == anyType { + return &directAnyCodec{} + } + if typ.Implements(anyType) { + return &anyCodec{ + valType: typ, + } + } + return nil +} + +type anyCodec struct { + valType reflect2.Type +} + +func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + panic("not implemented") +} + +func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + any.WriteTo(stream) +} + +func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + return any.Size() == 0 +} + +type directAnyCodec struct { +} + +func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *(*Any)(ptr) = iter.readAny() +} + +func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + any := *(*Any)(ptr) + any.WriteTo(stream) +} + +func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool { + any := *(*Any)(ptr) + return any.Size() == 0 +} diff --git a/vendor/github.com/json-iterator/go/any_array.go b/vendor/github.com/json-iterator/go/any_array.go new file mode 100644 index 000000000..0449e9aa4 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_array.go @@ -0,0 +1,278 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type arrayLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *arrayLazyAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayLazyAny) MustBeValid() Any { + return any +} + +func (any *arrayLazyAny) LastError() error { + return any.err +} + +func (any *arrayLazyAny) ToBool() bool { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.ReadArray() +} + +func (any *arrayLazyAny) ToInt() int { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt32() int32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt64() int64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint() uint { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint32() uint32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint64() uint64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat32() float32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat64() float64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *arrayLazyAny) ToVal(val interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(val) +} + +func (any *arrayLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateArrayElement(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + arr := make([]Any, 0) + iter.ReadArrayCB(func(iter *Iterator) bool { + found := iter.readAny().Get(path[1:]...) + if found.ValueType() != InvalidValue { + arr = append(arr, found) + } + return true + }) + return wrapArray(arr) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadArrayCB(func(iter *Iterator) bool { + size++ + iter.Skip() + return true + }) + return size +} + +func (any *arrayLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *arrayLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type arrayAny struct { + baseAny + val reflect.Value +} + +func wrapArray(val interface{}) *arrayAny { + return &arrayAny{baseAny{}, reflect.ValueOf(val)} +} + +func (any *arrayAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayAny) MustBeValid() Any { + return any +} + +func (any *arrayAny) LastError() error { + return nil +} + +func (any *arrayAny) ToBool() bool { + return any.val.Len() != 0 +} + +func (any *arrayAny) ToInt() int { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt32() int32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt64() int64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint() uint { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint32() uint32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint64() uint64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat32() float32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat64() float64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToString() string { + str, _ := MarshalToString(any.val.Interface()) + return str +} + +func (any *arrayAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + if firstPath < 0 || firstPath >= any.val.Len() { + return newInvalidAny(path) + } + return Wrap(any.val.Index(firstPath).Interface()) + case int32: + if '*' == firstPath { + mappedAll := make([]Any, 0) + for i := 0; i < any.val.Len(); i++ { + mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll = append(mappedAll, mapped) + } + } + return wrapArray(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayAny) Size() int { + return any.val.Len() +} + +func (any *arrayAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *arrayAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/vendor/github.com/json-iterator/go/any_bool.go b/vendor/github.com/json-iterator/go/any_bool.go new file mode 100644 index 000000000..9452324af --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_bool.go @@ -0,0 +1,137 @@ +package jsoniter + +type trueAny struct { + baseAny +} + +func (any *trueAny) LastError() error { + return nil +} + +func (any *trueAny) ToBool() bool { + return true +} + +func (any *trueAny) ToInt() int { + return 1 +} + +func (any *trueAny) ToInt32() int32 { + return 1 +} + +func (any *trueAny) ToInt64() int64 { + return 1 +} + +func (any *trueAny) ToUint() uint { + return 1 +} + +func (any *trueAny) ToUint32() uint32 { + return 1 +} + +func (any *trueAny) ToUint64() uint64 { + return 1 +} + +func (any *trueAny) ToFloat32() float32 { + return 1 +} + +func (any *trueAny) ToFloat64() float64 { + return 1 +} + +func (any *trueAny) ToString() string { + return "true" +} + +func (any *trueAny) WriteTo(stream *Stream) { + stream.WriteTrue() +} + +func (any *trueAny) Parse() *Iterator { + return nil +} + +func (any *trueAny) GetInterface() interface{} { + return true +} + +func (any *trueAny) ValueType() ValueType { + return BoolValue +} + +func (any *trueAny) MustBeValid() Any { + return any +} + +type falseAny struct { + baseAny +} + +func (any *falseAny) LastError() error { + return nil +} + +func (any *falseAny) ToBool() bool { + return false +} + +func (any *falseAny) ToInt() int { + return 0 +} + +func (any *falseAny) ToInt32() int32 { + return 0 +} + +func (any *falseAny) ToInt64() int64 { + return 0 +} + +func (any *falseAny) ToUint() uint { + return 0 +} + +func (any *falseAny) ToUint32() uint32 { + return 0 +} + +func (any *falseAny) ToUint64() uint64 { + return 0 +} + +func (any *falseAny) ToFloat32() float32 { + return 0 +} + +func (any *falseAny) ToFloat64() float64 { + return 0 +} + +func (any *falseAny) ToString() string { + return "false" +} + +func (any *falseAny) WriteTo(stream *Stream) { + stream.WriteFalse() +} + +func (any *falseAny) Parse() *Iterator { + return nil +} + +func (any *falseAny) GetInterface() interface{} { + return false +} + +func (any *falseAny) ValueType() ValueType { + return BoolValue +} + +func (any *falseAny) MustBeValid() Any { + return any +} diff --git a/vendor/github.com/json-iterator/go/any_float.go b/vendor/github.com/json-iterator/go/any_float.go new file mode 100644 index 000000000..35fdb0949 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_float.go @@ -0,0 +1,83 @@ +package jsoniter + +import ( + "strconv" +) + +type floatAny struct { + baseAny + val float64 +} + +func (any *floatAny) Parse() *Iterator { + return nil +} + +func (any *floatAny) ValueType() ValueType { + return NumberValue +} + +func (any *floatAny) MustBeValid() Any { + return any +} + +func (any *floatAny) LastError() error { + return nil +} + +func (any *floatAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *floatAny) ToInt() int { + return int(any.val) +} + +func (any *floatAny) ToInt32() int32 { + return int32(any.val) +} + +func (any *floatAny) ToInt64() int64 { + return int64(any.val) +} + +func (any *floatAny) ToUint() uint { + if any.val > 0 { + return uint(any.val) + } + return 0 +} + +func (any *floatAny) ToUint32() uint32 { + if any.val > 0 { + return uint32(any.val) + } + return 0 +} + +func (any *floatAny) ToUint64() uint64 { + if any.val > 0 { + return uint64(any.val) + } + return 0 +} + +func (any *floatAny) ToFloat32() float32 { + return float32(any.val) +} + +func (any *floatAny) ToFloat64() float64 { + return any.val +} + +func (any *floatAny) ToString() string { + return strconv.FormatFloat(any.val, 'E', -1, 64) +} + +func (any *floatAny) WriteTo(stream *Stream) { + stream.WriteFloat64(any.val) +} + +func (any *floatAny) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_int32.go b/vendor/github.com/json-iterator/go/any_int32.go new file mode 100644 index 000000000..1b56f3991 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_int32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int32Any struct { + baseAny + val int32 +} + +func (any *int32Any) LastError() error { + return nil +} + +func (any *int32Any) ValueType() ValueType { + return NumberValue +} + +func (any *int32Any) MustBeValid() Any { + return any +} + +func (any *int32Any) ToBool() bool { + return any.val != 0 +} + +func (any *int32Any) ToInt() int { + return int(any.val) +} + +func (any *int32Any) ToInt32() int32 { + return any.val +} + +func (any *int32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *int32Any) ToUint() uint { + return uint(any.val) +} + +func (any *int32Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *int32Any) WriteTo(stream *Stream) { + stream.WriteInt32(any.val) +} + +func (any *int32Any) Parse() *Iterator { + return nil +} + +func (any *int32Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_int64.go b/vendor/github.com/json-iterator/go/any_int64.go new file mode 100644 index 000000000..c440d72b6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_int64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int64Any struct { + baseAny + val int64 +} + +func (any *int64Any) LastError() error { + return nil +} + +func (any *int64Any) ValueType() ValueType { + return NumberValue +} + +func (any *int64Any) MustBeValid() Any { + return any +} + +func (any *int64Any) ToBool() bool { + return any.val != 0 +} + +func (any *int64Any) ToInt() int { + return int(any.val) +} + +func (any *int64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *int64Any) ToInt64() int64 { + return any.val +} + +func (any *int64Any) ToUint() uint { + return uint(any.val) +} + +func (any *int64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int64Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int64Any) ToString() string { + return strconv.FormatInt(any.val, 10) +} + +func (any *int64Any) WriteTo(stream *Stream) { + stream.WriteInt64(any.val) +} + +func (any *int64Any) Parse() *Iterator { + return nil +} + +func (any *int64Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_invalid.go b/vendor/github.com/json-iterator/go/any_invalid.go new file mode 100644 index 000000000..1d859eac3 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_invalid.go @@ -0,0 +1,82 @@ +package jsoniter + +import "fmt" + +type invalidAny struct { + baseAny + err error +} + +func newInvalidAny(path []interface{}) *invalidAny { + return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)} +} + +func (any *invalidAny) LastError() error { + return any.err +} + +func (any *invalidAny) ValueType() ValueType { + return InvalidValue +} + +func (any *invalidAny) MustBeValid() Any { + panic(any.err) +} + +func (any *invalidAny) ToBool() bool { + return false +} + +func (any *invalidAny) ToInt() int { + return 0 +} + +func (any *invalidAny) ToInt32() int32 { + return 0 +} + +func (any *invalidAny) ToInt64() int64 { + return 0 +} + +func (any *invalidAny) ToUint() uint { + return 0 +} + +func (any *invalidAny) ToUint32() uint32 { + return 0 +} + +func (any *invalidAny) ToUint64() uint64 { + return 0 +} + +func (any *invalidAny) ToFloat32() float32 { + return 0 +} + +func (any *invalidAny) ToFloat64() float64 { + return 0 +} + +func (any *invalidAny) ToString() string { + return "" +} + +func (any *invalidAny) WriteTo(stream *Stream) { +} + +func (any *invalidAny) Get(path ...interface{}) Any { + if any.err == nil { + return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)} + } + return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)} +} + +func (any *invalidAny) Parse() *Iterator { + return nil +} + +func (any *invalidAny) GetInterface() interface{} { + return nil +} diff --git a/vendor/github.com/json-iterator/go/any_nil.go b/vendor/github.com/json-iterator/go/any_nil.go new file mode 100644 index 000000000..d04cb54c1 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_nil.go @@ -0,0 +1,69 @@ +package jsoniter + +type nilAny struct { + baseAny +} + +func (any *nilAny) LastError() error { + return nil +} + +func (any *nilAny) ValueType() ValueType { + return NilValue +} + +func (any *nilAny) MustBeValid() Any { + return any +} + +func (any *nilAny) ToBool() bool { + return false +} + +func (any *nilAny) ToInt() int { + return 0 +} + +func (any *nilAny) ToInt32() int32 { + return 0 +} + +func (any *nilAny) ToInt64() int64 { + return 0 +} + +func (any *nilAny) ToUint() uint { + return 0 +} + +func (any *nilAny) ToUint32() uint32 { + return 0 +} + +func (any *nilAny) ToUint64() uint64 { + return 0 +} + +func (any *nilAny) ToFloat32() float32 { + return 0 +} + +func (any *nilAny) ToFloat64() float64 { + return 0 +} + +func (any *nilAny) ToString() string { + return "" +} + +func (any *nilAny) WriteTo(stream *Stream) { + stream.WriteNil() +} + +func (any *nilAny) Parse() *Iterator { + return nil +} + +func (any *nilAny) GetInterface() interface{} { + return nil +} diff --git a/vendor/github.com/json-iterator/go/any_number.go b/vendor/github.com/json-iterator/go/any_number.go new file mode 100644 index 000000000..9d1e901a6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_number.go @@ -0,0 +1,123 @@ +package jsoniter + +import ( + "io" + "unsafe" +) + +type numberLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *numberLazyAny) ValueType() ValueType { + return NumberValue +} + +func (any *numberLazyAny) MustBeValid() Any { + return any +} + +func (any *numberLazyAny) LastError() error { + return any.err +} + +func (any *numberLazyAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *numberLazyAny) ToInt() int { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToInt32() int32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToInt64() int64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint() uint { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint32() uint32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint64() uint64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToFloat32() float32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToFloat64() float64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *numberLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *numberLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} diff --git a/vendor/github.com/json-iterator/go/any_object.go b/vendor/github.com/json-iterator/go/any_object.go new file mode 100644 index 000000000..c44ef5c98 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_object.go @@ -0,0 +1,374 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type objectLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *objectLazyAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectLazyAny) MustBeValid() Any { + return any +} + +func (any *objectLazyAny) LastError() error { + return any.err +} + +func (any *objectLazyAny) ToBool() bool { + return true +} + +func (any *objectLazyAny) ToInt() int { + return 0 +} + +func (any *objectLazyAny) ToInt32() int32 { + return 0 +} + +func (any *objectLazyAny) ToInt64() int64 { + return 0 +} + +func (any *objectLazyAny) ToUint() uint { + return 0 +} + +func (any *objectLazyAny) ToUint32() uint32 { + return 0 +} + +func (any *objectLazyAny) ToUint64() uint64 { + return 0 +} + +func (any *objectLazyAny) ToFloat32() float32 { + return 0 +} + +func (any *objectLazyAny) ToFloat64() float64 { + return 0 +} + +func (any *objectLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *objectLazyAny) ToVal(obj interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(obj) +} + +func (any *objectLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateObjectField(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + mapped := locatePath(iter, path[1:]) + if mapped.ValueType() != InvalidValue { + mappedAll[field] = mapped + } + return true + }) + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectLazyAny) Keys() []string { + keys := []string{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + iter.Skip() + keys = append(keys, field) + return true + }) + return keys +} + +func (any *objectLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + size++ + return true + }) + return size +} + +func (any *objectLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *objectLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type objectAny struct { + baseAny + err error + val reflect.Value +} + +func wrapStruct(val interface{}) *objectAny { + return &objectAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *objectAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectAny) MustBeValid() Any { + return any +} + +func (any *objectAny) Parse() *Iterator { + return nil +} + +func (any *objectAny) LastError() error { + return any.err +} + +func (any *objectAny) ToBool() bool { + return any.val.NumField() != 0 +} + +func (any *objectAny) ToInt() int { + return 0 +} + +func (any *objectAny) ToInt32() int32 { + return 0 +} + +func (any *objectAny) ToInt64() int64 { + return 0 +} + +func (any *objectAny) ToUint() uint { + return 0 +} + +func (any *objectAny) ToUint32() uint32 { + return 0 +} + +func (any *objectAny) ToUint64() uint64 { + return 0 +} + +func (any *objectAny) ToFloat32() float32 { + return 0 +} + +func (any *objectAny) ToFloat64() float64 { + return 0 +} + +func (any *objectAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *objectAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + field := any.val.FieldByName(firstPath) + if !field.IsValid() { + return newInvalidAny(path) + } + return Wrap(field.Interface()) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for i := 0; i < any.val.NumField(); i++ { + field := any.val.Field(i) + if field.CanInterface() { + mapped := Wrap(field.Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[any.val.Type().Field(i).Name] = mapped + } + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectAny) Keys() []string { + keys := make([]string, 0, any.val.NumField()) + for i := 0; i < any.val.NumField(); i++ { + keys = append(keys, any.val.Type().Field(i).Name) + } + return keys +} + +func (any *objectAny) Size() int { + return any.val.NumField() +} + +func (any *objectAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *objectAny) GetInterface() interface{} { + return any.val.Interface() +} + +type mapAny struct { + baseAny + err error + val reflect.Value +} + +func wrapMap(val interface{}) *mapAny { + return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *mapAny) ValueType() ValueType { + return ObjectValue +} + +func (any *mapAny) MustBeValid() Any { + return any +} + +func (any *mapAny) Parse() *Iterator { + return nil +} + +func (any *mapAny) LastError() error { + return any.err +} + +func (any *mapAny) ToBool() bool { + return true +} + +func (any *mapAny) ToInt() int { + return 0 +} + +func (any *mapAny) ToInt32() int32 { + return 0 +} + +func (any *mapAny) ToInt64() int64 { + return 0 +} + +func (any *mapAny) ToUint() uint { + return 0 +} + +func (any *mapAny) ToUint32() uint32 { + return 0 +} + +func (any *mapAny) ToUint64() uint64 { + return 0 +} + +func (any *mapAny) ToFloat32() float32 { + return 0 +} + +func (any *mapAny) ToFloat64() float64 { + return 0 +} + +func (any *mapAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *mapAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for _, key := range any.val.MapKeys() { + keyAsStr := key.String() + element := Wrap(any.val.MapIndex(key).Interface()) + mapped := element.Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[keyAsStr] = mapped + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + value := any.val.MapIndex(reflect.ValueOf(firstPath)) + if !value.IsValid() { + return newInvalidAny(path) + } + return Wrap(value.Interface()) + } +} + +func (any *mapAny) Keys() []string { + keys := make([]string, 0, any.val.Len()) + for _, key := range any.val.MapKeys() { + keys = append(keys, key.String()) + } + return keys +} + +func (any *mapAny) Size() int { + return any.val.Len() +} + +func (any *mapAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *mapAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/vendor/github.com/json-iterator/go/any_str.go b/vendor/github.com/json-iterator/go/any_str.go new file mode 100644 index 000000000..a4b93c78c --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_str.go @@ -0,0 +1,166 @@ +package jsoniter + +import ( + "fmt" + "strconv" +) + +type stringAny struct { + baseAny + val string +} + +func (any *stringAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} +} + +func (any *stringAny) Parse() *Iterator { + return nil +} + +func (any *stringAny) ValueType() ValueType { + return StringValue +} + +func (any *stringAny) MustBeValid() Any { + return any +} + +func (any *stringAny) LastError() error { + return nil +} + +func (any *stringAny) ToBool() bool { + str := any.ToString() + if str == "0" { + return false + } + for _, c := range str { + switch c { + case ' ', '\n', '\r', '\t': + default: + return true + } + } + return false +} + +func (any *stringAny) ToInt() int { + return int(any.ToInt64()) + +} + +func (any *stringAny) ToInt32() int32 { + return int32(any.ToInt64()) +} + +func (any *stringAny) ToInt64() int64 { + if any.val == "" { + return 0 + } + + flag := 1 + startPos := 0 + endPos := 0 + if any.val[0] == '+' || any.val[0] == '-' { + startPos = 1 + } + + if any.val[0] == '-' { + flag = -1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) + return int64(flag) * parsed +} + +func (any *stringAny) ToUint() uint { + return uint(any.ToUint64()) +} + +func (any *stringAny) ToUint32() uint32 { + return uint32(any.ToUint64()) +} + +func (any *stringAny) ToUint64() uint64 { + if any.val == "" { + return 0 + } + + startPos := 0 + endPos := 0 + + if any.val[0] == '-' { + return 0 + } + if any.val[0] == '+' { + startPos = 1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) + return parsed +} + +func (any *stringAny) ToFloat32() float32 { + return float32(any.ToFloat64()) +} + +func (any *stringAny) ToFloat64() float64 { + if len(any.val) == 0 { + return 0 + } + + // first char invalid + if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') { + return 0 + } + + // extract valid num expression from string + // eg 123true => 123, -12.12xxa => -12.12 + endPos := 1 + for i := 1; i < len(any.val); i++ { + if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' { + endPos = i + 1 + continue + } + + // end position is the first char which is not digit + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + endPos = i + break + } + } + parsed, _ := strconv.ParseFloat(any.val[:endPos], 64) + return parsed +} + +func (any *stringAny) ToString() string { + return any.val +} + +func (any *stringAny) WriteTo(stream *Stream) { + stream.WriteString(any.val) +} + +func (any *stringAny) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_uint32.go b/vendor/github.com/json-iterator/go/any_uint32.go new file mode 100644 index 000000000..656bbd33d --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_uint32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint32Any struct { + baseAny + val uint32 +} + +func (any *uint32Any) LastError() error { + return nil +} + +func (any *uint32Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint32Any) MustBeValid() Any { + return any +} + +func (any *uint32Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint32Any) ToInt() int { + return int(any.val) +} + +func (any *uint32Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint32Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint32Any) ToUint32() uint32 { + return any.val +} + +func (any *uint32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *uint32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *uint32Any) WriteTo(stream *Stream) { + stream.WriteUint32(any.val) +} + +func (any *uint32Any) Parse() *Iterator { + return nil +} + +func (any *uint32Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_uint64.go b/vendor/github.com/json-iterator/go/any_uint64.go new file mode 100644 index 000000000..7df2fce33 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_uint64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint64Any struct { + baseAny + val uint64 +} + +func (any *uint64Any) LastError() error { + return nil +} + +func (any *uint64Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint64Any) MustBeValid() Any { + return any +} + +func (any *uint64Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint64Any) ToInt() int { + return int(any.val) +} + +func (any *uint64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint64Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint64Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *uint64Any) ToUint64() uint64 { + return any.val +} + +func (any *uint64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint64Any) ToString() string { + return strconv.FormatUint(any.val, 10) +} + +func (any *uint64Any) WriteTo(stream *Stream) { + stream.WriteUint64(any.val) +} + +func (any *uint64Any) Parse() *Iterator { + return nil +} + +func (any *uint64Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go new file mode 100644 index 000000000..8c58fcba5 --- /dev/null +++ b/vendor/github.com/json-iterator/go/config.go @@ -0,0 +1,375 @@ +package jsoniter + +import ( + "encoding/json" + "io" + "reflect" + "sync" + "unsafe" + + "github.com/modern-go/concurrent" + "github.com/modern-go/reflect2" +) + +// Config customize how the API should behave. +// The API is created from Config by Froze. +type Config struct { + IndentionStep int + MarshalFloatWith6Digits bool + EscapeHTML bool + SortMapKeys bool + UseNumber bool + DisallowUnknownFields bool + TagKey string + OnlyTaggedField bool + ValidateJsonRawMessage bool + ObjectFieldMustBeSimpleString bool + CaseSensitive bool +} + +// API the public interface of this package. +// Primary Marshal and Unmarshal. +type API interface { + IteratorPool + StreamPool + MarshalToString(v interface{}) (string, error) + Marshal(v interface{}) ([]byte, error) + MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) + UnmarshalFromString(str string, v interface{}) error + Unmarshal(data []byte, v interface{}) error + Get(data []byte, path ...interface{}) Any + NewEncoder(writer io.Writer) *Encoder + NewDecoder(reader io.Reader) *Decoder + Valid(data []byte) bool + RegisterExtension(extension Extension) + DecoderOf(typ reflect2.Type) ValDecoder + EncoderOf(typ reflect2.Type) ValEncoder +} + +// ConfigDefault the default API +var ConfigDefault = Config{ + EscapeHTML: true, +}.Froze() + +// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior +var ConfigCompatibleWithStandardLibrary = Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, +}.Froze() + +// ConfigFastest marshals float with only 6 digits precision +var ConfigFastest = Config{ + EscapeHTML: false, + MarshalFloatWith6Digits: true, // will lose precession + ObjectFieldMustBeSimpleString: true, // do not unescape object field +}.Froze() + +type frozenConfig struct { + configBeforeFrozen Config + sortMapKeys bool + indentionStep int + objectFieldMustBeSimpleString bool + onlyTaggedField bool + disallowUnknownFields bool + decoderCache *concurrent.Map + encoderCache *concurrent.Map + encoderExtension Extension + decoderExtension Extension + extraExtensions []Extension + streamPool *sync.Pool + iteratorPool *sync.Pool + caseSensitive bool +} + +func (cfg *frozenConfig) initCache() { + cfg.decoderCache = concurrent.NewMap() + cfg.encoderCache = concurrent.NewMap() +} + +func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { + cfg.decoderCache.Store(cacheKey, decoder) +} + +func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { + cfg.encoderCache.Store(cacheKey, encoder) +} + +func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { + decoder, found := cfg.decoderCache.Load(cacheKey) + if found { + return decoder.(ValDecoder) + } + return nil +} + +func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { + encoder, found := cfg.encoderCache.Load(cacheKey) + if found { + return encoder.(ValEncoder) + } + return nil +} + +var cfgCache = concurrent.NewMap() + +func getFrozenConfigFromCache(cfg Config) *frozenConfig { + obj, found := cfgCache.Load(cfg) + if found { + return obj.(*frozenConfig) + } + return nil +} + +func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { + cfgCache.Store(cfg, frozenConfig) +} + +// Froze forge API from config +func (cfg Config) Froze() API { + api := &frozenConfig{ + sortMapKeys: cfg.SortMapKeys, + indentionStep: cfg.IndentionStep, + objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, + onlyTaggedField: cfg.OnlyTaggedField, + disallowUnknownFields: cfg.DisallowUnknownFields, + caseSensitive: cfg.CaseSensitive, + } + api.streamPool = &sync.Pool{ + New: func() interface{} { + return NewStream(api, nil, 512) + }, + } + api.iteratorPool = &sync.Pool{ + New: func() interface{} { + return NewIterator(api) + }, + } + api.initCache() + encoderExtension := EncoderExtension{} + decoderExtension := DecoderExtension{} + if cfg.MarshalFloatWith6Digits { + api.marshalFloatWith6Digits(encoderExtension) + } + if cfg.EscapeHTML { + api.escapeHTML(encoderExtension) + } + if cfg.UseNumber { + api.useNumber(decoderExtension) + } + if cfg.ValidateJsonRawMessage { + api.validateJsonRawMessage(encoderExtension) + } + api.encoderExtension = encoderExtension + api.decoderExtension = decoderExtension + api.configBeforeFrozen = cfg + return api +} + +func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig { + api := getFrozenConfigFromCache(cfg) + if api != nil { + return api + } + api = cfg.Froze().(*frozenConfig) + for _, extension := range extraExtensions { + api.RegisterExtension(extension) + } + addFrozenConfigToCache(cfg, api) + return api +} + +func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) { + encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) { + rawMessage := *(*json.RawMessage)(ptr) + iter := cfg.BorrowIterator([]byte(rawMessage)) + iter.Read() + if iter.Error != nil { + stream.WriteRaw("null") + } else { + cfg.ReturnIterator(iter) + stream.WriteRaw(string(rawMessage)) + } + }, func(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 + }} + extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder + extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder +} + +func (cfg *frozenConfig) useNumber(extension DecoderExtension) { + extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { + exitingValue := *((*interface{})(ptr)) + if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr { + iter.ReadVal(exitingValue) + return + } + if iter.WhatIsNext() == NumberValue { + *((*interface{})(ptr)) = json.Number(iter.readNumberAsString()) + } else { + *((*interface{})(ptr)) = iter.Read() + } + }} +} +func (cfg *frozenConfig) getTagKey() string { + tagKey := cfg.configBeforeFrozen.TagKey + if tagKey == "" { + return "json" + } + return tagKey +} + +func (cfg *frozenConfig) RegisterExtension(extension Extension) { + cfg.extraExtensions = append(cfg.extraExtensions, extension) + copied := cfg.configBeforeFrozen + cfg.configBeforeFrozen = copied +} + +type lossyFloat32Encoder struct { +} + +func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32Lossy(*((*float32)(ptr))) +} + +func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type lossyFloat64Encoder struct { +} + +func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64Lossy(*((*float64)(ptr))) +} + +func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +// EnableLossyFloatMarshalling keeps 10**(-6) precision +// for float variables for better performance. +func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) { + // for better performance + extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{} + extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{} +} + +type htmlEscapedStringEncoder struct { +} + +func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteStringWithHTMLEscaped(str) +} + +func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) { + encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{} +} + +func (cfg *frozenConfig) cleanDecoders() { + typeDecoders = map[string]ValDecoder{} + fieldDecoders = map[string]ValDecoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) cleanEncoders() { + typeEncoders = map[string]ValEncoder{} + fieldEncoders = map[string]ValEncoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return "", stream.Error + } + return string(stream.Buffer()), nil +} + +func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return nil, stream.Error + } + result := stream.Buffer() + copied := make([]byte, len(result)) + copy(copied, result) + return copied, nil +} + +func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + if prefix != "" { + panic("prefix is not supported") + } + for _, r := range indent { + if r != ' ' { + panic("indent can only be space") + } + } + newCfg := cfg.configBeforeFrozen + newCfg.IndentionStep = len(indent) + return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v) +} + +func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error { + data := []byte(str) + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + c := iter.nextToken() + if c == 0 { + if iter.Error == io.EOF { + return nil + } + return iter.Error + } + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + return iter.Error +} + +func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + return locatePath(iter, path) +} + +func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + c := iter.nextToken() + if c == 0 { + if iter.Error == io.EOF { + return nil + } + return iter.Error + } + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + return iter.Error +} + +func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder { + stream := NewStream(cfg, writer, 512) + return &Encoder{stream} +} + +func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder { + iter := Parse(cfg, reader, 512) + return &Decoder{iter} +} + +func (cfg *frozenConfig) Valid(data []byte) bool { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.Skip() + return iter.Error == nil +} diff --git a/vendor/github.com/json-iterator/go/iter.go b/vendor/github.com/json-iterator/go/iter.go new file mode 100644 index 000000000..95ae54fbf --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter.go @@ -0,0 +1,322 @@ +package jsoniter + +import ( + "encoding/json" + "fmt" + "io" +) + +// ValueType the type for JSON element +type ValueType int + +const ( + // InvalidValue invalid JSON element + InvalidValue ValueType = iota + // StringValue JSON element "string" + StringValue + // NumberValue JSON element 100 or 0.10 + NumberValue + // NilValue JSON element null + NilValue + // BoolValue JSON element true or false + BoolValue + // ArrayValue JSON element [] + ArrayValue + // ObjectValue JSON element {} + ObjectValue +) + +var hexDigits []byte +var valueTypes []ValueType + +func init() { + hexDigits = make([]byte, 256) + for i := 0; i < len(hexDigits); i++ { + hexDigits[i] = 255 + } + for i := '0'; i <= '9'; i++ { + hexDigits[i] = byte(i - '0') + } + for i := 'a'; i <= 'f'; i++ { + hexDigits[i] = byte((i - 'a') + 10) + } + for i := 'A'; i <= 'F'; i++ { + hexDigits[i] = byte((i - 'A') + 10) + } + valueTypes = make([]ValueType, 256) + for i := 0; i < len(valueTypes); i++ { + valueTypes[i] = InvalidValue + } + valueTypes['"'] = StringValue + valueTypes['-'] = NumberValue + valueTypes['0'] = NumberValue + valueTypes['1'] = NumberValue + valueTypes['2'] = NumberValue + valueTypes['3'] = NumberValue + valueTypes['4'] = NumberValue + valueTypes['5'] = NumberValue + valueTypes['6'] = NumberValue + valueTypes['7'] = NumberValue + valueTypes['8'] = NumberValue + valueTypes['9'] = NumberValue + valueTypes['t'] = BoolValue + valueTypes['f'] = BoolValue + valueTypes['n'] = NilValue + valueTypes['['] = ArrayValue + valueTypes['{'] = ObjectValue +} + +// Iterator is a io.Reader like object, with JSON specific read functions. +// Error is not returned as return value, but stored as Error member on this iterator instance. +type Iterator struct { + cfg *frozenConfig + reader io.Reader + buf []byte + head int + tail int + captureStartedAt int + captured []byte + Error error + Attachment interface{} // open for customized decoder +} + +// NewIterator creates an empty Iterator instance +func NewIterator(cfg API) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: nil, + head: 0, + tail: 0, + } +} + +// Parse creates an Iterator instance from io.Reader +func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: reader, + buf: make([]byte, bufSize), + head: 0, + tail: 0, + } +} + +// ParseBytes creates an Iterator instance from byte array +func ParseBytes(cfg API, input []byte) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: input, + head: 0, + tail: len(input), + } +} + +// ParseString creates an Iterator instance from string +func ParseString(cfg API, input string) *Iterator { + return ParseBytes(cfg, []byte(input)) +} + +// Pool returns a pool can provide more iterator with same configuration +func (iter *Iterator) Pool() IteratorPool { + return iter.cfg +} + +// Reset reuse iterator instance by specifying another reader +func (iter *Iterator) Reset(reader io.Reader) *Iterator { + iter.reader = reader + iter.head = 0 + iter.tail = 0 + return iter +} + +// ResetBytes reuse iterator instance by specifying another byte array as input +func (iter *Iterator) ResetBytes(input []byte) *Iterator { + iter.reader = nil + iter.buf = input + iter.head = 0 + iter.tail = len(input) + return iter +} + +// WhatIsNext gets ValueType of relatively next json element +func (iter *Iterator) WhatIsNext() ValueType { + valueType := valueTypes[iter.nextToken()] + iter.unreadByte() + return valueType +} + +func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + return false + } + return true +} + +func (iter *Iterator) isObjectEnd() bool { + c := iter.nextToken() + if c == ',' { + return false + } + if c == '}' { + return true + } + iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) + return true +} + +func (iter *Iterator) nextToken() byte { + // a variation of skip whitespaces, returning the next non-whitespace token + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + 1 + return c + } + if !iter.loadMore() { + return 0 + } + } +} + +// ReportError record a error in iterator instance with current position. +func (iter *Iterator) ReportError(operation string, msg string) { + if iter.Error != nil { + if iter.Error != io.EOF { + return + } + } + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + peekEnd := iter.head + 10 + if peekEnd > iter.tail { + peekEnd = iter.tail + } + parsing := string(iter.buf[peekStart:peekEnd]) + contextStart := iter.head - 50 + if contextStart < 0 { + contextStart = 0 + } + contextEnd := iter.head + 50 + if contextEnd > iter.tail { + contextEnd = iter.tail + } + context := string(iter.buf[contextStart:contextEnd]) + iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", + operation, msg, iter.head-peekStart, parsing, context) +} + +// CurrentBuffer gets current buffer as string for debugging purpose +func (iter *Iterator) CurrentBuffer() string { + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, + string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) +} + +func (iter *Iterator) readByte() (ret byte) { + if iter.head == iter.tail { + if iter.loadMore() { + ret = iter.buf[iter.head] + iter.head++ + return ret + } + return 0 + } + ret = iter.buf[iter.head] + iter.head++ + return ret +} + +func (iter *Iterator) loadMore() bool { + if iter.reader == nil { + if iter.Error == nil { + iter.head = iter.tail + iter.Error = io.EOF + } + return false + } + if iter.captured != nil { + iter.captured = append(iter.captured, + iter.buf[iter.captureStartedAt:iter.tail]...) + iter.captureStartedAt = 0 + } + for { + n, err := iter.reader.Read(iter.buf) + if n == 0 { + if err != nil { + if iter.Error == nil { + iter.Error = err + } + return false + } + } else { + iter.head = 0 + iter.tail = n + return true + } + } +} + +func (iter *Iterator) unreadByte() { + if iter.Error != nil { + return + } + iter.head-- + return +} + +// Read read the next JSON element as generic interface{}. +func (iter *Iterator) Read() interface{} { + valueType := iter.WhatIsNext() + switch valueType { + case StringValue: + return iter.ReadString() + case NumberValue: + if iter.cfg.configBeforeFrozen.UseNumber { + return json.Number(iter.readNumberAsString()) + } + return iter.ReadFloat64() + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + return nil + case BoolValue: + return iter.ReadBool() + case ArrayValue: + arr := []interface{}{} + iter.ReadArrayCB(func(iter *Iterator) bool { + var elem interface{} + iter.ReadVal(&elem) + arr = append(arr, elem) + return true + }) + return arr + case ObjectValue: + obj := map[string]interface{}{} + iter.ReadMapCB(func(Iter *Iterator, field string) bool { + var elem interface{} + iter.ReadVal(&elem) + obj[field] = elem + return true + }) + return obj + default: + iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType)) + return nil + } +} diff --git a/vendor/github.com/json-iterator/go/iter_array.go b/vendor/github.com/json-iterator/go/iter_array.go new file mode 100644 index 000000000..6188cb457 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_array.go @@ -0,0 +1,58 @@ +package jsoniter + +// ReadArray read array element, tells if the array has more element to read. +func (iter *Iterator) ReadArray() (ret bool) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return false // null + case '[': + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + return true + } + return false + case ']': + return false + case ',': + return true + default: + iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) + return + } +} + +// ReadArrayCB read array with callback +func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { + c := iter.nextToken() + if c == '[' { + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + if !callback(iter) { + return false + } + c = iter.nextToken() + for c == ',' { + if !callback(iter) { + return false + } + c = iter.nextToken() + } + if c != ']' { + iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) + return false + } + return true + } + return true + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) + return false +} diff --git a/vendor/github.com/json-iterator/go/iter_float.go b/vendor/github.com/json-iterator/go/iter_float.go new file mode 100644 index 000000000..4f883c095 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_float.go @@ -0,0 +1,347 @@ +package jsoniter + +import ( + "encoding/json" + "io" + "math/big" + "strconv" + "strings" + "unsafe" +) + +var floatDigits []int8 + +const invalidCharForNumber = int8(-1) +const endOfNumber = int8(-2) +const dotInNumber = int8(-3) + +func init() { + floatDigits = make([]int8, 256) + for i := 0; i < len(floatDigits); i++ { + floatDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + floatDigits[i] = i - int8('0') + } + floatDigits[','] = endOfNumber + floatDigits[']'] = endOfNumber + floatDigits['}'] = endOfNumber + floatDigits[' '] = endOfNumber + floatDigits['\t'] = endOfNumber + floatDigits['\n'] = endOfNumber + floatDigits['.'] = dotInNumber +} + +// ReadBigFloat read big.Float +func (iter *Iterator) ReadBigFloat() (ret *big.Float) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + prec := 64 + if len(str) > prec { + prec = len(str) + } + val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) + if err != nil { + iter.Error = err + return nil + } + return val +} + +// ReadBigInt read big.Int +func (iter *Iterator) ReadBigInt() (ret *big.Int) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + ret = big.NewInt(0) + var success bool + ret, success = ret.SetString(str, 10) + if !success { + iter.ReportError("ReadBigInt", "invalid big int") + return nil + } + return ret +} + +//ReadFloat32 read float32 +func (iter *Iterator) ReadFloat32() (ret float32) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat32() + } + iter.unreadByte() + return iter.readPositiveFloat32() +} + +func (iter *Iterator) readPositiveFloat32() (ret float32) { + value := uint64(0) + c := byte(' ') + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c = iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.ReportError("readFloat32", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat32", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat32", "leading zero is invalid") + return + } + } + value = uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.head = i + return float32(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat32SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float32(float64(value) / float64(pow10[decimalPlaces])) + } + // too many decimal places + return iter.readFloat32SlowPath() + case invalidCharForNumber: + fallthrough + case dotInNumber: + return iter.readFloat32SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat32SlowPath() +} + +func (iter *Iterator) readNumberAsString() (ret string) { + strBuf := [16]byte{} + str := strBuf[0:0] +load_loop: + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + str = append(str, c) + continue + default: + iter.head = i + break load_loop + } + } + if !iter.loadMore() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + return + } + if len(str) == 0 { + iter.ReportError("readNumberAsString", "invalid number") + } + return *(*string)(unsafe.Pointer(&str)) +} + +func (iter *Iterator) readFloat32SlowPath() (ret float32) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat32SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 32) + if err != nil { + iter.Error = err + return + } + return float32(val) +} + +// ReadFloat64 read float64 +func (iter *Iterator) ReadFloat64() (ret float64) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat64() + } + iter.unreadByte() + return iter.readPositiveFloat64() +} + +func (iter *Iterator) readPositiveFloat64() (ret float64) { + value := uint64(0) + c := byte(' ') + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c = iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.ReportError("readFloat64", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat64", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat64", "leading zero is invalid") + return + } + } + value = uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.head = i + return float64(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat64SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float64(value) / float64(pow10[decimalPlaces]) + } + // too many decimal places + return iter.readFloat64SlowPath() + case invalidCharForNumber: + fallthrough + case dotInNumber: + return iter.readFloat64SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat64SlowPath() +} + +func (iter *Iterator) readFloat64SlowPath() (ret float64) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat64SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 64) + if err != nil { + iter.Error = err + return + } + return val +} + +func validateFloat(str string) string { + // strconv.ParseFloat is not validating `1.` or `1.e1` + if len(str) == 0 { + return "empty number" + } + if str[0] == '-' { + return "-- is not valid" + } + dotPos := strings.IndexByte(str, '.') + if dotPos != -1 { + if dotPos == len(str)-1 { + return "dot can not be last character" + } + switch str[dotPos+1] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + return "missing digit after dot" + } + } + return "" +} + +// ReadNumber read json.Number +func (iter *Iterator) ReadNumber() (ret json.Number) { + return json.Number(iter.readNumberAsString()) +} diff --git a/vendor/github.com/json-iterator/go/iter_int.go b/vendor/github.com/json-iterator/go/iter_int.go new file mode 100644 index 000000000..214232035 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_int.go @@ -0,0 +1,345 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var intDigits []int8 + +const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1 +const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1 + +func init() { + intDigits = make([]int8, 256) + for i := 0; i < len(intDigits); i++ { + intDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + intDigits[i] = i - int8('0') + } +} + +// ReadUint read uint +func (iter *Iterator) ReadUint() uint { + if strconv.IntSize == 32 { + return uint(iter.ReadUint32()) + } + return uint(iter.ReadUint64()) +} + +// ReadInt read int +func (iter *Iterator) ReadInt() int { + if strconv.IntSize == 32 { + return int(iter.ReadInt32()) + } + return int(iter.ReadInt64()) +} + +// ReadInt8 read int8 +func (iter *Iterator) ReadInt8() (ret int8) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt8+1 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int8(val) + } + val := iter.readUint32(c) + if val > math.MaxInt8 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int8(val) +} + +// ReadUint8 read uint8 +func (iter *Iterator) ReadUint8() (ret uint8) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint8 { + iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint8(val) +} + +// ReadInt16 read int16 +func (iter *Iterator) ReadInt16() (ret int16) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt16+1 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int16(val) + } + val := iter.readUint32(c) + if val > math.MaxInt16 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int16(val) +} + +// ReadUint16 read uint16 +func (iter *Iterator) ReadUint16() (ret uint16) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint16 { + iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint16(val) +} + +// ReadInt32 read int32 +func (iter *Iterator) ReadInt32() (ret int32) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt32+1 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int32(val) + } + val := iter.readUint32(c) + if val > math.MaxInt32 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int32(val) +} + +// ReadUint32 read uint32 +func (iter *Iterator) ReadUint32() (ret uint32) { + return iter.readUint32(iter.nextToken()) +} + +func (iter *Iterator) readUint32(c byte) (ret uint32) { + ind := intDigits[c] + if ind == 0 { + iter.assertInteger() + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint32(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint32(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint32(ind2)*10 + uint32(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + if value > uint32SafeToMultiply10 { + value2 := (value << 3) + (value << 1) + uint32(ind) + if value2 < value { + iter.ReportError("readUint32", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint32(ind) + } + if !iter.loadMore() { + iter.assertInteger() + return value + } + } +} + +// ReadInt64 read int64 +func (iter *Iterator) ReadInt64() (ret int64) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint64(iter.readByte()) + if val > math.MaxInt64+1 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return -int64(val) + } + val := iter.readUint64(c) + if val > math.MaxInt64 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return int64(val) +} + +// ReadUint64 read uint64 +func (iter *Iterator) ReadUint64() uint64 { + return iter.readUint64(iter.nextToken()) +} + +func (iter *Iterator) readUint64(c byte) (ret uint64) { + ind := intDigits[c] + if ind == 0 { + iter.assertInteger() + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint64(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint64(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint64(ind2)*10 + uint64(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + if value > uint64SafeToMultiple10 { + value2 := (value << 3) + (value << 1) + uint64(ind) + if value2 < value { + iter.ReportError("readUint64", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint64(ind) + } + if !iter.loadMore() { + iter.assertInteger() + return value + } + } +} + +func (iter *Iterator) assertInteger() { + if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' { + iter.ReportError("assertInteger", "can not decode float as int") + } +} diff --git a/vendor/github.com/json-iterator/go/iter_object.go b/vendor/github.com/json-iterator/go/iter_object.go new file mode 100644 index 000000000..1c5757671 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_object.go @@ -0,0 +1,251 @@ +package jsoniter + +import ( + "fmt" + "strings" +) + +// ReadObject read one field from object. +// If object ended, returns empty string. +// Otherwise, returns the field name. +func (iter *Iterator) ReadObject() (ret string) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return "" // null + case '{': + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + } + if c == '}' { + return "" // end of object + } + iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) + return + case ',': + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + case '}': + return "" // end of object + default: + iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) + return + } +} + +// CaseInsensitive +func (iter *Iterator) readFieldHash() int64 { + hash := int64(0x811c9dc5) + c := iter.nextToken() + if c != '"' { + iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) + return 0 + } + for { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + b := iter.buf[i] + if b == '\\' { + iter.head = i + for _, b := range iter.readStringSlowPath() { + if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash + } + if b == '"' { + iter.head = i + 1 + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash + } + if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + if !iter.loadMore() { + iter.ReportError("readFieldHash", `incomplete field name`) + return 0 + } + } +} + +func calcHash(str string, caseSensitive bool) int64 { + if !caseSensitive { + str = strings.ToLower(str) + } + hash := int64(0x811c9dc5) + for _, b := range []byte(str) { + hash ^= int64(b) + hash *= 0x1000193 + } + return int64(hash) +} + +// ReadObjectCB read object with callback, the key is ascii only and field name not copied +func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + var field string + if c == '{' { + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadObjectCB", `object not ended with }`) + return false + } + return true + } + if c == '}' { + return true + } + iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c})) + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +// ReadMapCB read map with callback, the key can be any string +func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return false + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return false + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadMapCB", `object not ended with }`) + return false + } + return true + } + if c == '}' { + return true + } + iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectStart() bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '}' { + return false + } + iter.unreadByte() + return true + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return false + } + iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { + str := iter.ReadStringAsSlice() + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if iter.buf[iter.head] != ':' { + iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) + return + } + iter.head++ + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if ret == nil { + return str + } + return ret +} diff --git a/vendor/github.com/json-iterator/go/iter_skip.go b/vendor/github.com/json-iterator/go/iter_skip.go new file mode 100644 index 000000000..f58beb913 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip.go @@ -0,0 +1,129 @@ +package jsoniter + +import "fmt" + +// ReadNil reads a json object as nil and +// returns whether it's a nil or not +func (iter *Iterator) ReadNil() (ret bool) { + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') // null + return true + } + iter.unreadByte() + return false +} + +// ReadBool reads a json object as BoolValue +func (iter *Iterator) ReadBool() (ret bool) { + c := iter.nextToken() + if c == 't' { + iter.skipThreeBytes('r', 'u', 'e') + return true + } + if c == 'f' { + iter.skipFourBytes('a', 'l', 's', 'e') + return false + } + iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) + return +} + +// SkipAndReturnBytes skip next JSON element, and return its content as []byte. +// The []byte can be kept, it is a copy of data. +func (iter *Iterator) SkipAndReturnBytes() []byte { + iter.startCapture(iter.head) + iter.Skip() + return iter.stopCapture() +} + +type captureBuffer struct { + startedAt int + captured []byte +} + +func (iter *Iterator) startCapture(captureStartedAt int) { + if iter.captured != nil { + panic("already in capture mode") + } + iter.captureStartedAt = captureStartedAt + iter.captured = make([]byte, 0, 32) +} + +func (iter *Iterator) stopCapture() []byte { + if iter.captured == nil { + panic("not in capture mode") + } + captured := iter.captured + remaining := iter.buf[iter.captureStartedAt:iter.head] + iter.captureStartedAt = -1 + iter.captured = nil + if len(captured) == 0 { + copied := make([]byte, len(remaining)) + copy(copied, remaining) + return copied + } + captured = append(captured, remaining...) + return captured +} + +// Skip skips a json object and positions to relatively the next json object +func (iter *Iterator) Skip() { + c := iter.nextToken() + switch c { + case '"': + iter.skipString() + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + case '0': + iter.unreadByte() + iter.ReadFloat32() + case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.skipNumber() + case '[': + iter.skipArray() + case '{': + iter.skipObject() + default: + iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) + return + } +} + +func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b4 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } +} + +func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } +} diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go new file mode 100644 index 000000000..8fcdc3b69 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go @@ -0,0 +1,144 @@ +//+build jsoniter_sloppy + +package jsoniter + +// sloppy but faster implementation, do not validate the input json + +func (iter *Iterator) skipNumber() { + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\r', '\t', ',', '}', ']': + iter.head = i + return + } + } + if !iter.loadMore() { + return + } + } +} + +func (iter *Iterator) skipArray() { + level := 1 + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '[': // If open symbol, increase level + level++ + case ']': // If close symbol, increase level + level-- + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete array") + return + } + } +} + +func (iter *Iterator) skipObject() { + level := 1 + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '{': // If open symbol, increase level + level++ + case '}': // If close symbol, increase level + level-- + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete object") + return + } + } +} + +func (iter *Iterator) skipString() { + for { + end, escaped := iter.findStringEnd() + if end == -1 { + if !iter.loadMore() { + iter.ReportError("skipString", "incomplete string") + return + } + if escaped { + iter.head = 1 // skip the first char as last char read is \ + } + } else { + iter.head = end + return + } + } +} + +// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go +// Tries to find the end of string +// Support if string contains escaped quote symbols. +func (iter *Iterator) findStringEnd() (int, bool) { + escaped := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + if !escaped { + return i + 1, false + } + j := i - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return i + 1, true + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + } + } else if c == '\\' { + escaped = true + } + } + j := iter.tail - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return -1, false // do not end with \ + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + + } + return -1, true // end with \ +} diff --git a/vendor/github.com/json-iterator/go/iter_skip_strict.go b/vendor/github.com/json-iterator/go/iter_skip_strict.go new file mode 100644 index 000000000..f67bc2e83 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip_strict.go @@ -0,0 +1,89 @@ +//+build !jsoniter_sloppy + +package jsoniter + +import "fmt" + +func (iter *Iterator) skipNumber() { + if !iter.trySkipNumber() { + iter.unreadByte() + iter.ReadFloat32() + } +} + +func (iter *Iterator) trySkipNumber() bool { + dotFound := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + case '.': + if dotFound { + iter.ReportError("validateNumber", `more than one dot found in number`) + return true // already failed + } + if i+1 == iter.tail { + return false + } + c = iter.buf[i+1] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + iter.ReportError("validateNumber", `missing digit after dot`) + return true // already failed + } + dotFound = true + default: + switch c { + case ',', ']', '}', ' ', '\t', '\n', '\r': + if iter.head == i { + return false // if - without following digits + } + iter.head = i + return true // must be valid + } + return false // may be invalid + } + } + return false +} + +func (iter *Iterator) skipString() { + if !iter.trySkipString() { + iter.unreadByte() + iter.ReadString() + } +} + +func (iter *Iterator) trySkipString() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + iter.head = i + 1 + return true // valid + } else if c == '\\' { + return false + } else if c < ' ' { + iter.ReportError("trySkipString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return true // already failed + } + } + return false +} + +func (iter *Iterator) skipObject() { + iter.unreadByte() + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + return true + }) +} + +func (iter *Iterator) skipArray() { + iter.unreadByte() + iter.ReadArrayCB(func(iter *Iterator) bool { + iter.Skip() + return true + }) +} diff --git a/vendor/github.com/json-iterator/go/iter_str.go b/vendor/github.com/json-iterator/go/iter_str.go new file mode 100644 index 000000000..adc487ea8 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_str.go @@ -0,0 +1,215 @@ +package jsoniter + +import ( + "fmt" + "unicode/utf16" +) + +// ReadString read string from iterator +func (iter *Iterator) ReadString() (ret string) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + ret = string(iter.buf[iter.head:i]) + iter.head = i + 1 + return ret + } else if c == '\\' { + break + } else if c < ' ' { + iter.ReportError("ReadString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return + } + } + return iter.readStringSlowPath() + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return "" + } + iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readStringSlowPath() (ret string) { + var str []byte + var c byte + for iter.Error == nil { + c = iter.readByte() + if c == '"' { + return string(str) + } + if c == '\\' { + c = iter.readByte() + str = iter.readEscapedChar(c, str) + } else { + str = append(str, c) + } + } + iter.ReportError("readStringSlowPath", "unexpected end of input") + return +} + +func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { + switch c { + case 'u': + r := iter.readU4() + if utf16.IsSurrogate(r) { + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != '\\' { + iter.unreadByte() + str = appendRune(str, r) + return str + } + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != 'u' { + str = appendRune(str, r) + return iter.readEscapedChar(c, str) + } + r2 := iter.readU4() + if iter.Error != nil { + return nil + } + combined := utf16.DecodeRune(r, r2) + if combined == '\uFFFD' { + str = appendRune(str, r) + str = appendRune(str, r2) + } else { + str = appendRune(str, combined) + } + } else { + str = appendRune(str, r) + } + case '"': + str = append(str, '"') + case '\\': + str = append(str, '\\') + case '/': + str = append(str, '/') + case 'b': + str = append(str, '\b') + case 'f': + str = append(str, '\f') + case 'n': + str = append(str, '\n') + case 'r': + str = append(str, '\r') + case 't': + str = append(str, '\t') + default: + iter.ReportError("readEscapedChar", + `invalid escape char after \`) + return nil + } + return str +} + +// ReadStringAsSlice read string from iterator without copying into string form. +// The []byte can not be kept, as it will change after next iterator call. +func (iter *Iterator) ReadStringAsSlice() (ret []byte) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + // for: field name, base64, number + if iter.buf[i] == '"' { + // fast path: reuse the underlying buffer + ret = iter.buf[iter.head:i] + iter.head = i + 1 + return ret + } + } + readLen := iter.tail - iter.head + copied := make([]byte, readLen, readLen*2) + copy(copied, iter.buf[iter.head:iter.tail]) + iter.head = iter.tail + for iter.Error == nil { + c := iter.readByte() + if c == '"' { + return copied + } + copied = append(copied, c) + } + return copied + } + iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readU4() (ret rune) { + for i := 0; i < 4; i++ { + c := iter.readByte() + if iter.Error != nil { + return + } + if c >= '0' && c <= '9' { + ret = ret*16 + rune(c-'0') + } else if c >= 'a' && c <= 'f' { + ret = ret*16 + rune(c-'a'+10) + } else if c >= 'A' && c <= 'F' { + ret = ret*16 + rune(c-'A'+10) + } else { + iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) + return + } + } + return ret +} + +const ( + t1 = 0x00 // 0000 0000 + tx = 0x80 // 1000 0000 + t2 = 0xC0 // 1100 0000 + t3 = 0xE0 // 1110 0000 + t4 = 0xF0 // 1111 0000 + t5 = 0xF8 // 1111 1000 + + maskx = 0x3F // 0011 1111 + mask2 = 0x1F // 0001 1111 + mask3 = 0x0F // 0000 1111 + mask4 = 0x07 // 0000 0111 + + rune1Max = 1<<7 - 1 + rune2Max = 1<<11 - 1 + rune3Max = 1<<16 - 1 + + surrogateMin = 0xD800 + surrogateMax = 0xDFFF + + maxRune = '\U0010FFFF' // Maximum valid Unicode code point. + runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character" +) + +func appendRune(p []byte, r rune) []byte { + // Negative values are erroneous. Making it unsigned addresses the problem. + switch i := uint32(r); { + case i <= rune1Max: + p = append(p, byte(r)) + return p + case i <= rune2Max: + p = append(p, t2|byte(r>>6)) + p = append(p, tx|byte(r)&maskx) + return p + case i > maxRune, surrogateMin <= i && i <= surrogateMax: + r = runeError + fallthrough + case i <= rune3Max: + p = append(p, t3|byte(r>>12)) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + default: + p = append(p, t4|byte(r>>18)) + p = append(p, tx|byte(r>>12)&maskx) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + } +} diff --git a/vendor/github.com/json-iterator/go/jsoniter.go b/vendor/github.com/json-iterator/go/jsoniter.go new file mode 100644 index 000000000..c2934f916 --- /dev/null +++ b/vendor/github.com/json-iterator/go/jsoniter.go @@ -0,0 +1,18 @@ +// Package jsoniter implements encoding and decoding of JSON as defined in +// RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. +// Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter +// and variable type declarations (if any). +// jsoniter interfaces gives 100% compatibility with code using standard lib. +// +// "JSON and Go" +// (https://golang.org/doc/articles/json_and_go.html) +// gives a description of how Marshal/Unmarshal operate +// between arbitrary or predefined json objects and bytes, +// and it applies to jsoniter.Marshal/Unmarshal as well. +// +// Besides, jsoniter.Iterator provides a different set of interfaces +// iterating given bytes/string/reader +// and yielding parsed elements one by one. +// This set of interfaces reads input as required and gives +// better performance. +package jsoniter diff --git a/vendor/github.com/json-iterator/go/pool.go b/vendor/github.com/json-iterator/go/pool.go new file mode 100644 index 000000000..e2389b56c --- /dev/null +++ b/vendor/github.com/json-iterator/go/pool.go @@ -0,0 +1,42 @@ +package jsoniter + +import ( + "io" +) + +// IteratorPool a thread safe pool of iterators with same configuration +type IteratorPool interface { + BorrowIterator(data []byte) *Iterator + ReturnIterator(iter *Iterator) +} + +// StreamPool a thread safe pool of streams with same configuration +type StreamPool interface { + BorrowStream(writer io.Writer) *Stream + ReturnStream(stream *Stream) +} + +func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { + stream := cfg.streamPool.Get().(*Stream) + stream.Reset(writer) + return stream +} + +func (cfg *frozenConfig) ReturnStream(stream *Stream) { + stream.out = nil + stream.Error = nil + stream.Attachment = nil + cfg.streamPool.Put(stream) +} + +func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { + iter := cfg.iteratorPool.Get().(*Iterator) + iter.ResetBytes(data) + return iter +} + +func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { + iter.Error = nil + iter.Attachment = nil + cfg.iteratorPool.Put(iter) +} diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go new file mode 100644 index 000000000..4459e203f --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect.go @@ -0,0 +1,332 @@ +package jsoniter + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/modern-go/reflect2" +) + +// ValDecoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValDecoder with json.Decoder. +// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). +// +// Reflection on type to create decoders, which is then cached +// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions +// 1. create instance of new value, for example *int will need a int to be allocated +// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New +// 3. assignment to map, both key and value will be reflect.Value +// For a simple struct binding, it will be reflect.Value free and allocation free +type ValDecoder interface { + Decode(ptr unsafe.Pointer, iter *Iterator) +} + +// ValEncoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValEncoder with json.Encoder. +// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). +type ValEncoder interface { + IsEmpty(ptr unsafe.Pointer) bool + Encode(ptr unsafe.Pointer, stream *Stream) +} + +type checkIsEmpty interface { + IsEmpty(ptr unsafe.Pointer) bool +} + +type ctx struct { + *frozenConfig + prefix string + encoders map[reflect2.Type]ValEncoder + decoders map[reflect2.Type]ValDecoder +} + +func (b *ctx) caseSensitive() bool { + if b.frozenConfig == nil { + // default is case-insensitive + return false + } + return b.frozenConfig.caseSensitive +} + +func (b *ctx) append(prefix string) *ctx { + return &ctx{ + frozenConfig: b.frozenConfig, + prefix: b.prefix + " " + prefix, + encoders: b.encoders, + decoders: b.decoders, + } +} + +// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal +func (iter *Iterator) ReadVal(obj interface{}) { + cacheKey := reflect2.RTypeOf(obj) + decoder := iter.cfg.getDecoderFromCache(cacheKey) + if decoder == nil { + typ := reflect2.TypeOf(obj) + if typ.Kind() != reflect.Ptr { + iter.ReportError("ReadVal", "can only unmarshal into pointer") + return + } + decoder = iter.cfg.DecoderOf(typ) + } + ptr := reflect2.PtrOf(obj) + if ptr == nil { + iter.ReportError("ReadVal", "can not read into nil pointer") + return + } + decoder.Decode(ptr, iter) +} + +// WriteVal copy the go interface into underlying JSON, same as json.Marshal +func (stream *Stream) WriteVal(val interface{}) { + if nil == val { + stream.WriteNil() + return + } + cacheKey := reflect2.RTypeOf(val) + encoder := stream.cfg.getEncoderFromCache(cacheKey) + if encoder == nil { + typ := reflect2.TypeOf(val) + encoder = stream.cfg.EncoderOf(typ) + } + encoder.Encode(reflect2.PtrOf(val), stream) +} + +func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { + cacheKey := typ.RType() + decoder := cfg.getDecoderFromCache(cacheKey) + if decoder != nil { + return decoder + } + ctx := &ctx{ + frozenConfig: cfg, + prefix: "", + decoders: map[reflect2.Type]ValDecoder{}, + encoders: map[reflect2.Type]ValEncoder{}, + } + ptrType := typ.(*reflect2.UnsafePtrType) + decoder = decoderOfType(ctx, ptrType.Elem()) + cfg.addDecoderToCache(cacheKey, decoder) + return decoder +} + +func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := getTypeDecoderFromExtension(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfType(ctx, typ) + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) + for _, extension := range ctx.extraExtensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + return decoder +} + +func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := ctx.decoders[typ] + if decoder != nil { + return decoder + } + placeholder := &placeholderDecoder{} + ctx.decoders[typ] = placeholder + decoder = _createDecoderOfType(ctx, typ) + placeholder.decoder = decoder + return decoder +} + +func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := createDecoderOfJsonRawMessage(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfJsonNumber(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfMarshaler(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfAny(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfNative(ctx, typ) + if decoder != nil { + return decoder + } + switch typ.Kind() { + case reflect.Interface: + ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType) + if isIFace { + return &ifaceDecoder{valType: ifaceType} + } + return &efaceDecoder{} + case reflect.Struct: + return decoderOfStruct(ctx, typ) + case reflect.Array: + return decoderOfArray(ctx, typ) + case reflect.Slice: + return decoderOfSlice(ctx, typ) + case reflect.Map: + return decoderOfMap(ctx, typ) + case reflect.Ptr: + return decoderOfOptional(ctx, typ) + default: + return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} + } +} + +func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { + cacheKey := typ.RType() + encoder := cfg.getEncoderFromCache(cacheKey) + if encoder != nil { + return encoder + } + ctx := &ctx{ + frozenConfig: cfg, + prefix: "", + decoders: map[reflect2.Type]ValDecoder{}, + encoders: map[reflect2.Type]ValEncoder{}, + } + encoder = encoderOfType(ctx, typ) + if typ.LikePtr() { + encoder = &onePtrEncoder{encoder} + } + cfg.addEncoderToCache(cacheKey, encoder) + return encoder +} + +type onePtrEncoder struct { + encoder ValEncoder +} + +func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +} + +func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := getTypeEncoderFromExtension(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfType(ctx, typ) + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) + for _, extension := range ctx.extraExtensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + return encoder +} + +func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := ctx.encoders[typ] + if encoder != nil { + return encoder + } + placeholder := &placeholderEncoder{} + ctx.encoders[typ] = placeholder + encoder = _createEncoderOfType(ctx, typ) + placeholder.encoder = encoder + return encoder +} +func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := createEncoderOfJsonRawMessage(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfJsonNumber(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfMarshaler(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfAny(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfNative(ctx, typ) + if encoder != nil { + return encoder + } + kind := typ.Kind() + switch kind { + case reflect.Interface: + return &dynamicEncoder{typ} + case reflect.Struct: + return encoderOfStruct(ctx, typ) + case reflect.Array: + return encoderOfArray(ctx, typ) + case reflect.Slice: + return encoderOfSlice(ctx, typ) + case reflect.Map: + return encoderOfMap(ctx, typ) + case reflect.Ptr: + return encoderOfOptional(ctx, typ) + default: + return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} + } +} + +type lazyErrorDecoder struct { + err error +} + +func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.WhatIsNext() != NilValue { + if iter.Error == nil { + iter.Error = decoder.err + } + } else { + iter.Skip() + } +} + +type lazyErrorEncoder struct { + err error +} + +func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if ptr == nil { + stream.WriteNil() + } else if stream.Error == nil { + stream.Error = encoder.err + } +} + +func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type placeholderDecoder struct { + decoder ValDecoder +} + +func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.decoder.Decode(ptr, iter) +} + +type placeholderEncoder struct { + encoder ValEncoder +} + +func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(ptr, stream) +} + +func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(ptr) +} diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go new file mode 100644 index 000000000..13a0b7b08 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_array.go @@ -0,0 +1,104 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "unsafe" +) + +func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder { + arrayType := typ.(*reflect2.UnsafeArrayType) + decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) + return &arrayDecoder{arrayType, decoder} +} + +func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder { + arrayType := typ.(*reflect2.UnsafeArrayType) + if arrayType.Len() == 0 { + return emptyArrayEncoder{} + } + encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) + return &arrayEncoder{arrayType, encoder} +} + +type emptyArrayEncoder struct{} + +func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyArray() +} + +func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return true +} + +type arrayEncoder struct { + arrayType *reflect2.UnsafeArrayType + elemEncoder ValEncoder +} + +func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteArrayStart() + elemPtr := unsafe.Pointer(ptr) + encoder.elemEncoder.Encode(elemPtr, stream) + for i := 1; i < encoder.arrayType.Len(); i++ { + stream.WriteMore() + elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i) + encoder.elemEncoder.Encode(elemPtr, stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error()) + } +} + +func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type arrayDecoder struct { + arrayType *reflect2.UnsafeArrayType + elemDecoder ValDecoder +} + +func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error()) + } +} + +func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + arrayType := decoder.arrayType + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return + } + if c != '[' { + iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c})) + return + } + c = iter.nextToken() + if c == ']' { + return + } + iter.unreadByte() + elemPtr := arrayType.UnsafeGetIndex(ptr, 0) + decoder.elemDecoder.Decode(elemPtr, iter) + length := 1 + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + if length >= arrayType.Len() { + iter.Skip() + continue + } + idx := length + length += 1 + elemPtr = arrayType.UnsafeGetIndex(ptr, idx) + decoder.elemDecoder.Decode(elemPtr, iter) + } + if c != ']' { + iter.ReportError("decode array", "expect ], but found "+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_dynamic.go b/vendor/github.com/json-iterator/go/reflect_dynamic.go new file mode 100644 index 000000000..8b6bc8b43 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_dynamic.go @@ -0,0 +1,70 @@ +package jsoniter + +import ( + "github.com/modern-go/reflect2" + "reflect" + "unsafe" +) + +type dynamicEncoder struct { + valType reflect2.Type +} + +func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + stream.WriteVal(obj) +} + +func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.valType.UnsafeIndirect(ptr) == nil +} + +type efaceDecoder struct { +} + +func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + pObj := (*interface{})(ptr) + obj := *pObj + if obj == nil { + *pObj = iter.Read() + return + } + typ := reflect2.TypeOf(obj) + if typ.Kind() != reflect.Ptr { + *pObj = iter.Read() + return + } + ptrType := typ.(*reflect2.UnsafePtrType) + ptrElemType := ptrType.Elem() + if iter.WhatIsNext() == NilValue { + if ptrElemType.Kind() != reflect.Ptr { + iter.skipFourBytes('n', 'u', 'l', 'l') + *pObj = nil + return + } + } + if reflect2.IsNil(obj) { + obj := ptrElemType.New() + iter.ReadVal(obj) + *pObj = obj + return + } + iter.ReadVal(obj) +} + +type ifaceDecoder struct { + valType *reflect2.UnsafeIFaceType +} + +func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew()) + return + } + obj := decoder.valType.UnsafeIndirect(ptr) + if reflect2.IsNil(obj) { + iter.ReportError("decode non empty interface", "can not unmarshal into nil") + return + } + iter.ReadVal(obj) +} diff --git a/vendor/github.com/json-iterator/go/reflect_extension.go b/vendor/github.com/json-iterator/go/reflect_extension.go new file mode 100644 index 000000000..04f68756b --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_extension.go @@ -0,0 +1,483 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "reflect" + "sort" + "strings" + "unicode" + "unsafe" +) + +var typeDecoders = map[string]ValDecoder{} +var fieldDecoders = map[string]ValDecoder{} +var typeEncoders = map[string]ValEncoder{} +var fieldEncoders = map[string]ValEncoder{} +var extensions = []Extension{} + +// StructDescriptor describe how should we encode/decode the struct +type StructDescriptor struct { + Type reflect2.Type + Fields []*Binding +} + +// GetField get one field from the descriptor by its name. +// Can not use map here to keep field orders. +func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { + for _, binding := range structDescriptor.Fields { + if binding.Field.Name() == fieldName { + return binding + } + } + return nil +} + +// Binding describe how should we encode/decode the struct field +type Binding struct { + levels []int + Field reflect2.StructField + FromNames []string + ToNames []string + Encoder ValEncoder + Decoder ValDecoder +} + +// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. +// Can also rename fields by UpdateStructDescriptor. +type Extension interface { + UpdateStructDescriptor(structDescriptor *StructDescriptor) + CreateMapKeyDecoder(typ reflect2.Type) ValDecoder + CreateMapKeyEncoder(typ reflect2.Type) ValEncoder + CreateDecoder(typ reflect2.Type) ValDecoder + CreateEncoder(typ reflect2.Type) ValEncoder + DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder + DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder +} + +// DummyExtension embed this type get dummy implementation for all methods of Extension +type DummyExtension struct { +} + +// UpdateStructDescriptor No-op +func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateMapKeyDecoder No-op +func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// CreateDecoder No-op +func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateEncoder No-op +func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type EncoderExtension map[reflect2.Type]ValEncoder + +// UpdateStructDescriptor No-op +func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateDecoder No-op +func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateEncoder get encoder from map +func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return extension[typ] +} + +// CreateMapKeyDecoder No-op +func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type DecoderExtension map[reflect2.Type]ValDecoder + +// UpdateStructDescriptor No-op +func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateMapKeyDecoder No-op +func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// CreateDecoder get decoder from map +func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return extension[typ] +} + +// CreateEncoder No-op +func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type funcDecoder struct { + fun DecoderFunc +} + +func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.fun(ptr, iter) +} + +type funcEncoder struct { + fun EncoderFunc + isEmptyFunc func(ptr unsafe.Pointer) bool +} + +func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.fun(ptr, stream) +} + +func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { + if encoder.isEmptyFunc == nil { + return false + } + return encoder.isEmptyFunc(ptr) +} + +// DecoderFunc the function form of TypeDecoder +type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) + +// EncoderFunc the function form of TypeEncoder +type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) + +// RegisterTypeDecoderFunc register TypeDecoder for a type with function +func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { + typeDecoders[typ] = &funcDecoder{fun} +} + +// RegisterTypeDecoder register TypeDecoder for a typ +func RegisterTypeDecoder(typ string, decoder ValDecoder) { + typeDecoders[typ] = decoder +} + +// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function +func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { + RegisterFieldDecoder(typ, field, &funcDecoder{fun}) +} + +// RegisterFieldDecoder register TypeDecoder for a struct field +func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { + fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder +} + +// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function +func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} +} + +// RegisterTypeEncoder register TypeEncoder for a type +func RegisterTypeEncoder(typ string, encoder ValEncoder) { + typeEncoders[typ] = encoder +} + +// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function +func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) +} + +// RegisterFieldEncoder register TypeEncoder for a struct field +func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { + fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder +} + +// RegisterExtension register extension +func RegisterExtension(extension Extension) { + extensions = append(extensions, extension) +} + +func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := _getTypeDecoderFromExtension(ctx, typ) + if decoder != nil { + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) + for _, extension := range ctx.extraExtensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + } + return decoder +} +func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { + for _, extension := range extensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + decoder := ctx.decoderExtension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + for _, extension := range ctx.extraExtensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + typeName := typ.String() + decoder = typeDecoders[typeName] + if decoder != nil { + return decoder + } + if typ.Kind() == reflect.Ptr { + ptrType := typ.(*reflect2.UnsafePtrType) + decoder := typeDecoders[ptrType.Elem().String()] + if decoder != nil { + return &OptionalDecoder{ptrType.Elem(), decoder} + } + } + return nil +} + +func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := _getTypeEncoderFromExtension(ctx, typ) + if encoder != nil { + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) + for _, extension := range ctx.extraExtensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + } + return encoder +} + +func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { + for _, extension := range extensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + encoder := ctx.encoderExtension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + for _, extension := range ctx.extraExtensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + typeName := typ.String() + encoder = typeEncoders[typeName] + if encoder != nil { + return encoder + } + if typ.Kind() == reflect.Ptr { + typePtr := typ.(*reflect2.UnsafePtrType) + encoder := typeEncoders[typePtr.Elem().String()] + if encoder != nil { + return &OptionalEncoder{encoder} + } + } + return nil +} + +func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { + structType := typ.(*reflect2.UnsafeStructType) + embeddedBindings := []*Binding{} + bindings := []*Binding{} + for i := 0; i < structType.NumField(); i++ { + field := structType.Field(i) + tag, hastag := field.Tag().Lookup(ctx.getTagKey()) + if ctx.onlyTaggedField && !hastag { + continue + } + tagParts := strings.Split(tag, ",") + if tag == "-" { + continue + } + if field.Anonymous() && (tag == "" || tagParts[0] == "") { + if field.Type().Kind() == reflect.Struct { + structDescriptor := describeStruct(ctx, field.Type()) + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} + binding.Decoder = &structFieldDecoder{field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } else if field.Type().Kind() == reflect.Ptr { + ptrType := field.Type().(*reflect2.UnsafePtrType) + if ptrType.Elem().Kind() == reflect.Struct { + structDescriptor := describeStruct(ctx, ptrType.Elem()) + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &dereferenceEncoder{binding.Encoder} + binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} + binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder} + binding.Decoder = &structFieldDecoder{field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } + } + } + fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) + fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) + decoder := fieldDecoders[fieldCacheKey] + if decoder == nil { + decoder = decoderOfType(ctx.append(field.Name()), field.Type()) + } + encoder := fieldEncoders[fieldCacheKey] + if encoder == nil { + encoder = encoderOfType(ctx.append(field.Name()), field.Type()) + } + binding := &Binding{ + Field: field, + FromNames: fieldNames, + ToNames: fieldNames, + Decoder: decoder, + Encoder: encoder, + } + binding.levels = []int{i} + bindings = append(bindings, binding) + } + return createStructDescriptor(ctx, typ, bindings, embeddedBindings) +} +func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { + structDescriptor := &StructDescriptor{ + Type: typ, + Fields: bindings, + } + for _, extension := range extensions { + extension.UpdateStructDescriptor(structDescriptor) + } + ctx.encoderExtension.UpdateStructDescriptor(structDescriptor) + ctx.decoderExtension.UpdateStructDescriptor(structDescriptor) + for _, extension := range ctx.extraExtensions { + extension.UpdateStructDescriptor(structDescriptor) + } + processTags(structDescriptor, ctx.frozenConfig) + // merge normal & embedded bindings & sort with original order + allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) + sort.Sort(allBindings) + structDescriptor.Fields = allBindings + return structDescriptor +} + +type sortableBindings []*Binding + +func (bindings sortableBindings) Len() int { + return len(bindings) +} + +func (bindings sortableBindings) Less(i, j int) bool { + left := bindings[i].levels + right := bindings[j].levels + k := 0 + for { + if left[k] < right[k] { + return true + } else if left[k] > right[k] { + return false + } + k++ + } +} + +func (bindings sortableBindings) Swap(i, j int) { + bindings[i], bindings[j] = bindings[j], bindings[i] +} + +func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { + for _, binding := range structDescriptor.Fields { + shouldOmitEmpty := false + tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",") + for _, tagPart := range tagParts[1:] { + if tagPart == "omitempty" { + shouldOmitEmpty = true + } else if tagPart == "string" { + if binding.Field.Type().Kind() == reflect.String { + binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} + binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} + } else { + binding.Decoder = &stringModeNumberDecoder{binding.Decoder} + binding.Encoder = &stringModeNumberEncoder{binding.Encoder} + } + } + } + binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} + binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} + } +} + +func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { + // ignore? + if wholeTag == "-" { + return []string{} + } + // rename? + var fieldNames []string + if tagProvidedFieldName == "" { + fieldNames = []string{originalFieldName} + } else { + fieldNames = []string{tagProvidedFieldName} + } + // private? + isNotExported := unicode.IsLower(rune(originalFieldName[0])) + if isNotExported { + fieldNames = []string{} + } + return fieldNames +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go new file mode 100644 index 000000000..98d45c1ec --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_json_number.go @@ -0,0 +1,112 @@ +package jsoniter + +import ( + "encoding/json" + "github.com/modern-go/reflect2" + "strconv" + "unsafe" +) + +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +func CastJsonNumber(val interface{}) (string, bool) { + switch typedVal := val.(type) { + case json.Number: + return string(typedVal), true + case Number: + return string(typedVal), true + } + return "", false +} + +var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem() +var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem() + +func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{} + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{} + } + return nil +} + +func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{} + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{} + } + return nil +} + +type jsonNumberCodec struct { +} + +func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*json.Number)(ptr)) = json.Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*json.Number)(ptr)) = "" + default: + *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + number := *((*json.Number)(ptr)) + if len(number) == 0 { + stream.writeByte('0') + } else { + stream.WriteRaw(string(number)) + } +} + +func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.Number)(ptr))) == 0 +} + +type jsoniterNumberCodec struct { +} + +func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*Number)(ptr)) = Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*Number)(ptr)) = "" + default: + *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + number := *((*Number)(ptr)) + if len(number) == 0 { + stream.writeByte('0') + } else { + stream.WriteRaw(string(number)) + } +} + +func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*Number)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go new file mode 100644 index 000000000..f2619936c --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go @@ -0,0 +1,60 @@ +package jsoniter + +import ( + "encoding/json" + "github.com/modern-go/reflect2" + "unsafe" +) + +var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem() +var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem() + +func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{} + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{} + } + return nil +} + +func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{} + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{} + } + return nil +} + +type jsonRawMessageCodec struct { +} + +func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*json.RawMessage)(ptr)))) +} + +func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 +} + +type jsoniterRawMessageCodec struct { +} + +func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*RawMessage)(ptr)))) +} + +func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*RawMessage)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go new file mode 100644 index 000000000..7f66a88b0 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_map.go @@ -0,0 +1,326 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "sort" + "unsafe" +) + +func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder { + mapType := typ.(*reflect2.UnsafeMapType) + keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()) + elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem()) + return &mapDecoder{ + mapType: mapType, + keyType: mapType.Key(), + elemType: mapType.Elem(), + keyDecoder: keyDecoder, + elemDecoder: elemDecoder, + } +} + +func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder { + mapType := typ.(*reflect2.UnsafeMapType) + if ctx.sortMapKeys { + return &sortKeysMapEncoder{ + mapType: mapType, + keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), + elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), + } + } + return &mapEncoder{ + mapType: mapType, + keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), + elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), + } +} + +func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ) + if decoder != nil { + return decoder + } + for _, extension := range ctx.extraExtensions { + decoder := extension.CreateMapKeyDecoder(typ) + if decoder != nil { + return decoder + } + } + switch typ.Kind() { + case reflect.String: + return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) + case reflect.Bool, + reflect.Uint8, reflect.Int8, + reflect.Uint16, reflect.Int16, + reflect.Uint32, reflect.Int32, + reflect.Uint64, reflect.Int64, + reflect.Uint, reflect.Int, + reflect.Float32, reflect.Float64, + reflect.Uintptr: + typ = reflect2.DefaultTypeOfKind(typ.Kind()) + return &numericMapKeyDecoder{decoderOfType(ctx, typ)} + default: + ptrType := reflect2.PtrTo(typ) + if ptrType.Implements(textMarshalerType) { + return &referenceDecoder{ + &textUnmarshalerDecoder{ + valType: ptrType, + }, + } + } + if typ.Implements(textMarshalerType) { + return &textUnmarshalerDecoder{ + valType: typ, + } + } + return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)} + } +} + +func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ) + if encoder != nil { + return encoder + } + for _, extension := range ctx.extraExtensions { + encoder := extension.CreateMapKeyEncoder(typ) + if encoder != nil { + return encoder + } + } + switch typ.Kind() { + case reflect.String: + return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) + case reflect.Bool, + reflect.Uint8, reflect.Int8, + reflect.Uint16, reflect.Int16, + reflect.Uint32, reflect.Int32, + reflect.Uint64, reflect.Int64, + reflect.Uint, reflect.Int, + reflect.Float32, reflect.Float64, + reflect.Uintptr: + typ = reflect2.DefaultTypeOfKind(typ.Kind()) + return &numericMapKeyEncoder{encoderOfType(ctx, typ)} + default: + if typ == textMarshalerType { + return &directTextMarshalerEncoder{ + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + } + if typ.Implements(textMarshalerType) { + return &textMarshalerEncoder{ + valType: typ, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + } + if typ.Kind() == reflect.Interface { + return &dynamicMapKeyEncoder{ctx, typ} + } + return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} + } +} + +type mapDecoder struct { + mapType *reflect2.UnsafeMapType + keyType reflect2.Type + elemType reflect2.Type + keyDecoder ValDecoder + elemDecoder ValDecoder +} + +func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + mapType := decoder.mapType + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + *(*unsafe.Pointer)(ptr) = nil + mapType.UnsafeSet(ptr, mapType.UnsafeNew()) + return + } + if mapType.UnsafeIsNil(ptr) { + mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0)) + } + if c != '{' { + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return + } + c = iter.nextToken() + if c == '}' { + return + } + if c != '"' { + iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) + return + } + iter.unreadByte() + key := decoder.keyType.UnsafeNew() + decoder.keyDecoder.Decode(key, iter) + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return + } + elem := decoder.elemType.UnsafeNew() + decoder.elemDecoder.Decode(elem, iter) + decoder.mapType.UnsafeSetIndex(ptr, key, elem) + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + key := decoder.keyType.UnsafeNew() + decoder.keyDecoder.Decode(key, iter) + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return + } + elem := decoder.elemType.UnsafeNew() + decoder.elemDecoder.Decode(elem, iter) + decoder.mapType.UnsafeSetIndex(ptr, key, elem) + } + if c != '}' { + iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c})) + } +} + +type numericMapKeyDecoder struct { + decoder ValDecoder +} + +func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) + return + } + decoder.decoder.Decode(ptr, iter) + c = iter.nextToken() + if c != '"' { + iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) + return + } +} + +type numericMapKeyEncoder struct { + encoder ValEncoder +} + +func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.encoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type dynamicMapKeyEncoder struct { + ctx *ctx + valType reflect2.Type +} + +func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) +} + +func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + obj := encoder.valType.UnsafeIndirect(ptr) + return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) +} + +type mapEncoder struct { + mapType *reflect2.UnsafeMapType + keyEncoder ValEncoder + elemEncoder ValEncoder +} + +func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteObjectStart() + iter := encoder.mapType.UnsafeIterate(ptr) + for i := 0; iter.HasNext(); i++ { + if i != 0 { + stream.WriteMore() + } + key, elem := iter.UnsafeNext() + encoder.keyEncoder.Encode(key, stream) + if stream.indention > 0 { + stream.writeTwoBytes(byte(':'), byte(' ')) + } else { + stream.writeByte(':') + } + encoder.elemEncoder.Encode(elem, stream) + } + stream.WriteObjectEnd() +} + +func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + iter := encoder.mapType.UnsafeIterate(ptr) + return !iter.HasNext() +} + +type sortKeysMapEncoder struct { + mapType *reflect2.UnsafeMapType + keyEncoder ValEncoder + elemEncoder ValEncoder +} + +func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *(*unsafe.Pointer)(ptr) == nil { + stream.WriteNil() + return + } + stream.WriteObjectStart() + mapIter := encoder.mapType.UnsafeIterate(ptr) + subStream := stream.cfg.BorrowStream(nil) + subIter := stream.cfg.BorrowIterator(nil) + keyValues := encodedKeyValues{} + for mapIter.HasNext() { + subStream.buf = make([]byte, 0, 64) + key, elem := mapIter.UnsafeNext() + encoder.keyEncoder.Encode(key, subStream) + if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { + stream.Error = subStream.Error + } + encodedKey := subStream.Buffer() + subIter.ResetBytes(encodedKey) + decodedKey := subIter.ReadString() + if stream.indention > 0 { + subStream.writeTwoBytes(byte(':'), byte(' ')) + } else { + subStream.writeByte(':') + } + encoder.elemEncoder.Encode(elem, subStream) + keyValues = append(keyValues, encodedKV{ + key: decodedKey, + keyValue: subStream.Buffer(), + }) + } + sort.Sort(keyValues) + for i, keyValue := range keyValues { + if i != 0 { + stream.WriteMore() + } + stream.Write(keyValue.keyValue) + } + stream.WriteObjectEnd() + stream.cfg.ReturnStream(subStream) + stream.cfg.ReturnIterator(subIter) +} + +func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + iter := encoder.mapType.UnsafeIterate(ptr) + return !iter.HasNext() +} + +type encodedKeyValues []encodedKV + +type encodedKV struct { + key string + keyValue []byte +} + +func (sv encodedKeyValues) Len() int { return len(sv) } +func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key } diff --git a/vendor/github.com/json-iterator/go/reflect_marshaler.go b/vendor/github.com/json-iterator/go/reflect_marshaler.go new file mode 100644 index 000000000..58ac959ad --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_marshaler.go @@ -0,0 +1,218 @@ +package jsoniter + +import ( + "encoding" + "encoding/json" + "github.com/modern-go/reflect2" + "unsafe" +) + +var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem() +var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem() +var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem() +var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem() + +func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder { + ptrType := reflect2.PtrTo(typ) + if ptrType.Implements(unmarshalerType) { + return &referenceDecoder{ + &unmarshalerDecoder{ptrType}, + } + } + if ptrType.Implements(textUnmarshalerType) { + return &referenceDecoder{ + &textUnmarshalerDecoder{ptrType}, + } + } + return nil +} + +func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == marshalerType { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &directMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + } + return encoder + } + if typ.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &marshalerEncoder{ + valType: typ, + checkIsEmpty: checkIsEmpty, + } + return encoder + } + ptrType := reflect2.PtrTo(typ) + if ctx.prefix != "" && ptrType.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, ptrType) + var encoder ValEncoder = &marshalerEncoder{ + valType: ptrType, + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + if typ == textMarshalerType { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &directTextMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + return encoder + } + if typ.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: typ, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return encoder + } + // if prefix is empty, the type is the root type + if ctx.prefix != "" && ptrType.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, ptrType) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: ptrType, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + return nil +} + +type marshalerEncoder struct { + checkIsEmpty checkIsEmpty + valType reflect2.Type +} + +func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + if encoder.valType.IsNullable() && reflect2.IsNil(obj) { + stream.WriteNil() + return + } + marshaler := obj.(json.Marshaler) + bytes, err := marshaler.MarshalJSON() + if err != nil { + stream.Error = err + } else { + stream.Write(bytes) + } +} + +func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type directMarshalerEncoder struct { + checkIsEmpty checkIsEmpty +} + +func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + marshaler := *(*json.Marshaler)(ptr) + if marshaler == nil { + stream.WriteNil() + return + } + bytes, err := marshaler.MarshalJSON() + if err != nil { + stream.Error = err + } else { + stream.Write(bytes) + } +} + +func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type textMarshalerEncoder struct { + valType reflect2.Type + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty +} + +func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + if encoder.valType.IsNullable() && reflect2.IsNil(obj) { + stream.WriteNil() + return + } + marshaler := (obj).(encoding.TextMarshaler) + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + str := string(bytes) + encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) + } +} + +func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type directTextMarshalerEncoder struct { + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty +} + +func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + marshaler := *(*encoding.TextMarshaler)(ptr) + if marshaler == nil { + stream.WriteNil() + return + } + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + str := string(bytes) + encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) + } +} + +func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type unmarshalerDecoder struct { + valType reflect2.Type +} + +func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valType := decoder.valType + obj := valType.UnsafeIndirect(ptr) + unmarshaler := obj.(json.Unmarshaler) + iter.nextToken() + iter.unreadByte() // skip spaces + bytes := iter.SkipAndReturnBytes() + err := unmarshaler.UnmarshalJSON(bytes) + if err != nil { + iter.ReportError("unmarshalerDecoder", err.Error()) + } +} + +type textUnmarshalerDecoder struct { + valType reflect2.Type +} + +func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valType := decoder.valType + obj := valType.UnsafeIndirect(ptr) + if reflect2.IsNil(obj) { + ptrType := valType.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + elem := elemType.UnsafeNew() + ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem)) + obj = valType.UnsafeIndirect(ptr) + } + unmarshaler := (obj).(encoding.TextUnmarshaler) + str := iter.ReadString() + err := unmarshaler.UnmarshalText([]byte(str)) + if err != nil { + iter.ReportError("textUnmarshalerDecoder", err.Error()) + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_native.go b/vendor/github.com/json-iterator/go/reflect_native.go new file mode 100644 index 000000000..9042eb0cb --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_native.go @@ -0,0 +1,451 @@ +package jsoniter + +import ( + "encoding/base64" + "reflect" + "strconv" + "unsafe" + + "github.com/modern-go/reflect2" +) + +const ptrSize = 32 << uintptr(^uintptr(0)>>63) + +func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { + sliceDecoder := decoderOfSlice(ctx, typ) + return &base64Codec{sliceDecoder: sliceDecoder} + } + typeName := typ.String() + kind := typ.Kind() + switch kind { + case reflect.String: + if typeName != "string" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) + } + return &stringCodec{} + case reflect.Int: + if typeName != "int" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &int32Codec{} + } + return &int64Codec{} + case reflect.Int8: + if typeName != "int8" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) + } + return &int8Codec{} + case reflect.Int16: + if typeName != "int16" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) + } + return &int16Codec{} + case reflect.Int32: + if typeName != "int32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) + } + return &int32Codec{} + case reflect.Int64: + if typeName != "int64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) + } + return &int64Codec{} + case reflect.Uint: + if typeName != "uint" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint8: + if typeName != "uint8" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) + } + return &uint8Codec{} + case reflect.Uint16: + if typeName != "uint16" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) + } + return &uint16Codec{} + case reflect.Uint32: + if typeName != "uint32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) + } + return &uint32Codec{} + case reflect.Uintptr: + if typeName != "uintptr" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) + } + if ptrSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint64: + if typeName != "uint64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) + } + return &uint64Codec{} + case reflect.Float32: + if typeName != "float32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) + } + return &float32Codec{} + case reflect.Float64: + if typeName != "float64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) + } + return &float64Codec{} + case reflect.Bool: + if typeName != "bool" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) + } + return &boolCodec{} + } + return nil +} + +func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { + sliceDecoder := decoderOfSlice(ctx, typ) + return &base64Codec{sliceDecoder: sliceDecoder} + } + typeName := typ.String() + switch typ.Kind() { + case reflect.String: + if typeName != "string" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) + } + return &stringCodec{} + case reflect.Int: + if typeName != "int" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &int32Codec{} + } + return &int64Codec{} + case reflect.Int8: + if typeName != "int8" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) + } + return &int8Codec{} + case reflect.Int16: + if typeName != "int16" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) + } + return &int16Codec{} + case reflect.Int32: + if typeName != "int32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) + } + return &int32Codec{} + case reflect.Int64: + if typeName != "int64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) + } + return &int64Codec{} + case reflect.Uint: + if typeName != "uint" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint8: + if typeName != "uint8" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) + } + return &uint8Codec{} + case reflect.Uint16: + if typeName != "uint16" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) + } + return &uint16Codec{} + case reflect.Uint32: + if typeName != "uint32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) + } + return &uint32Codec{} + case reflect.Uintptr: + if typeName != "uintptr" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) + } + if ptrSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint64: + if typeName != "uint64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) + } + return &uint64Codec{} + case reflect.Float32: + if typeName != "float32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) + } + return &float32Codec{} + case reflect.Float64: + if typeName != "float64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) + } + return &float64Codec{} + case reflect.Bool: + if typeName != "bool" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) + } + return &boolCodec{} + } + return nil +} + +type stringCodec struct { +} + +func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*string)(ptr)) = iter.ReadString() +} + +func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteString(str) +} + +func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +type int8Codec struct { +} + +func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int8)(ptr)) = iter.ReadInt8() + } +} + +func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt8(*((*int8)(ptr))) +} + +func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int8)(ptr)) == 0 +} + +type int16Codec struct { +} + +func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int16)(ptr)) = iter.ReadInt16() + } +} + +func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt16(*((*int16)(ptr))) +} + +func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int16)(ptr)) == 0 +} + +type int32Codec struct { +} + +func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int32)(ptr)) = iter.ReadInt32() + } +} + +func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt32(*((*int32)(ptr))) +} + +func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int32)(ptr)) == 0 +} + +type int64Codec struct { +} + +func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int64)(ptr)) = iter.ReadInt64() + } +} + +func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt64(*((*int64)(ptr))) +} + +func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int64)(ptr)) == 0 +} + +type uint8Codec struct { +} + +func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint8)(ptr)) = iter.ReadUint8() + } +} + +func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint8(*((*uint8)(ptr))) +} + +func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint8)(ptr)) == 0 +} + +type uint16Codec struct { +} + +func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint16)(ptr)) = iter.ReadUint16() + } +} + +func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint16(*((*uint16)(ptr))) +} + +func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint16)(ptr)) == 0 +} + +type uint32Codec struct { +} + +func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint32)(ptr)) = iter.ReadUint32() + } +} + +func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint32(*((*uint32)(ptr))) +} + +func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint32)(ptr)) == 0 +} + +type uint64Codec struct { +} + +func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint64)(ptr)) = iter.ReadUint64() + } +} + +func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint64(*((*uint64)(ptr))) +} + +func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint64)(ptr)) == 0 +} + +type float32Codec struct { +} + +func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float32)(ptr)) = iter.ReadFloat32() + } +} + +func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32(*((*float32)(ptr))) +} + +func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type float64Codec struct { +} + +func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float64)(ptr)) = iter.ReadFloat64() + } +} + +func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64(*((*float64)(ptr))) +} + +func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +type boolCodec struct { +} + +func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*bool)(ptr)) = iter.ReadBool() + } +} + +func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteBool(*((*bool)(ptr))) +} + +func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool { + return !(*((*bool)(ptr))) +} + +type base64Codec struct { + sliceType *reflect2.UnsafeSliceType + sliceDecoder ValDecoder +} + +func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + codec.sliceType.UnsafeSetNil(ptr) + return + } + switch iter.WhatIsNext() { + case StringValue: + src := iter.ReadString() + dst, err := base64.StdEncoding.DecodeString(src) + if err != nil { + iter.ReportError("decode base64", err.Error()) + } else { + codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst)) + } + case ArrayValue: + codec.sliceDecoder.Decode(ptr, iter) + default: + iter.ReportError("base64Codec", "invalid input") + } +} + +func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + src := *((*[]byte)(ptr)) + if len(src) == 0 { + stream.WriteNil() + return + } + encoding := base64.StdEncoding + stream.writeByte('"') + size := encoding.EncodedLen(len(src)) + buf := make([]byte, size) + encoding.Encode(buf, src) + stream.buf = append(stream.buf, buf...) + stream.writeByte('"') +} + +func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*[]byte)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_optional.go b/vendor/github.com/json-iterator/go/reflect_optional.go new file mode 100644 index 000000000..43ec71d6d --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_optional.go @@ -0,0 +1,133 @@ +package jsoniter + +import ( + "github.com/modern-go/reflect2" + "reflect" + "unsafe" +) + +func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + decoder := decoderOfType(ctx, elemType) + if ctx.prefix == "" && elemType.Kind() == reflect.Ptr { + return &dereferenceDecoder{elemType, decoder} + } + return &OptionalDecoder{elemType, decoder} +} + +func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + elemEncoder := encoderOfType(ctx, elemType) + encoder := &OptionalEncoder{elemEncoder} + return encoder +} + +type OptionalDecoder struct { + ValueType reflect2.Type + ValueDecoder ValDecoder +} + +func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + *((*unsafe.Pointer)(ptr)) = nil + } else { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + newPtr := decoder.ValueType.UnsafeNew() + decoder.ValueDecoder.Decode(newPtr, iter) + *((*unsafe.Pointer)(ptr)) = newPtr + } else { + //reuse existing instance + decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } + } +} + +type dereferenceDecoder struct { + // only to deference a pointer + valueType reflect2.Type + valueDecoder ValDecoder +} + +func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + newPtr := decoder.valueType.UnsafeNew() + decoder.valueDecoder.Decode(newPtr, iter) + *((*unsafe.Pointer)(ptr)) = newPtr + } else { + //reuse existing instance + decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } +} + +type OptionalEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*unsafe.Pointer)(ptr)) == nil +} + +type dereferenceEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + dePtr := *((*unsafe.Pointer)(ptr)) + if dePtr == nil { + return true + } + return encoder.ValueEncoder.IsEmpty(dePtr) +} + +func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { + deReferenced := *((*unsafe.Pointer)(ptr)) + if deReferenced == nil { + return true + } + isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil) + if !converted { + return false + } + fieldPtr := unsafe.Pointer(deReferenced) + return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) +} + +type referenceEncoder struct { + encoder ValEncoder +} + +func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +} + +type referenceDecoder struct { + decoder ValDecoder +} + +func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.decoder.Decode(unsafe.Pointer(&ptr), iter) +} diff --git a/vendor/github.com/json-iterator/go/reflect_slice.go b/vendor/github.com/json-iterator/go/reflect_slice.go new file mode 100644 index 000000000..9441d79df --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_slice.go @@ -0,0 +1,99 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "unsafe" +) + +func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder { + sliceType := typ.(*reflect2.UnsafeSliceType) + decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) + return &sliceDecoder{sliceType, decoder} +} + +func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder { + sliceType := typ.(*reflect2.UnsafeSliceType) + encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) + return &sliceEncoder{sliceType, encoder} +} + +type sliceEncoder struct { + sliceType *reflect2.UnsafeSliceType + elemEncoder ValEncoder +} + +func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if encoder.sliceType.UnsafeIsNil(ptr) { + stream.WriteNil() + return + } + length := encoder.sliceType.UnsafeLengthOf(ptr) + if length == 0 { + stream.WriteEmptyArray() + return + } + stream.WriteArrayStart() + encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream) + for i := 1; i < length; i++ { + stream.WriteMore() + elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i) + encoder.elemEncoder.Encode(elemPtr, stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error()) + } +} + +func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.sliceType.UnsafeLengthOf(ptr) == 0 +} + +type sliceDecoder struct { + sliceType *reflect2.UnsafeSliceType + elemDecoder ValDecoder +} + +func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error()) + } +} + +func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + sliceType := decoder.sliceType + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + sliceType.UnsafeSetNil(ptr) + return + } + if c != '[' { + iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c})) + return + } + c = iter.nextToken() + if c == ']' { + sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0)) + return + } + iter.unreadByte() + sliceType.UnsafeGrow(ptr, 1) + elemPtr := sliceType.UnsafeGetIndex(ptr, 0) + decoder.elemDecoder.Decode(elemPtr, iter) + length := 1 + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + idx := length + length += 1 + sliceType.UnsafeGrow(ptr, length) + elemPtr = sliceType.UnsafeGetIndex(ptr, idx) + decoder.elemDecoder.Decode(elemPtr, iter) + } + if c != ']' { + iter.ReportError("decode slice", "expect ], but found "+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go new file mode 100644 index 000000000..355d2d116 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go @@ -0,0 +1,1048 @@ +package jsoniter + +import ( + "fmt" + "io" + "strings" + "unsafe" + + "github.com/modern-go/reflect2" +) + +func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { + bindings := map[string]*Binding{} + structDescriptor := describeStruct(ctx, typ) + for _, binding := range structDescriptor.Fields { + for _, fromName := range binding.FromNames { + old := bindings[fromName] + if old == nil { + bindings[fromName] = binding + continue + } + ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding) + if ignoreOld { + delete(bindings, fromName) + } + if !ignoreNew { + bindings[fromName] = binding + } + } + } + fields := map[string]*structFieldDecoder{} + for k, binding := range bindings { + fields[k] = binding.Decoder.(*structFieldDecoder) + } + + if !ctx.caseSensitive() { + for k, binding := range bindings { + if _, found := fields[strings.ToLower(k)]; !found { + fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) + } + } + } + + return createStructDecoder(ctx, typ, fields) +} + +func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { + if ctx.disallowUnknownFields { + return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} + } + knownHash := map[int64]struct{}{ + 0: {}, + } + + switch len(fields) { + case 0: + return &skipObjectDecoder{typ} + case 1: + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} + } + case 2: + var fieldHash1 int64 + var fieldHash2 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldHash1 == 0 { + fieldHash1 = fieldHash + fieldDecoder1 = fieldDecoder + } else { + fieldHash2 = fieldHash + fieldDecoder2 = fieldDecoder + } + } + return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} + case 3: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } + } + return &threeFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3} + case 4: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } + } + return &fourFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4} + case 5: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } + } + return &fiveFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5} + case 6: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } + } + return &sixFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6} + case 7: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } + } + return &sevenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7} + case 8: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } + } + return &eightFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8} + case 9: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } + } + return &nineFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9} + case 10: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldName10 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + var fieldDecoder10 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else if fieldName9 == 0 { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } else { + fieldName10 = fieldHash + fieldDecoder10 = fieldDecoder + } + } + return &tenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9, + fieldName10, fieldDecoder10} + } + return &generalStructDecoder{typ, fields, false} +} + +type generalStructDecoder struct { + typ reflect2.Type + fields map[string]*structFieldDecoder + disallowUnknownFields bool +} + +func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + var c byte + for c = ','; c == ','; c = iter.nextToken() { + decoder.decodeOneField(ptr, iter) + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + if c != '}' { + iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c})) + } +} + +func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { + var field string + var fieldDecoder *structFieldDecoder + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes := iter.ReadStringAsSlice() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil && !iter.cfg.caseSensitive { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } else { + field = iter.ReadString() + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil && !iter.cfg.caseSensitive { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } + if fieldDecoder == nil { + msg := "found unknown field: " + field + if decoder.disallowUnknownFields { + iter.ReportError("ReadObject", msg) + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + iter.Skip() + return + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + fieldDecoder.Decode(ptr, iter) +} + +type skipObjectDecoder struct { + typ reflect2.Type +} + +func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valueType := iter.WhatIsNext() + if valueType != ObjectValue && valueType != NilValue { + iter.ReportError("skipObjectDecoder", "expect object or null") + return + } + iter.Skip() +} + +type oneFieldStructDecoder struct { + typ reflect2.Type + fieldHash int64 + fieldDecoder *structFieldDecoder +} + +func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + if iter.readFieldHash() == decoder.fieldHash { + decoder.fieldDecoder.Decode(ptr, iter) + } else { + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type twoFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder +} + +func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type threeFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder +} + +func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type fourFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder +} + +func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type fiveFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder +} + +func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type sixFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder +} + +func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type sevenFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder +} + +func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type eightFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder +} + +func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type nineFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder + fieldHash9 int64 + fieldDecoder9 *structFieldDecoder +} + +func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type tenFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder + fieldHash9 int64 + fieldDecoder9 *structFieldDecoder + fieldHash10 int64 + fieldDecoder10 *structFieldDecoder +} + +func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + case decoder.fieldHash10: + decoder.fieldDecoder10.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type structFieldDecoder struct { + field reflect2.StructField + fieldDecoder ValDecoder +} + +func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + fieldPtr := decoder.field.UnsafeGet(ptr) + decoder.fieldDecoder.Decode(fieldPtr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error()) + } +} + +type stringModeStringDecoder struct { + elemDecoder ValDecoder + cfg *frozenConfig +} + +func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.elemDecoder.Decode(ptr, iter) + str := *((*string)(ptr)) + tempIter := decoder.cfg.BorrowIterator([]byte(str)) + defer decoder.cfg.ReturnIterator(tempIter) + *((*string)(ptr)) = tempIter.ReadString() +} + +type stringModeNumberDecoder struct { + elemDecoder ValDecoder +} + +func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } + decoder.elemDecoder.Decode(ptr, iter) + if iter.Error != nil { + return + } + c = iter.readByte() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go new file mode 100644 index 000000000..d0759cf64 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go @@ -0,0 +1,210 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "unsafe" +) + +func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { + type bindingTo struct { + binding *Binding + toName string + ignored bool + } + orderedBindings := []*bindingTo{} + structDescriptor := describeStruct(ctx, typ) + for _, binding := range structDescriptor.Fields { + for _, toName := range binding.ToNames { + new := &bindingTo{ + binding: binding, + toName: toName, + } + for _, old := range orderedBindings { + if old.toName != toName { + continue + } + old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) + } + orderedBindings = append(orderedBindings, new) + } + } + if len(orderedBindings) == 0 { + return &emptyStructEncoder{} + } + finalOrderedFields := []structFieldTo{} + for _, bindingTo := range orderedBindings { + if !bindingTo.ignored { + finalOrderedFields = append(finalOrderedFields, structFieldTo{ + encoder: bindingTo.binding.Encoder.(*structFieldEncoder), + toName: bindingTo.toName, + }) + } + } + return &structEncoder{typ, finalOrderedFields} +} + +func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty { + encoder := createEncoderOfNative(ctx, typ) + if encoder != nil { + return encoder + } + kind := typ.Kind() + switch kind { + case reflect.Interface: + return &dynamicEncoder{typ} + case reflect.Struct: + return &structEncoder{typ: typ} + case reflect.Array: + return &arrayEncoder{} + case reflect.Slice: + return &sliceEncoder{} + case reflect.Map: + return encoderOfMap(ctx, typ) + case reflect.Ptr: + return &OptionalEncoder{} + default: + return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)} + } +} + +func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { + newTagged := new.Field.Tag().Get(cfg.getTagKey()) != "" + oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != "" + if newTagged { + if oldTagged { + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } else { + return true, false + } + } else { + if oldTagged { + return true, false + } + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } +} + +type structFieldEncoder struct { + field reflect2.StructField + fieldEncoder ValEncoder + omitempty bool +} + +func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + fieldPtr := encoder.field.UnsafeGet(ptr) + encoder.fieldEncoder.Encode(fieldPtr, stream) + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) + } +} + +func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { + fieldPtr := encoder.field.UnsafeGet(ptr) + return encoder.fieldEncoder.IsEmpty(fieldPtr) +} + +func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { + isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil) + if !converted { + return false + } + fieldPtr := encoder.field.UnsafeGet(ptr) + return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) +} + +type IsEmbeddedPtrNil interface { + IsEmbeddedPtrNil(ptr unsafe.Pointer) bool +} + +type structEncoder struct { + typ reflect2.Type + fields []structFieldTo +} + +type structFieldTo struct { + encoder *structFieldEncoder + toName string +} + +func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteObjectStart() + isNotFirst := false + for _, field := range encoder.fields { + if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { + continue + } + if field.encoder.IsEmbeddedPtrNil(ptr) { + continue + } + if isNotFirst { + stream.WriteMore() + } + stream.WriteObjectField(field.toName) + field.encoder.Encode(ptr, stream) + isNotFirst = true + } + stream.WriteObjectEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) + } +} + +func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type emptyStructEncoder struct { +} + +func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyObject() +} + +func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type stringModeNumberEncoder struct { + elemEncoder ValEncoder +} + +func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.elemEncoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} + +type stringModeStringEncoder struct { + elemEncoder ValEncoder + cfg *frozenConfig +} + +func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + tempStream := encoder.cfg.BorrowStream(nil) + defer encoder.cfg.ReturnStream(tempStream) + encoder.elemEncoder.Encode(ptr, tempStream) + stream.WriteString(string(tempStream.Buffer())) +} + +func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} diff --git a/vendor/github.com/json-iterator/go/stream.go b/vendor/github.com/json-iterator/go/stream.go new file mode 100644 index 000000000..17662fded --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream.go @@ -0,0 +1,211 @@ +package jsoniter + +import ( + "io" +) + +// stream is a io.Writer like object, with JSON specific write functions. +// Error is not returned as return value, but stored as Error member on this stream instance. +type Stream struct { + cfg *frozenConfig + out io.Writer + buf []byte + Error error + indention int + Attachment interface{} // open for customized encoder +} + +// NewStream create new stream instance. +// cfg can be jsoniter.ConfigDefault. +// out can be nil if write to internal buffer. +// bufSize is the initial size for the internal buffer in bytes. +func NewStream(cfg API, out io.Writer, bufSize int) *Stream { + return &Stream{ + cfg: cfg.(*frozenConfig), + out: out, + buf: make([]byte, 0, bufSize), + Error: nil, + indention: 0, + } +} + +// Pool returns a pool can provide more stream with same configuration +func (stream *Stream) Pool() StreamPool { + return stream.cfg +} + +// Reset reuse this stream instance by assign a new writer +func (stream *Stream) Reset(out io.Writer) { + stream.out = out + stream.buf = stream.buf[:0] +} + +// Available returns how many bytes are unused in the buffer. +func (stream *Stream) Available() int { + return cap(stream.buf) - len(stream.buf) +} + +// Buffered returns the number of bytes that have been written into the current buffer. +func (stream *Stream) Buffered() int { + return len(stream.buf) +} + +// Buffer if writer is nil, use this method to take the result +func (stream *Stream) Buffer() []byte { + return stream.buf +} + +// SetBuffer allows to append to the internal buffer directly +func (stream *Stream) SetBuffer(buf []byte) { + stream.buf = buf +} + +// Write writes the contents of p into the buffer. +// It returns the number of bytes written. +// If nn < len(p), it also returns an error explaining +// why the write is short. +func (stream *Stream) Write(p []byte) (nn int, err error) { + stream.buf = append(stream.buf, p...) + if stream.out != nil { + nn, err = stream.out.Write(stream.buf) + stream.buf = stream.buf[nn:] + return + } + return len(p), nil +} + +// WriteByte writes a single byte. +func (stream *Stream) writeByte(c byte) { + stream.buf = append(stream.buf, c) +} + +func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { + stream.buf = append(stream.buf, c1, c2) +} + +func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { + stream.buf = append(stream.buf, c1, c2, c3) +} + +func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { + stream.buf = append(stream.buf, c1, c2, c3, c4) +} + +func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { + stream.buf = append(stream.buf, c1, c2, c3, c4, c5) +} + +// Flush writes any buffered data to the underlying io.Writer. +func (stream *Stream) Flush() error { + if stream.out == nil { + return nil + } + if stream.Error != nil { + return stream.Error + } + n, err := stream.out.Write(stream.buf) + if err != nil { + if stream.Error == nil { + stream.Error = err + } + return err + } + stream.buf = stream.buf[n:] + return nil +} + +// WriteRaw write string out without quotes, just like []byte +func (stream *Stream) WriteRaw(s string) { + stream.buf = append(stream.buf, s...) +} + +// WriteNil write null to stream +func (stream *Stream) WriteNil() { + stream.writeFourBytes('n', 'u', 'l', 'l') +} + +// WriteTrue write true to stream +func (stream *Stream) WriteTrue() { + stream.writeFourBytes('t', 'r', 'u', 'e') +} + +// WriteFalse write false to stream +func (stream *Stream) WriteFalse() { + stream.writeFiveBytes('f', 'a', 'l', 's', 'e') +} + +// WriteBool write true or false into stream +func (stream *Stream) WriteBool(val bool) { + if val { + stream.WriteTrue() + } else { + stream.WriteFalse() + } +} + +// WriteObjectStart write { with possible indention +func (stream *Stream) WriteObjectStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('{') + stream.writeIndention(0) +} + +// WriteObjectField write "field": with possible indention +func (stream *Stream) WriteObjectField(field string) { + stream.WriteString(field) + if stream.indention > 0 { + stream.writeTwoBytes(':', ' ') + } else { + stream.writeByte(':') + } +} + +// WriteObjectEnd write } with possible indention +func (stream *Stream) WriteObjectEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte('}') +} + +// WriteEmptyObject write {} +func (stream *Stream) WriteEmptyObject() { + stream.writeByte('{') + stream.writeByte('}') +} + +// WriteMore write , with possible indention +func (stream *Stream) WriteMore() { + stream.writeByte(',') + stream.writeIndention(0) + stream.Flush() +} + +// WriteArrayStart write [ with possible indention +func (stream *Stream) WriteArrayStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('[') + stream.writeIndention(0) +} + +// WriteEmptyArray write [] +func (stream *Stream) WriteEmptyArray() { + stream.writeTwoBytes('[', ']') +} + +// WriteArrayEnd write ] with possible indention +func (stream *Stream) WriteArrayEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte(']') +} + +func (stream *Stream) writeIndention(delta int) { + if stream.indention == 0 { + return + } + stream.writeByte('\n') + toWrite := stream.indention - delta + for i := 0; i < toWrite; i++ { + stream.buf = append(stream.buf, ' ') + } +} diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go new file mode 100644 index 000000000..f318d2c59 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_float.go @@ -0,0 +1,94 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var pow10 []uint64 + +func init() { + pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} +} + +// WriteFloat32 write float32 to stream +func (stream *Stream) WriteFloat32(val float32) { + abs := math.Abs(float64(val)) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if float32(abs) < 1e-6 || float32(abs) >= 1e21 { + fmt = 'e' + } + } + stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32) +} + +// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat32Lossy(val float32) { + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat32(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(float64(val)*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] + } +} + +// WriteFloat64 write float64 to stream +func (stream *Stream) WriteFloat64(val float64) { + abs := math.Abs(val) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if abs < 1e-6 || abs >= 1e21 { + fmt = 'e' + } + } + stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64) +} + +// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat64Lossy(val float64) { + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat64(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(val*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] + } +} diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go new file mode 100644 index 000000000..d1059ee4c --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_int.go @@ -0,0 +1,190 @@ +package jsoniter + +var digits []uint32 + +func init() { + digits = make([]uint32, 1000) + for i := uint32(0); i < 1000; i++ { + digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0' + if i < 10 { + digits[i] += 2 << 24 + } else if i < 100 { + digits[i] += 1 << 24 + } + } +} + +func writeFirstBuf(space []byte, v uint32) []byte { + start := v >> 24 + if start == 0 { + space = append(space, byte(v>>16), byte(v>>8)) + } else if start == 1 { + space = append(space, byte(v>>8)) + } + space = append(space, byte(v)) + return space +} + +func writeBuf(buf []byte, v uint32) []byte { + return append(buf, byte(v>>16), byte(v>>8), byte(v)) +} + +// WriteUint8 write uint8 to stream +func (stream *Stream) WriteUint8(val uint8) { + stream.buf = writeFirstBuf(stream.buf, digits[val]) +} + +// WriteInt8 write int8 to stream +func (stream *Stream) WriteInt8(nval int8) { + var val uint8 + if nval < 0 { + val = uint8(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint8(nval) + } + stream.buf = writeFirstBuf(stream.buf, digits[val]) +} + +// WriteUint16 write uint16 to stream +func (stream *Stream) WriteUint16(val uint16) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return +} + +// WriteInt16 write int16 to stream +func (stream *Stream) WriteInt16(nval int16) { + var val uint16 + if nval < 0 { + val = uint16(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint16(nval) + } + stream.WriteUint16(val) +} + +// WriteUint32 write uint32 to stream +func (stream *Stream) WriteUint32(val uint32) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q2]) + } else { + r3 := q2 - q3*1000 + stream.buf = append(stream.buf, byte(q3+'0')) + stream.buf = writeBuf(stream.buf, digits[r3]) + } + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) +} + +// WriteInt32 write int32 to stream +func (stream *Stream) WriteInt32(nval int32) { + var val uint32 + if nval < 0 { + val = uint32(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint32(nval) + } + stream.WriteUint32(val) +} + +// WriteUint64 write uint64 to stream +func (stream *Stream) WriteUint64(val uint64) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q2]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r3 := q2 - q3*1000 + q4 := q3 / 1000 + if q4 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q3]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r4 := q3 - q4*1000 + q5 := q4 / 1000 + if q5 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q4]) + stream.buf = writeBuf(stream.buf, digits[r4]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r5 := q4 - q5*1000 + q6 := q5 / 1000 + if q6 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q5]) + } else { + stream.buf = writeFirstBuf(stream.buf, digits[q6]) + r6 := q5 - q6*1000 + stream.buf = writeBuf(stream.buf, digits[r6]) + } + stream.buf = writeBuf(stream.buf, digits[r5]) + stream.buf = writeBuf(stream.buf, digits[r4]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) +} + +// WriteInt64 write int64 to stream +func (stream *Stream) WriteInt64(nval int64) { + var val uint64 + if nval < 0 { + val = uint64(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint64(nval) + } + stream.WriteUint64(val) +} + +// WriteInt write int to stream +func (stream *Stream) WriteInt(val int) { + stream.WriteInt64(int64(val)) +} + +// WriteUint write uint to stream +func (stream *Stream) WriteUint(val uint) { + stream.WriteUint64(uint64(val)) +} diff --git a/vendor/github.com/json-iterator/go/stream_str.go b/vendor/github.com/json-iterator/go/stream_str.go new file mode 100644 index 000000000..54c2ba0b3 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_str.go @@ -0,0 +1,372 @@ +package jsoniter + +import ( + "unicode/utf8" +) + +// htmlSafeSet holds the value true if the ASCII character with the given +// array position can be safely represented inside a JSON string, embedded +// inside of HTML