From dfd0e46894f2f0fa6c444916392c9f95c5930466 Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Thu, 1 Dec 2016 22:13:29 -0500 Subject: [PATCH] Switch from _third_party to vendor. This switches all dependencies that were versioned with party to be instead included as submodules. The respective projects are checked out to the same commit at which they were initially vendored with party, so this should have no functional change. --- .gitmodules | 27 + .../p/go-charset/charset/big5.go | 88 - .../p/go-charset/charset/charset.go | 301 - .../p/go-charset/charset/charset_test.go | 279 - .../p/go-charset/charset/codepage.go | 133 - .../p/go-charset/charset/cp932.go | 195 - .../p/go-charset/charset/example_test.go | 36 - .../p/go-charset/charset/file.go | 40 - .../p/go-charset/charset/local.go | 162 - .../p/go-charset/charset/utf16.go | 110 - .../p/go-charset/charset/utf8.go | 51 - .../p/go-charset/data/data_big5.dat.go | 18 - .../p/go-charset/data/data_charsets.json.go | 18 - .../p/go-charset/data/data_cp932.dat.go | 18 - .../p/go-charset/data/data_ibm437.cp.go | 18 - .../p/go-charset/data/data_ibm850.cp.go | 18 - .../p/go-charset/data/data_ibm866.cp.go | 18 - .../p/go-charset/data/data_iso-8859-1.cp.go | 18 - .../p/go-charset/data/data_iso-8859-10.cp.go | 18 - .../p/go-charset/data/data_iso-8859-15.cp.go | 18 - .../p/go-charset/data/data_iso-8859-2.cp.go | 18 - .../p/go-charset/data/data_iso-8859-3.cp.go | 18 - .../p/go-charset/data/data_iso-8859-4.cp.go | 18 - .../p/go-charset/data/data_iso-8859-5.cp.go | 18 - .../p/go-charset/data/data_iso-8859-6.cp.go | 18 - .../p/go-charset/data/data_iso-8859-7.cp.go | 18 - .../p/go-charset/data/data_iso-8859-8.cp.go | 18 - .../p/go-charset/data/data_iso-8859-9.cp.go | 18 - .../go-charset/data/data_jisx0201kana.dat.go | 18 - .../p/go-charset/data/data_koi8-r.cp.go | 18 - .../p/go-charset/data/data_windows-1250.cp.go | 18 - .../p/go-charset/data/data_windows-1251.cp.go | 18 - .../p/go-charset/data/data_windows-1252.cp.go | 18 - .../code.google.com/p/go-charset/data/doc.go | 6 - .../p/go-charset/data/generate.go | 97 - .../MiniProfiler/go/miniprofiler/doc.go | 123 - .../go/miniprofiler/miniprofiler.go | 348 - .../MiniProfiler/go/miniprofiler/static.go | 748 - .../MiniProfiler/go/miniprofiler/templates.go | 26 - .../MiniProfiler/go/miniprofiler/types.go | 302 - .../MiniProfiler/go/miniprofiler_gae/doc.go | 47 - .../go/miniprofiler_gae/miniprofiler_gae.go | 129 - .../github.com/golang/protobuf/proto/Makefile | 43 - .../golang/protobuf/proto/all_test.go | 2083 - .../github.com/golang/protobuf/proto/clone.go | 212 - .../golang/protobuf/proto/clone_test.go | 245 - .../golang/protobuf/proto/decode.go | 827 - .../golang/protobuf/proto/encode.go | 1293 - .../github.com/golang/protobuf/proto/equal.go | 256 - .../golang/protobuf/proto/equal_test.go | 191 - .../golang/protobuf/proto/extensions.go | 400 - .../golang/protobuf/proto/extensions_test.go | 292 - .../github.com/golang/protobuf/proto/lib.go | 813 - .../golang/protobuf/proto/message_set.go | 287 - .../golang/protobuf/proto/message_set_test.go | 66 - .../golang/protobuf/proto/pointer_reflect.go | 479 - .../golang/protobuf/proto/pointer_unsafe.go | 266 - .../golang/protobuf/proto/properties.go | 742 - .../golang/protobuf/proto/proto3_test.go | 125 - .../golang/protobuf/proto/size2_test.go | 63 - .../golang/protobuf/proto/size_test.go | 142 - .../github.com/golang/protobuf/proto/text.go | 769 - .../golang/protobuf/proto/text_parser.go | 772 - .../golang/protobuf/proto/text_parser_test.go | 511 - .../golang/protobuf/proto/text_test.go | 441 - .../github.com/gorilla/context/LICENSE | 27 - .../github.com/gorilla/context/README.md | 7 - .../github.com/gorilla/context/context.go | 143 - .../gorilla/context/context_test.go | 161 - .../github.com/gorilla/context/doc.go | 82 - _third_party/github.com/gorilla/mux/LICENSE | 27 - _third_party/github.com/gorilla/mux/README.md | 7 - .../github.com/gorilla/mux/bench_test.go | 21 - _third_party/github.com/gorilla/mux/doc.go | 199 - _third_party/github.com/gorilla/mux/mux.go | 366 - .../github.com/gorilla/mux/mux_test.go | 1048 - .../github.com/gorilla/mux/old_test.go | 714 - _third_party/github.com/gorilla/mux/regexp.go | 285 - _third_party/github.com/gorilla/mux/route.go | 571 - .../github.com/mjibson/appstats/README.md | 5 - .../github.com/mjibson/appstats/appstats.go | 292 - .../github.com/mjibson/appstats/bytesize.go | 45 - .../github.com/mjibson/appstats/cost.go | 60 - .../github.com/mjibson/appstats/doc.go | 75 - .../github.com/mjibson/appstats/funcs.go | 69 - .../github.com/mjibson/appstats/handler.go | 356 - .../github.com/mjibson/appstats/html.go | 504 - .../github.com/mjibson/appstats/static.go | 15 - .../github.com/mjibson/appstats/types.go | 169 - .../github.com/mjibson/goon/README.md | 5 - _third_party/github.com/mjibson/goon/doc.go | 138 - .../github.com/mjibson/goon/entity.go | 850 - _third_party/github.com/mjibson/goon/goon.go | 661 - .../github.com/mjibson/goon/goon_test.go | 2090 - _third_party/github.com/mjibson/goon/query.go | 170 - .../golang.org/x/net/html/atom/atom.go | 78 - .../golang.org/x/net/html/atom/atom_test.go | 109 - .../golang.org/x/net/html/atom/gen.go | 648 - .../golang.org/x/net/html/atom/table.go | 713 - .../golang.org/x/net/html/atom/table_test.go | 351 - .../golang.org/x/net/html/charset/charset.go | 244 - .../x/net/html/charset/charset_test.go | 236 - .../golang.org/x/net/html/charset/gen.go | 111 - .../golang.org/x/net/html/charset/table.go | 235 - _third_party/golang.org/x/net/html/const.go | 102 - _third_party/golang.org/x/net/html/doc.go | 106 - _third_party/golang.org/x/net/html/doctype.go | 156 - _third_party/golang.org/x/net/html/entity.go | 2253 - .../golang.org/x/net/html/entity_test.go | 29 - _third_party/golang.org/x/net/html/escape.go | 258 - .../golang.org/x/net/html/escape_test.go | 97 - .../golang.org/x/net/html/example_test.go | 40 - _third_party/golang.org/x/net/html/foreign.go | 226 - _third_party/golang.org/x/net/html/node.go | 193 - .../golang.org/x/net/html/node_test.go | 146 - _third_party/golang.org/x/net/html/parse.go | 2094 - .../golang.org/x/net/html/parse_test.go | 388 - _third_party/golang.org/x/net/html/render.go | 271 - .../golang.org/x/net/html/render_test.go | 156 - _third_party/golang.org/x/net/html/token.go | 1219 - .../golang.org/x/net/html/token_test.go | 748 - _third_party/golang.org/x/text/cldr/base.go | 110 - _third_party/golang.org/x/text/cldr/cldr.go | 121 - .../golang.org/x/text/cldr/cldr_test.go | 27 - .../golang.org/x/text/cldr/collate.go | 359 - .../golang.org/x/text/cldr/collate_test.go | 275 - .../golang.org/x/text/cldr/data_test.go | 186 - _third_party/golang.org/x/text/cldr/decode.go | 169 - .../golang.org/x/text/cldr/examples_test.go | 20 - .../golang.org/x/text/cldr/makexml.go | 400 - .../golang.org/x/text/cldr/resolve.go | 602 - .../golang.org/x/text/cldr/resolve_test.go | 368 - _third_party/golang.org/x/text/cldr/slice.go | 144 - .../golang.org/x/text/cldr/slice_test.go | 175 - _third_party/golang.org/x/text/cldr/xml.go | 1386 - .../x/text/encoding/charmap/charmap.go | 209 - .../x/text/encoding/charmap/maketables.go | 415 - .../x/text/encoding/charmap/tables.go | 5116 -- .../golang.org/x/text/encoding/encoding.go | 179 - .../x/text/encoding/encoding_test.go | 1036 - .../x/text/encoding/example_test.go | 40 - .../text/encoding/internal/identifier/gen.go | 137 - .../internal/identifier/identifier.go | 80 - .../text/encoding/internal/identifier/mib.go | 1621 - .../x/text/encoding/internal/internal.go | 60 - .../x/text/encoding/japanese/all.go | 12 - .../x/text/encoding/japanese/eucjp.go | 210 - .../x/text/encoding/japanese/iso2022jp.go | 284 - .../x/text/encoding/japanese/maketables.go | 161 - .../x/text/encoding/japanese/shiftjis.go | 188 - .../x/text/encoding/japanese/tables.go | 26971 ---------- .../x/text/encoding/korean/euckr.go | 177 - .../x/text/encoding/korean/maketables.go | 143 - .../x/text/encoding/korean/tables.go | 34152 ------------ .../x/text/encoding/simplifiedchinese/all.go | 12 - .../x/text/encoding/simplifiedchinese/gbk.go | 280 - .../encoding/simplifiedchinese/hzgb2312.go | 228 - .../encoding/simplifiedchinese/maketables.go | 161 - .../text/encoding/simplifiedchinese/tables.go | 43999 ---------------- .../text/encoding/traditionalchinese/big5.go | 198 - .../encoding/traditionalchinese/maketables.go | 140 - .../encoding/traditionalchinese/tables.go | 37142 ------------- .../x/text/encoding/unicode/override.go | 82 - .../x/text/encoding/unicode/unicode.go | 333 - .../golang.org/x/text/internal/gen/gen.go | 199 - .../x/text/transform/examples_test.go | 37 - .../golang.org/x/text/transform/transform.go | 616 - .../x/text/transform/transform_test.go | 1082 - admin.go | 4 +- app/app.go | 2 +- autodiscover.go | 4 +- charge.go | 4 +- dev.go | 4 +- main.go | 8 +- rss/rss_test.go | 2 +- sanitizer/sanitize.go | 2 +- sanitizer/snip.go | 2 +- tasks.go | 6 +- types.go | 2 +- user.go | 8 +- utils.go | 12 +- vendor/code.google.com/p/go-charset | 1 + vendor/github.com/MiniProfiler/go | 1 + vendor/github.com/golang/protobuf | 1 + vendor/github.com/gorilla/context | 1 + vendor/github.com/gorilla/mux | 1 + vendor/github.com/mjibson/appstats | 1 + vendor/github.com/mjibson/goon | 1 + vendor/golang.org/x/net | 1 + vendor/golang.org/x/text | 1 + 190 files changed, 66 insertions(+), 195376 deletions(-) create mode 100644 .gitmodules delete mode 100644 _third_party/code.google.com/p/go-charset/charset/big5.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/charset.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/charset_test.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/codepage.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/cp932.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/example_test.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/file.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/local.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/utf16.go delete mode 100644 _third_party/code.google.com/p/go-charset/charset/utf8.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_big5.dat.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_charsets.json.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_cp932.dat.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_ibm437.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_ibm850.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_ibm866.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-1.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-10.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-15.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-2.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-3.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-4.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-5.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-6.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-7.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-8.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_iso-8859-9.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_jisx0201kana.dat.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_koi8-r.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_windows-1250.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_windows-1251.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/data_windows-1252.cp.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/doc.go delete mode 100644 _third_party/code.google.com/p/go-charset/data/generate.go delete mode 100644 _third_party/github.com/MiniProfiler/go/miniprofiler/doc.go delete mode 100644 _third_party/github.com/MiniProfiler/go/miniprofiler/miniprofiler.go delete mode 100644 _third_party/github.com/MiniProfiler/go/miniprofiler/static.go delete mode 100644 _third_party/github.com/MiniProfiler/go/miniprofiler/templates.go delete mode 100644 _third_party/github.com/MiniProfiler/go/miniprofiler/types.go delete mode 100644 _third_party/github.com/MiniProfiler/go/miniprofiler_gae/doc.go delete mode 100644 _third_party/github.com/MiniProfiler/go/miniprofiler_gae/miniprofiler_gae.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/Makefile delete mode 100644 _third_party/github.com/golang/protobuf/proto/all_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/clone.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/clone_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/decode.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/encode.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/equal.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/equal_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/extensions.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/extensions_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/lib.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/message_set.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/message_set_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/pointer_reflect.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/pointer_unsafe.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/properties.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/proto3_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/size2_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/size_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/text.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/text_parser.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/text_parser_test.go delete mode 100644 _third_party/github.com/golang/protobuf/proto/text_test.go delete mode 100644 _third_party/github.com/gorilla/context/LICENSE delete mode 100644 _third_party/github.com/gorilla/context/README.md delete mode 100644 _third_party/github.com/gorilla/context/context.go delete mode 100644 _third_party/github.com/gorilla/context/context_test.go delete mode 100644 _third_party/github.com/gorilla/context/doc.go delete mode 100644 _third_party/github.com/gorilla/mux/LICENSE delete mode 100644 _third_party/github.com/gorilla/mux/README.md delete mode 100644 _third_party/github.com/gorilla/mux/bench_test.go delete mode 100644 _third_party/github.com/gorilla/mux/doc.go delete mode 100644 _third_party/github.com/gorilla/mux/mux.go delete mode 100644 _third_party/github.com/gorilla/mux/mux_test.go delete mode 100644 _third_party/github.com/gorilla/mux/old_test.go delete mode 100644 _third_party/github.com/gorilla/mux/regexp.go delete mode 100644 _third_party/github.com/gorilla/mux/route.go delete mode 100644 _third_party/github.com/mjibson/appstats/README.md delete mode 100644 _third_party/github.com/mjibson/appstats/appstats.go delete mode 100644 _third_party/github.com/mjibson/appstats/bytesize.go delete mode 100644 _third_party/github.com/mjibson/appstats/cost.go delete mode 100644 _third_party/github.com/mjibson/appstats/doc.go delete mode 100644 _third_party/github.com/mjibson/appstats/funcs.go delete mode 100644 _third_party/github.com/mjibson/appstats/handler.go delete mode 100644 _third_party/github.com/mjibson/appstats/html.go delete mode 100644 _third_party/github.com/mjibson/appstats/static.go delete mode 100644 _third_party/github.com/mjibson/appstats/types.go delete mode 100644 _third_party/github.com/mjibson/goon/README.md delete mode 100644 _third_party/github.com/mjibson/goon/doc.go delete mode 100644 _third_party/github.com/mjibson/goon/entity.go delete mode 100644 _third_party/github.com/mjibson/goon/goon.go delete mode 100644 _third_party/github.com/mjibson/goon/goon_test.go delete mode 100644 _third_party/github.com/mjibson/goon/query.go delete mode 100644 _third_party/golang.org/x/net/html/atom/atom.go delete mode 100644 _third_party/golang.org/x/net/html/atom/atom_test.go delete mode 100644 _third_party/golang.org/x/net/html/atom/gen.go delete mode 100644 _third_party/golang.org/x/net/html/atom/table.go delete mode 100644 _third_party/golang.org/x/net/html/atom/table_test.go delete mode 100644 _third_party/golang.org/x/net/html/charset/charset.go delete mode 100644 _third_party/golang.org/x/net/html/charset/charset_test.go delete mode 100644 _third_party/golang.org/x/net/html/charset/gen.go delete mode 100644 _third_party/golang.org/x/net/html/charset/table.go delete mode 100644 _third_party/golang.org/x/net/html/const.go delete mode 100644 _third_party/golang.org/x/net/html/doc.go delete mode 100644 _third_party/golang.org/x/net/html/doctype.go delete mode 100644 _third_party/golang.org/x/net/html/entity.go delete mode 100644 _third_party/golang.org/x/net/html/entity_test.go delete mode 100644 _third_party/golang.org/x/net/html/escape.go delete mode 100644 _third_party/golang.org/x/net/html/escape_test.go delete mode 100644 _third_party/golang.org/x/net/html/example_test.go delete mode 100644 _third_party/golang.org/x/net/html/foreign.go delete mode 100644 _third_party/golang.org/x/net/html/node.go delete mode 100644 _third_party/golang.org/x/net/html/node_test.go delete mode 100644 _third_party/golang.org/x/net/html/parse.go delete mode 100644 _third_party/golang.org/x/net/html/parse_test.go delete mode 100644 _third_party/golang.org/x/net/html/render.go delete mode 100644 _third_party/golang.org/x/net/html/render_test.go delete mode 100644 _third_party/golang.org/x/net/html/token.go delete mode 100644 _third_party/golang.org/x/net/html/token_test.go delete mode 100644 _third_party/golang.org/x/text/cldr/base.go delete mode 100644 _third_party/golang.org/x/text/cldr/cldr.go delete mode 100644 _third_party/golang.org/x/text/cldr/cldr_test.go delete mode 100644 _third_party/golang.org/x/text/cldr/collate.go delete mode 100644 _third_party/golang.org/x/text/cldr/collate_test.go delete mode 100644 _third_party/golang.org/x/text/cldr/data_test.go delete mode 100644 _third_party/golang.org/x/text/cldr/decode.go delete mode 100644 _third_party/golang.org/x/text/cldr/examples_test.go delete mode 100644 _third_party/golang.org/x/text/cldr/makexml.go delete mode 100644 _third_party/golang.org/x/text/cldr/resolve.go delete mode 100644 _third_party/golang.org/x/text/cldr/resolve_test.go delete mode 100644 _third_party/golang.org/x/text/cldr/slice.go delete mode 100644 _third_party/golang.org/x/text/cldr/slice_test.go delete mode 100644 _third_party/golang.org/x/text/cldr/xml.go delete mode 100644 _third_party/golang.org/x/text/encoding/charmap/charmap.go delete mode 100644 _third_party/golang.org/x/text/encoding/charmap/maketables.go delete mode 100644 _third_party/golang.org/x/text/encoding/charmap/tables.go delete mode 100644 _third_party/golang.org/x/text/encoding/encoding.go delete mode 100644 _third_party/golang.org/x/text/encoding/encoding_test.go delete mode 100644 _third_party/golang.org/x/text/encoding/example_test.go delete mode 100644 _third_party/golang.org/x/text/encoding/internal/identifier/gen.go delete mode 100644 _third_party/golang.org/x/text/encoding/internal/identifier/identifier.go delete mode 100644 _third_party/golang.org/x/text/encoding/internal/identifier/mib.go delete mode 100644 _third_party/golang.org/x/text/encoding/internal/internal.go delete mode 100644 _third_party/golang.org/x/text/encoding/japanese/all.go delete mode 100644 _third_party/golang.org/x/text/encoding/japanese/eucjp.go delete mode 100644 _third_party/golang.org/x/text/encoding/japanese/iso2022jp.go delete mode 100644 _third_party/golang.org/x/text/encoding/japanese/maketables.go delete mode 100644 _third_party/golang.org/x/text/encoding/japanese/shiftjis.go delete mode 100644 _third_party/golang.org/x/text/encoding/japanese/tables.go delete mode 100644 _third_party/golang.org/x/text/encoding/korean/euckr.go delete mode 100644 _third_party/golang.org/x/text/encoding/korean/maketables.go delete mode 100644 _third_party/golang.org/x/text/encoding/korean/tables.go delete mode 100644 _third_party/golang.org/x/text/encoding/simplifiedchinese/all.go delete mode 100644 _third_party/golang.org/x/text/encoding/simplifiedchinese/gbk.go delete mode 100644 _third_party/golang.org/x/text/encoding/simplifiedchinese/hzgb2312.go delete mode 100644 _third_party/golang.org/x/text/encoding/simplifiedchinese/maketables.go delete mode 100644 _third_party/golang.org/x/text/encoding/simplifiedchinese/tables.go delete mode 100644 _third_party/golang.org/x/text/encoding/traditionalchinese/big5.go delete mode 100644 _third_party/golang.org/x/text/encoding/traditionalchinese/maketables.go delete mode 100644 _third_party/golang.org/x/text/encoding/traditionalchinese/tables.go delete mode 100644 _third_party/golang.org/x/text/encoding/unicode/override.go delete mode 100644 _third_party/golang.org/x/text/encoding/unicode/unicode.go delete mode 100644 _third_party/golang.org/x/text/internal/gen/gen.go delete mode 100644 _third_party/golang.org/x/text/transform/examples_test.go delete mode 100644 _third_party/golang.org/x/text/transform/transform.go delete mode 100644 _third_party/golang.org/x/text/transform/transform_test.go create mode 160000 vendor/code.google.com/p/go-charset create mode 160000 vendor/github.com/MiniProfiler/go create mode 160000 vendor/github.com/golang/protobuf create mode 160000 vendor/github.com/gorilla/context create mode 160000 vendor/github.com/gorilla/mux create mode 160000 vendor/github.com/mjibson/appstats create mode 160000 vendor/github.com/mjibson/goon create mode 160000 vendor/golang.org/x/net create mode 160000 vendor/golang.org/x/text diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..b9f6d219 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,27 @@ +[submodule "vendor/golang.org/x/text"] + path = vendor/golang.org/x/text + url = https://go.googlesource.com/text +[submodule "vendor/code.google.com/p/go-charset"] + path = vendor/code.google.com/p/go-charset + url = https://github.com/rogpeppe/go-charset +[submodule "vendor/github.com/golang/protobuf"] + path = vendor/github.com/golang/protobuf + url = https://github.com/golang/protobuf +[submodule "vendor/golang.org/x/net"] + path = vendor/golang.org/x/net + url = https://go.googlesource.com/net +[submodule "vendor/github.com/gorilla/context"] + path = vendor/github.com/gorilla/context + url = https://github.com/gorilla/context +[submodule "vendor/github.com/gorilla/mux"] + path = vendor/github.com/gorilla/mux + url = https://github.com/gorilla/mux +[submodule "vendor/github.com/MiniProfiler/go"] + path = vendor/github.com/MiniProfiler/go + url = https://github.com/MiniProfiler/go +[submodule "vendor/github.com/mjibson/goon"] + path = vendor/github.com/mjibson/goon + url = https://github.com/mjibson/goon +[submodule "vendor/github.com/mjibson/appstats"] + path = vendor/github.com/mjibson/appstats + url = https://github.com/mjibson/appstats diff --git a/_third_party/code.google.com/p/go-charset/charset/big5.go b/_third_party/code.google.com/p/go-charset/charset/big5.go deleted file mode 100644 index e01fa1af..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/big5.go +++ /dev/null @@ -1,88 +0,0 @@ -package charset - -import ( - "fmt" - "unicode/utf8" -) - -func init() { - registerClass("big5", fromBig5, nil) -} - -// Big5 consists of 89 fonts of 157 chars each -const ( - big5Max = 13973 - big5Font = 157 - big5Data = "big5.dat" -) - -type translateFromBig5 struct { - font int - scratch []byte - big5map []rune -} - -func (p *translateFromBig5) Translate(data []byte, eof bool) (int, []byte, error) { - p.scratch = p.scratch[:0] - n := 0 - for len(data) > 0 { - c := int(data[0]) - data = data[1:] - n++ - if p.font == -1 { - // idle state - if c >= 0xa1 { - p.font = c - continue - } - if c == 26 { - c = '\n' - } - continue - } - f := p.font - p.font = -1 - r := utf8.RuneError - switch { - case c >= 64 && c <= 126: - c -= 64 - case c >= 161 && c <= 254: - c = c - 161 + 63 - default: - // bad big5 char - f = 255 - } - if f <= 254 { - f -= 161 - ix := f*big5Font + c - if ix < len(p.big5map) { - r = p.big5map[ix] - } - if r == -1 { - r = utf8.RuneError - } - } - p.scratch = appendRune(p.scratch, r) - } - return n, p.scratch, nil -} - -type big5Key bool - -func fromBig5(arg string) (Translator, error) { - big5map, err := cache(big5Key(false), func() (interface{}, error) { - data, err := readFile(big5Data) - if err != nil { - return nil, fmt.Errorf("charset: cannot open big5 data file: %v", err) - } - big5map := []rune(string(data)) - if len(big5map) != big5Max { - return nil, fmt.Errorf("charset: corrupt big5 data") - } - return big5map, nil - }) - if err != nil { - return nil, err - } - return &translateFromBig5{big5map: big5map.([]rune), font: -1}, nil -} diff --git a/_third_party/code.google.com/p/go-charset/charset/charset.go b/_third_party/code.google.com/p/go-charset/charset/charset.go deleted file mode 100644 index a7af30ee..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/charset.go +++ /dev/null @@ -1,301 +0,0 @@ -// The charset package implements translation between character sets. -// It uses Unicode as the intermediate representation. -// Because it can be large, the character set data is separated -// from the charset package. It can be embedded in the Go -// executable by importing the data package: -// -// import _ "code.google.com/p/go-charset/data" -// -// It can also made available in a data directory (by settting CharsetDir). -package charset - -import ( - "io" - "strings" - "unicode/utf8" -) - -// Charset holds information about a given character set. -type Charset struct { - Name string // Canonical name of character set. - Aliases []string // Known aliases. - Desc string // Description. - NoFrom bool // Not possible to translate from this charset. - NoTo bool // Not possible to translate to this charset. -} - -// Translator represents a character set converter. -// The Translate method translates the given data, -// and returns the number of bytes of data consumed, -// a slice containing the converted data (which may be -// overwritten on the next call to Translate), and any -// conversion error. If eof is true, the data represents -// the final bytes of the input. -type Translator interface { - Translate(data []byte, eof bool) (n int, cdata []byte, err error) -} - -// A Factory can be used to make character set translators. -type Factory interface { - // TranslatorFrom creates a translator that will translate from the named character - // set to UTF-8. - TranslatorFrom(name string) (Translator, error) // Create a Translator from this character set to. - - // TranslatorTo creates a translator that will translate from UTF-8 to the named character set. - TranslatorTo(name string) (Translator, error) // Create a Translator To this character set. - - // Names returns all the character set names accessibile through the factory. - Names() []string - - // Info returns information on the named character set. It returns nil if the - // factory doesn't recognise the given name. - Info(name string) *Charset -} - -var factories = []Factory{localFactory{}} - -// Register registers a new Factory which will be consulted when NewReader -// or NewWriter needs a character set translator for a given name. -func Register(factory Factory) { - factories = append(factories, factory) -} - -// NewReader returns a new Reader that translates from the named -// character set to UTF-8 as it reads r. -func NewReader(charset string, r io.Reader) (io.Reader, error) { - tr, err := TranslatorFrom(charset) - if err != nil { - return nil, err - } - return NewTranslatingReader(r, tr), nil -} - -// NewWriter returns a new WriteCloser writing to w. It converts writes -// of UTF-8 text into writes on w of text in the named character set. -// The Close is necessary to flush any remaining partially translated -// characters to the output. -func NewWriter(charset string, w io.Writer) (io.WriteCloser, error) { - tr, err := TranslatorTo(charset) - if err != nil { - return nil, err - } - return NewTranslatingWriter(w, tr), nil -} - -// Info returns information about a character set, or nil -// if the character set is not found. -func Info(name string) *Charset { - for _, f := range factories { - if info := f.Info(name); info != nil { - return info - } - } - return nil -} - -// Names returns the canonical names of all supported character sets, in alphabetical order. -func Names() []string { - // TODO eliminate duplicates - var names []string - for _, f := range factories { - names = append(names, f.Names()...) - } - return names -} - -// TranslatorFrom returns a translator that will translate from -// the named character set to UTF-8. -func TranslatorFrom(charset string) (Translator, error) { - var err error - var tr Translator - for _, f := range factories { - tr, err = f.TranslatorFrom(charset) - if err == nil { - break - } - } - if tr == nil { - return nil, err - } - return tr, nil -} - -// TranslatorTo returns a translator that will translate from UTF-8 -// to the named character set. -func TranslatorTo(charset string) (Translator, error) { - var err error - var tr Translator - for _, f := range factories { - tr, err = f.TranslatorTo(charset) - if err == nil { - break - } - } - if tr == nil { - return nil, err - } - return tr, nil -} - -func normalizedChar(c rune) rune { - switch { - case c >= 'A' && c <= 'Z': - c = c - 'A' + 'a' - case c == '_': - c = '-' - } - return c -} - -// NormalisedName returns s with all Roman capitals -// mapped to lower case, and '_' mapped to '-' -func NormalizedName(s string) string { - return strings.Map(normalizedChar, s) -} - -type translatingWriter struct { - w io.Writer - tr Translator - buf []byte // unconsumed data from writer. -} - -// NewTranslatingWriter returns a new WriteCloser writing to w. -// It passes the written bytes through the given Translator. -func NewTranslatingWriter(w io.Writer, tr Translator) io.WriteCloser { - return &translatingWriter{w: w, tr: tr} -} - -func (w *translatingWriter) Write(data []byte) (rn int, rerr error) { - wdata := data - if len(w.buf) > 0 { - w.buf = append(w.buf, data...) - wdata = w.buf - } - n, cdata, err := w.tr.Translate(wdata, false) - if err != nil { - // TODO - } - if n > 0 { - _, err = w.w.Write(cdata) - if err != nil { - return 0, err - } - } - w.buf = w.buf[:0] - if n < len(wdata) { - w.buf = append(w.buf, wdata[n:]...) - } - return len(data), nil -} - -func (p *translatingWriter) Close() error { - for { - n, data, err := p.tr.Translate(p.buf, true) - p.buf = p.buf[n:] - if err != nil { - // TODO - } - // If the Translator produces no data - // at EOF, then assume that it never will. - if len(data) == 0 { - break - } - n, err = p.w.Write(data) - if err != nil { - return err - } - if n < len(data) { - return io.ErrShortWrite - } - if len(p.buf) == 0 { - break - } - } - return nil -} - -type translatingReader struct { - r io.Reader - tr Translator - cdata []byte // unconsumed data from converter. - rdata []byte // unconverted data from reader. - err error // final error from reader. -} - -// NewTranslatingReader returns a new Reader that -// translates data using the given Translator as it reads r. -func NewTranslatingReader(r io.Reader, tr Translator) io.Reader { - return &translatingReader{r: r, tr: tr} -} - -func (r *translatingReader) Read(buf []byte) (int, error) { - for { - if len(r.cdata) > 0 { - n := copy(buf, r.cdata) - r.cdata = r.cdata[n:] - return n, nil - } - if r.err == nil { - r.rdata = ensureCap(r.rdata, len(r.rdata)+len(buf)) - n, err := r.r.Read(r.rdata[len(r.rdata):cap(r.rdata)]) - // Guard against non-compliant Readers. - if n == 0 && err == nil { - err = io.EOF - } - r.rdata = r.rdata[0 : len(r.rdata)+n] - r.err = err - } else if len(r.rdata) == 0 { - break - } - nc, cdata, cvterr := r.tr.Translate(r.rdata, r.err != nil) - if cvterr != nil { - // TODO - } - r.cdata = cdata - - // Ensure that we consume all bytes at eof - // if the converter refuses them. - if nc == 0 && r.err != nil { - nc = len(r.rdata) - } - - // Copy unconsumed data to the start of the rdata buffer. - r.rdata = r.rdata[0:copy(r.rdata, r.rdata[nc:])] - } - return 0, r.err -} - -// ensureCap returns s with a capacity of at least n bytes. -// If cap(s) < n, then it returns a new copy of s with the -// required capacity. -func ensureCap(s []byte, n int) []byte { - if n <= cap(s) { - return s - } - // logic adapted from appendslice1 in runtime - m := cap(s) - if m == 0 { - m = n - } else { - for { - if m < 1024 { - m += m - } else { - m += m / 4 - } - if m >= n { - break - } - } - } - t := make([]byte, len(s), m) - copy(t, s) - return t -} - -func appendRune(buf []byte, r rune) []byte { - n := len(buf) - buf = ensureCap(buf, n+utf8.UTFMax) - nu := utf8.EncodeRune(buf[n:n+utf8.UTFMax], r) - return buf[0 : n+nu] -} diff --git a/_third_party/code.google.com/p/go-charset/charset/charset_test.go b/_third_party/code.google.com/p/go-charset/charset/charset_test.go deleted file mode 100644 index 908601b0..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/charset_test.go +++ /dev/null @@ -1,279 +0,0 @@ -package charset_test - -import ( - "bytes" - "fmt" - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - _ "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/data" - "io" - "strings" - "testing" - "testing/iotest" - "unicode/utf8" -) - -type translateTest struct { - canRoundTrip bool - charset string - in string - out string -} - -// TODO test codepage behaviour at char boundary. - -var tests = []translateTest{ - {true, "iso-8859-15", "\xa41 is cheap", "€1 is cheap"}, - {true, "ms-kanji", "\x82\xb1\x82\xea\x82\xcd\x8a\xbf\x8e\x9a\x82\xc5\x82\xb7\x81B", "これは漢字です。"}, - {true, "utf-16le", "S0\x8c0o0\"oW[g0Y0\x020", "これは漢字です。"}, - {true, "utf-16be", "0S0\x8c0oo\"[W0g0Y0\x02", "これは漢字です。"}, - {true, "utf-8", "♔", "♔"}, - {false, "utf-8", "a♔é\x80", "a♔é" + string(utf8.RuneError)}, - {true, "sjis", "", ""}, - {true, "latin1", "\xa35 for Pepp\xe9", "£5 for Peppé"}, -} - -func TestCharsets(t *testing.T) { - for i, test := range tests { - t.Logf("test %d", i) - test.run(t) - } -} - -func translate(tr charset.Translator, in string) (string, error) { - var buf bytes.Buffer - r := charset.NewTranslatingReader(strings.NewReader(in), tr) - _, err := io.Copy(&buf, r) - if err != nil { - return "", err - } - return string(buf.Bytes()), nil -} - -func (test translateTest) run(t *testing.T) { - cs := charset.Info(test.charset) - if cs == nil { - t.Fatalf("no info found for %q", test.charset) - } - fromtr, err := charset.TranslatorFrom(test.charset) - if err != nil { - t.Fatalf("error making translator from %q: %v", test.charset, err) - } - out, err := translate(fromtr, test.in) - if err != nil { - t.Fatalf("error translating from %q: %v", test.charset, err) - } - if out != test.out { - t.Fatalf("error translating from %q: expected %x got %x", test.charset, test.out, out) - } - - if cs.NoTo || !test.canRoundTrip { - return - } - - totr, err := charset.TranslatorTo(test.charset) - if err != nil { - t.Fatalf("error making translator to %q: %v", test.charset, err) - } - in, err := translate(totr, out) - if err != nil { - t.Fatalf("error translating to %q: %v", test.charset, err) - } - if in != test.in { - t.Fatalf("%q round trip conversion failed; expected %x got %x", test.charset, test.in, in) - } -} - -// TODO test big5 - -var testReaders = []func(io.Reader) io.Reader{ - func(r io.Reader) io.Reader { return r }, - iotest.OneByteReader, - iotest.HalfReader, - iotest.DataErrReader, -} - -var testWriters = []func(io.Writer) io.Writer{ - func(w io.Writer) io.Writer { return w }, - OneByteWriter, -} - -var testTranslators = []func() charset.Translator{ - func() charset.Translator { return new(holdingTranslator) }, - func() charset.Translator { return new(shortTranslator) }, -} - -var codepageCharsets = []string{"latin1"} - -func TestCodepages(t *testing.T) { - for _, name := range codepageCharsets { - for _, inr := range testReaders { - for _, outr := range testReaders { - testCodepage(t, name, inr, outr) - } - } - } -} - -func testCodepage(t *testing.T, name string, inReader, outReader func(io.Reader) io.Reader) { - data := make([]byte, 256) - for i := range data { - data[i] = byte(i) - } - inr := inReader(bytes.NewBuffer(data)) - r, err := charset.NewReader(name, inr) - if err != nil { - t.Fatalf("cannot make reader for charset %q: %v", name, err) - } - outr := outReader(r) - r = outr - - var outbuf bytes.Buffer - w, err := charset.NewWriter(name, &outbuf) - if err != nil { - t.Fatalf("cannot make writer for charset %q: %v", name, err) - } - _, err = io.Copy(w, r) - if err != nil { - t.Fatalf("copy failed: %v", err) - } - err = w.Close() - if err != nil { - t.Fatalf("close failed: %v", err) - } - if len(outbuf.Bytes()) != len(data) { - t.Fatalf("short result of roundtrip, charset %q, readers %T, %T; expected 256, got %d", name, inr, outr, len(outbuf.Bytes())) - } - for i, x := range outbuf.Bytes() { - if data[i] != x { - t.Fatalf("charset %q, round trip expected %d, got %d", name, i, data[i]) - } - } -} - -func TestTranslatingReader(t *testing.T) { - for _, tr := range testTranslators { - for _, inr := range testReaders { - for _, outr := range testReaders { - testTranslatingReader(t, tr(), inr, outr) - } - } - } -} - -func testTranslatingReader(t *testing.T, tr charset.Translator, inReader, outReader func(io.Reader) io.Reader) { - data := make([]byte, 128) - for i := range data { - data[i] = byte(i) - } - inr := inReader(bytes.NewBuffer(data)) - r := charset.NewTranslatingReader(inr, tr) - outr := outReader(r) - r = outr - - var outbuf bytes.Buffer - _, err := io.Copy(&outbuf, r) - if err != nil { - t.Fatalf("translator %T, readers %T, %T, copy failed: %v", tr, inr, outr, err) - } - err = checkTranslation(data, outbuf.Bytes()) - if err != nil { - t.Fatalf("translator %T, readers %T, %T, %v\n", err) - } -} - -func TestTranslatingWriter(t *testing.T) { - for _, tr := range testTranslators { - for _, w := range testWriters { - testTranslatingWriter(t, tr(), w) - } - } -} - -func testTranslatingWriter(t *testing.T, tr charset.Translator, writer func(io.Writer) io.Writer) { - var outbuf bytes.Buffer - trw := charset.NewTranslatingWriter(&outbuf, tr) - w := writer(trw) - - data := make([]byte, 128) - for i := range data { - data[i] = byte(i) - } - n, err := w.Write(data) - if err != nil { - t.Fatalf("translator %T, writer %T, write error: %v", tr, w, err) - } - if n != len(data) { - t.Fatalf("translator %T, writer %T, short write; expected %d got %d", tr, w, len(data), n) - } - trw.Close() - err = checkTranslation(data, outbuf.Bytes()) - if err != nil { - t.Fatalf("translator %T, writer %T, %v", tr, w, err) - } -} - -func xlate(x byte) byte { - return x + 128 -} - -func checkTranslation(in, out []byte) error { - if len(in) != len(out) { - return fmt.Errorf("wrong byte count; expected %d got %d", len(in), len(out)) - } - for i, x := range out { - if in[i]+128 != x { - return fmt.Errorf("bad translation at %d; expected %d, got %d", i, in[i]+128, x) - } - } - return nil -} - -// holdingTranslator holds its input until the end. -type holdingTranslator struct { - scratch []byte -} - -func (t *holdingTranslator) Translate(buf []byte, eof bool) (int, []byte, error) { - t.scratch = append(t.scratch, buf...) - if !eof { - return len(buf), nil, nil - } - for i, x := range t.scratch { - t.scratch[i] = xlate(x) - } - return len(buf), t.scratch, nil -} - -// shortTranslator translates only one byte at a time, even at eof. -type shortTranslator [1]byte - -func (t *shortTranslator) Translate(buf []byte, eof bool) (int, []byte, error) { - if len(buf) == 0 { - return 0, nil, nil - } - t[0] = xlate(buf[0]) - return 1, t[:], nil -} - -// OneByteWriter returns a Writer that implements -// each non-empty Write by writing one byte to w. -func OneByteWriter(w io.Writer) io.Writer { - return &oneByteWriter{w} -} - -type oneByteWriter struct { - w io.Writer -} - -func (w *oneByteWriter) Write(buf []byte) (int, error) { - n := 0 - for len(buf) > 0 { - nw, err := w.w.Write(buf[0:1]) - n += nw - if err != nil { - return n, err - } - buf = buf[1:] - } - return n, nil -} diff --git a/_third_party/code.google.com/p/go-charset/charset/codepage.go b/_third_party/code.google.com/p/go-charset/charset/codepage.go deleted file mode 100644 index 6864c875..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/codepage.go +++ /dev/null @@ -1,133 +0,0 @@ -package charset - -import ( - "fmt" - "unicode/utf8" -) - -func init() { - registerClass("cp", fromCodePage, toCodePage) -} - -type translateFromCodePage struct { - byte2rune *[256]rune - scratch []byte -} - -type cpKeyFrom string -type cpKeyTo string - -func (p *translateFromCodePage) Translate(data []byte, eof bool) (int, []byte, error) { - p.scratch = ensureCap(p.scratch, len(data)*utf8.UTFMax)[:0] - buf := p.scratch - for _, x := range data { - r := p.byte2rune[x] - if r < utf8.RuneSelf { - buf = append(buf, byte(r)) - continue - } - size := utf8.EncodeRune(buf[len(buf):cap(buf)], r) - buf = buf[0 : len(buf)+size] - } - return len(data), buf, nil -} - -type toCodePageInfo struct { - rune2byte map[rune]byte - // same gives the number of runes at start of code page that map exactly to - // unicode. - same rune -} - -type translateToCodePage struct { - toCodePageInfo - scratch []byte -} - -func (p *translateToCodePage) Translate(data []byte, eof bool) (int, []byte, error) { - p.scratch = ensureCap(p.scratch, len(data)) - buf := p.scratch[:0] - - for i := 0; i < len(data); { - r := rune(data[i]) - size := 1 - if r >= utf8.RuneSelf { - r, size = utf8.DecodeRune(data[i:]) - if size == 1 && !eof && !utf8.FullRune(data[i:]) { - return i, buf, nil - } - } - - var b byte - if r < p.same { - b = byte(r) - } else { - var ok bool - b, ok = p.rune2byte[r] - if !ok { - b = '?' - } - } - buf = append(buf, b) - i += size - } - return len(data), buf, nil -} - -func fromCodePage(arg string) (Translator, error) { - runes, err := cache(cpKeyFrom(arg), func() (interface{}, error) { - data, err := readFile(arg) - if err != nil { - return nil, err - } - runes := []rune(string(data)) - if len(runes) != 256 { - return nil, fmt.Errorf("charset: %q has wrong rune count (%d)", arg, len(runes)) - } - r := new([256]rune) - copy(r[:], runes) - return r, nil - }) - if err != nil { - return nil, err - } - return &translateFromCodePage{byte2rune: runes.(*[256]rune)}, nil -} - -func toCodePage(arg string) (Translator, error) { - m, err := cache(cpKeyTo(arg), func() (interface{}, error) { - data, err := readFile(arg) - if err != nil { - return nil, err - } - - info := toCodePageInfo{ - rune2byte: make(map[rune]byte), - same: 256, - } - atStart := true - i := rune(0) - for _, r := range string(data) { - if atStart { - if r == i { - i++ - continue - } - info.same = i - atStart = false - } - info.rune2byte[r] = byte(i) - i++ - } - // TODO fix tables - // fmt.Printf("%s, same = %d\n", arg, info.same) - if i != 256 { - return nil, fmt.Errorf("charset: %q has wrong rune count (%d)", arg, i) - } - return info, nil - }) - if err != nil { - return nil, err - } - return &translateToCodePage{toCodePageInfo: m.(toCodePageInfo)}, nil -} diff --git a/_third_party/code.google.com/p/go-charset/charset/cp932.go b/_third_party/code.google.com/p/go-charset/charset/cp932.go deleted file mode 100644 index 9f46262b..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/cp932.go +++ /dev/null @@ -1,195 +0,0 @@ -package charset - -import ( - "fmt" - "unicode/utf8" -) - -func init() { - registerClass("cp932", fromCP932, nil) -} - -// encoding details -// (Traditional) Shift-JIS -// -// 00..1f control characters -// 20 space -// 21..7f JIS X 0201:1976/1997 roman (see notes) -// 80 undefined -// 81..9f lead byte of JIS X 0208-1983 or JIS X 0202:1990/1997 -// a0 undefined -// a1..df JIS X 0201:1976/1997 katakana -// e0..ea lead byte of JIS X 0208-1983 or JIS X 0202:1990/1997 -// eb..ff undefined -// -// CP932 (windows-31J) -// -// this encoding scheme extends Shift-JIS in the following way -// -// eb..ec undefined (marked as lead bytes - see notes below) -// ed..ee lead byte of NEC-selected IBM extended characters -// ef undefined (marked as lead byte - see notes below) -// f0..f9 lead byte of User defined GAIJI (see note below) -// fa..fc lead byte of IBM extended characters -// fd..ff undefined -// -// -// Notes -// -// JISX 0201:1976/1997 roman -// this is the same as ASCII but with 0x5c (ASCII code for '\') -// representing the Yen currency symbol '¥' (U+00a5) -// This mapping is contentious, some conversion packages implent it -// others do not. -// The mapping files from The Unicode Consortium show cp932 mapping -// plain ascii in the range 00..7f whereas shift-jis maps 0x5c ('\') to the yen -// symbol (¥) and 0x7e ('~') to overline (¯) -// -// CP932 double-byte character codes: -// -// eb-ec, ef, f0-f9: -// Marked as DBCS LEAD BYTEs in the unicode mapping data -// obtained from: -// https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT -// -// but there are no defined mappings for codes in this range. -// It is not clear whether or not an implementation should -// consume one or two bytes before emitting an error char. - -const ( - kanaPages = 1 - kanaPageSize = 63 - kanaChar0 = 0xa1 - - cp932Pages = 45 // 81..84, 87..9f, e0..ea, ed..ee, fa..fc - cp932PageSize = 189 // 40..fc (including 7f) - cp932Char0 = 0x40 -) - -type jisTables struct { - page0 [256]rune - dbcsoff [256]int - cp932 []rune -} - -type translateFromCP932 struct { - tables *jisTables - scratch []byte -} - -func (p *translateFromCP932) Translate(data []byte, eof bool) (int, []byte, error) { - tables := p.tables - p.scratch = p.scratch[:0] - n := 0 - for i := 0; i < len(data); i++ { - b := data[i] - r := tables.page0[b] - if r != -1 { - p.scratch = appendRune(p.scratch, r) - n++ - continue - } - // DBCS - i++ - if i >= len(data) { - break - } - pnum := tables.dbcsoff[b] - ix := int(data[i]) - cp932Char0 - if pnum == -1 || ix < 0 || ix >= cp932PageSize { - r = utf8.RuneError - } else { - r = tables.cp932[pnum*cp932PageSize+ix] - } - p.scratch = appendRune(p.scratch, r) - n += 2 - } - return n, p.scratch, nil -} - -type cp932Key bool - -func fromCP932(arg string) (Translator, error) { - shiftJIS := arg == "shiftjis" - tables, err := cache(cp932Key(shiftJIS), func() (interface{}, error) { - tables := new(jisTables) - kana, err := jisGetMap("jisx0201kana.dat", kanaPageSize, kanaPages) - if err != nil { - return nil, err - } - tables.cp932, err = jisGetMap("cp932.dat", cp932PageSize, cp932Pages) - if err != nil { - return nil, err - } - - // jisx0201kana is mapped into 0xA1..0xDF - for i := 0; i < kanaPageSize; i++ { - tables.page0[i+kanaChar0] = kana[i] - } - - // 00..7f same as ascii in cp932 - for i := rune(0); i < 0x7f; i++ { - tables.page0[i] = i - } - - if shiftJIS { - // shift-jis uses JIS X 0201 for the ASCII range - // this is the same as ASCII apart from - // 0x5c ('\') maps to yen symbol (¥) and 0x7e ('~') maps to overline (¯) - tables.page0['\\'] = '¥' - tables.page0['~'] = '¯' - } - - // pre-calculate DBCS page numbers to mapping file page numbers - // and mark codes in page0 that are DBCS lead bytes - pnum := 0 - for i := 0x81; i <= 0x84; i++ { - tables.page0[i] = -1 - tables.dbcsoff[i] = pnum - pnum++ - } - for i := 0x87; i <= 0x9f; i++ { - tables.page0[i] = -1 - tables.dbcsoff[i] = pnum - pnum++ - } - for i := 0xe0; i <= 0xea; i++ { - tables.page0[i] = -1 - tables.dbcsoff[i] = pnum - pnum++ - } - if shiftJIS { - return tables, nil - } - // add in cp932 extensions - for i := 0xed; i <= 0xee; i++ { - tables.page0[i] = -1 - tables.dbcsoff[i] = pnum - pnum++ - } - for i := 0xfa; i <= 0xfc; i++ { - tables.page0[i] = -1 - tables.dbcsoff[i] = pnum - pnum++ - } - return tables, nil - }) - - if err != nil { - return nil, err - } - - return &translateFromCP932{tables: tables.(*jisTables)}, nil -} - -func jisGetMap(name string, pgsize, npages int) ([]rune, error) { - data, err := readFile(name) - if err != nil { - return nil, err - } - m := []rune(string(data)) - if len(m) != pgsize*npages { - return nil, fmt.Errorf("%q: incorrect length data", name) - } - return m, nil -} diff --git a/_third_party/code.google.com/p/go-charset/charset/example_test.go b/_third_party/code.google.com/p/go-charset/charset/example_test.go deleted file mode 100644 index 7f9dc849..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/example_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package charset_test - -import ( - "bytes" - "fmt" - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - _ "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/data" - "io/ioutil" - "log" - "strings" -) - -func ExampleNewReader() { - r, err := charset.NewReader("latin1", strings.NewReader("\xa35 for Pepp\xe9")) - if err != nil { - log.Fatal(err) - } - result, err := ioutil.ReadAll(r) - if err != nil { - log.Fatal(err) - } - fmt.Printf("%s\n", result) - // Output: £5 for Peppé -} - -func ExampleNewWriter() { - buf := new(bytes.Buffer) - w, err := charset.NewWriter("latin1", buf) - if err != nil { - log.Fatal(err) - } - fmt.Fprintf(w, "£5 for Peppé") - w.Close() - fmt.Printf("%q\n", buf.Bytes()) - // Output: "\xa35 for Pepp\xe9" -} diff --git a/_third_party/code.google.com/p/go-charset/charset/file.go b/_third_party/code.google.com/p/go-charset/charset/file.go deleted file mode 100644 index a0c26225..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/file.go +++ /dev/null @@ -1,40 +0,0 @@ -package charset - -import ( - "io" - "io/ioutil" - "os" - "path/filepath" -) - -var files = make(map[string]func() (io.ReadCloser, error)) - -// RegisterDataFile registers the existence of a given data -// file with the given name that may be used by a character-set converter. -// It is intended to be used by packages that wish to embed -// data in the executable binary, and should not be -// used normally. -func RegisterDataFile(name string, open func() (io.ReadCloser, error)) { - files[name] = open -} - -// CharsetDir gives the location of the default data file directory. -// This directory will be used for files with names that have not -// been registered with RegisterDataFile. -var CharsetDir = "/usr/local/lib/go-charset/datafiles" - -func readFile(name string) (data []byte, err error) { - var r io.ReadCloser - if open := files[name]; open != nil { - r, err = open() - if err != nil { - return - } - } else { - r, err = os.Open(filepath.Join(CharsetDir, name)) - if err != nil { - return - } - } - return ioutil.ReadAll(r) -} diff --git a/_third_party/code.google.com/p/go-charset/charset/local.go b/_third_party/code.google.com/p/go-charset/charset/local.go deleted file mode 100644 index 9776b962..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/local.go +++ /dev/null @@ -1,162 +0,0 @@ -package charset - -import ( - "encoding/json" - "fmt" - "os" - "sync" -) - -var ( - readLocalCharsetsOnce sync.Once - localCharsets = make(map[string]*localCharset) -) - -type localCharset struct { - Charset - arg string - *class -} - -// A class of character sets. -// Each class can be instantiated with an argument specified in the config file. -// Many character sets can use a single class. -type class struct { - from, to func(arg string) (Translator, error) -} - -// The set of classes, indexed by class name. -var classes = make(map[string]*class) - -func registerClass(charset string, from, to func(arg string) (Translator, error)) { - classes[charset] = &class{from, to} -} - -type localFactory struct{} - -func (f localFactory) TranslatorFrom(name string) (Translator, error) { - f.init() - name = NormalizedName(name) - cs := localCharsets[name] - if cs == nil { - return nil, fmt.Errorf("character set %q not found", name) - } - if cs.from == nil { - return nil, fmt.Errorf("cannot translate from %q", name) - } - return cs.from(cs.arg) -} - -func (f localFactory) TranslatorTo(name string) (Translator, error) { - f.init() - name = NormalizedName(name) - cs := localCharsets[name] - if cs == nil { - return nil, fmt.Errorf("character set %q not found", name) - } - if cs.to == nil { - return nil, fmt.Errorf("cannot translate to %q", name) - } - return cs.to(cs.arg) -} - -func (f localFactory) Names() []string { - f.init() - var names []string - for name, cs := range localCharsets { - // add names only for non-aliases. - if localCharsets[cs.Name] == cs { - names = append(names, name) - } - } - return names -} - -func (f localFactory) Info(name string) *Charset { - f.init() - lcs := localCharsets[NormalizedName(name)] - if lcs == nil { - return nil - } - // copy the charset info so that callers can't mess with it. - cs := lcs.Charset - return &cs -} - -func (f localFactory) init() { - readLocalCharsetsOnce.Do(readLocalCharsets) -} - -// charsetEntry is the data structure for one entry in the JSON config file. -// If Alias is non-empty, it should be the canonical name of another -// character set; otherwise Class should be the name -// of an entry in classes, and Arg is the argument for -// instantiating it. -type charsetEntry struct { - Aliases []string - Desc string - Class string - Arg string -} - -// readCharsets reads the JSON config file. -// It's done once only, when first needed. -func readLocalCharsets() { - csdata, err := readFile("charsets.json") - if err != nil { - fmt.Fprintf(os.Stderr, "charset: cannot open \"charsets.json\": %v\n", err) - return - } - - var entries map[string]charsetEntry - err = json.Unmarshal(csdata, &entries) - if err != nil { - fmt.Fprintf(os.Stderr, "charset: cannot decode config file: %v\n", err) - } - for name, e := range entries { - class := classes[e.Class] - if class == nil { - continue - } - name = NormalizedName(name) - for i, a := range e.Aliases { - e.Aliases[i] = NormalizedName(a) - } - cs := &localCharset{ - Charset: Charset{ - Name: name, - Aliases: e.Aliases, - Desc: e.Desc, - NoFrom: class.from == nil, - NoTo: class.to == nil, - }, - arg: e.Arg, - class: class, - } - localCharsets[cs.Name] = cs - for _, a := range cs.Aliases { - localCharsets[a] = cs - } - } -} - -// A general cache store that local character set translators -// can use for persistent storage of data. -var ( - cacheMutex sync.Mutex - cacheStore = make(map[interface{}]interface{}) -) - -func cache(key interface{}, f func() (interface{}, error)) (interface{}, error) { - cacheMutex.Lock() - defer cacheMutex.Unlock() - if x := cacheStore[key]; x != nil { - return x, nil - } - x, err := f() - if err != nil { - return nil, err - } - cacheStore[key] = x - return x, err -} diff --git a/_third_party/code.google.com/p/go-charset/charset/utf16.go b/_third_party/code.google.com/p/go-charset/charset/utf16.go deleted file mode 100644 index ebde794c..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/utf16.go +++ /dev/null @@ -1,110 +0,0 @@ -package charset - -import ( - "encoding/binary" - "errors" - "unicode/utf8" -) - -func init() { - registerClass("utf16", fromUTF16, toUTF16) -} - -type translateFromUTF16 struct { - first bool - endian binary.ByteOrder - scratch []byte -} - -func (p *translateFromUTF16) Translate(data []byte, eof bool) (int, []byte, error) { - data = data[0 : len(data)&^1] // round to even number of bytes. - if len(data) < 2 { - return 0, nil, nil - } - n := 0 - if p.first && p.endian == nil { - switch binary.BigEndian.Uint16(data) { - case 0xfeff: - p.endian = binary.BigEndian - data = data[2:] - n += 2 - case 0xfffe: - p.endian = binary.LittleEndian - data = data[2:] - n += 2 - default: - p.endian = guessEndian(data) - } - p.first = false - } - - p.scratch = p.scratch[:0] - for ; len(data) > 0; data = data[2:] { - p.scratch = appendRune(p.scratch, rune(p.endian.Uint16(data))) - n += 2 - } - return n, p.scratch, nil -} - -func guessEndian(data []byte) binary.ByteOrder { - // XXX TODO - return binary.LittleEndian -} - -type translateToUTF16 struct { - first bool - endian binary.ByteOrder - scratch []byte -} - -func (p *translateToUTF16) Translate(data []byte, eof bool) (int, []byte, error) { - p.scratch = ensureCap(p.scratch[:0], (len(data)+1)*2) - if p.first { - p.scratch = p.scratch[0:2] - p.endian.PutUint16(p.scratch, 0xfeff) - p.first = false - } - n := 0 - for len(data) > 0 { - if !utf8.FullRune(data) && !eof { - break - } - r, size := utf8.DecodeRune(data) - // TODO if r > 65535? - - slen := len(p.scratch) - p.scratch = p.scratch[0 : slen+2] - p.endian.PutUint16(p.scratch[slen:], uint16(r)) - data = data[size:] - n += size - } - return n, p.scratch, nil -} - -func getEndian(arg string) (binary.ByteOrder, error) { - switch arg { - case "le": - return binary.LittleEndian, nil - case "be": - return binary.BigEndian, nil - case "": - return nil, nil - } - return nil, errors.New("charset: unknown utf16 endianness") -} - -func fromUTF16(arg string) (Translator, error) { - endian, err := getEndian(arg) - if err != nil { - return nil, err - } - return &translateFromUTF16{first: true, endian: endian}, nil -} - -func toUTF16(arg string) (Translator, error) { - endian, err := getEndian(arg) - if err != nil { - return nil, err - } - return &translateToUTF16{first: false, endian: endian}, nil -} diff --git a/_third_party/code.google.com/p/go-charset/charset/utf8.go b/_third_party/code.google.com/p/go-charset/charset/utf8.go deleted file mode 100644 index 23980b33..00000000 --- a/_third_party/code.google.com/p/go-charset/charset/utf8.go +++ /dev/null @@ -1,51 +0,0 @@ -package charset - -import ( - "unicode/utf8" -) - -func init() { - registerClass("utf8", toUTF8, toUTF8) -} - -type translateToUTF8 struct { - scratch []byte -} - -var errorBytes = []byte(string(utf8.RuneError)) - -const errorRuneLen = len(string(utf8.RuneError)) - -func (p *translateToUTF8) Translate(data []byte, eof bool) (int, []byte, error) { - p.scratch = ensureCap(p.scratch, (len(data))*errorRuneLen) - buf := p.scratch[:0] - for i := 0; i < len(data); { - // fast path for ASCII - if b := data[i]; b < utf8.RuneSelf { - buf = append(buf, b) - i++ - continue - } - _, size := utf8.DecodeRune(data[i:]) - if size == 1 { - if !eof && !utf8.FullRune(data) { - // When DecodeRune has converted only a single - // byte, we know there must be some kind of error - // because we know the byte's not ASCII. - // If we aren't at EOF, and it's an incomplete - // rune encoding, then we return to process - // the final bytes in a subsequent call. - return i, buf, nil - } - buf = append(buf, errorBytes...) - } else { - buf = append(buf, data[i:i+size]...) - } - i += size - } - return len(data), buf, nil -} - -func toUTF8(arg string) (Translator, error) { - return new(translateToUTF8), nil -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_big5.dat.go b/_third_party/code.google.com/p/go-charset/data/data_big5.dat.go deleted file mode 100644 index a116cc66..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_big5.dat.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("big5.dat", func() (io.ReadCloser, error) { - r := strings.NewReader("\u3000,、。.・;:?!︰…‥﹐﹑﹒·﹔﹕﹖﹗︲–︱—︳�︴﹏()︵︶{}︷︸〔〕︹︺【】︻︼《》︽︾〈〉︿﹀「」﹁﹂『』﹃﹄﹙﹚﹛﹜﹝﹞‘’“”〝〞‵′#&*※§〃○●△▲◎☆★◇◆□■▽▼㊣℅‾�_�﹉﹊﹍﹎﹋﹌#&*+-×÷±√<>=≤≥≠∞≒≡﹢﹣﹤﹥﹦∼∩∪⊥∠∟⊿㏒㏑∫∮∵∴♀♂♁☉↑↓←→↖↗↙↘∥∣��/\$¥〒¢£%@℃℉$%@㏕㎜㎝㎞㏎㎡㎎㎏㏄°兙兛兞兝兡兣嗧瓩糎▁▂▃▄▅▆▇█▏▎▍▌▋▊▉┼┴┬┤├▔─│▕┌┐└┘╭╮╰╯═╞╪╡◢◣◥◤╱╲╳0123456789ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ〡〢〣〤〥〦〧〨〩�卄�ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ˙ˉˊˇˋ���������������������������������������������������������������一乙丁七乃九了二人儿入八几刀刁力匕十卜又三下丈上丫丸凡久么也乞于亡兀刃勺千叉口土士夕大女子孑孓寸小尢尸山川工己已巳巾干廾弋弓才丑丐不中丰丹之尹予云井互五亢仁什仃仆仇仍今介仄元允內六兮公冗凶分切刈勻勾勿化匹午升卅卞厄友及反壬天夫太夭孔少尤尺屯巴幻廿弔引心戈戶手扎支文斗斤方日曰月木欠止歹毋比毛氏水火爪父爻片牙牛犬王丙世丕且丘主乍乏乎以付仔仕他仗代令仙仞充兄冉冊冬凹出凸刊加功包匆北匝仟半卉卡占卯卮去可古右召叮叩叨叼司叵叫另只史叱台句叭叻四囚外央失奴奶孕它尼巨巧左市布平幼弁弘弗必戊打扔扒扑斥旦朮本未末札正母民氐永汁汀氾犯玄玉瓜瓦甘生用甩田由甲申疋白皮皿目矛矢石示禾穴立丞丟乒乓乩亙交亦亥仿伉伙伊伕伍伐休伏仲件任仰仳份企伋光兇兆先全共再冰列刑划刎刖劣匈匡匠印危吉吏同吊吐吁吋各向名合吃后吆吒因回囝圳地在圭圬圯圩夙多夷夸妄奸妃好她如妁字存宇守宅安寺尖屹州帆并年式弛忙忖戎戌戍成扣扛托收早旨旬旭曲曳有朽朴朱朵次此死氖汝汗汙江池汐汕污汛汍汎灰牟牝百竹米糸缶羊羽老考而耒耳聿肉肋肌臣自至臼舌舛舟艮色艾虫血行衣西阡串亨位住佇佗佞伴佛何估佐佑伽伺伸佃佔似但佣作你伯低伶余佝佈佚兌克免兵冶冷別判利刪刨劫助努劬匣即卵吝吭吞吾否呎吧呆呃吳呈呂君吩告吹吻吸吮吵吶吠吼呀吱含吟听囪困囤囫坊坑址坍均坎圾坐坏圻壯夾妝妒妨妞妣妙妖妍妤妓妊妥孝孜孚孛完宋宏尬局屁尿尾岐岑岔岌巫希序庇床廷弄弟彤形彷役忘忌志忍忱快忸忪戒我抄抗抖技扶抉扭把扼找批扳抒扯折扮投抓抑抆改攻攸旱更束李杏材村杜杖杞杉杆杠杓杗步每求汞沙沁沈沉沅沛汪決沐汰沌汨沖沒汽沃汲汾汴沆汶沍沔沘沂灶灼災灸牢牡牠狄狂玖甬甫男甸皂盯矣私秀禿究系罕肖肓肝肘肛肚育良芒芋芍見角言谷豆豕貝赤走足身車辛辰迂迆迅迄巡邑邢邪邦那酉釆里防阮阱阪阬並乖乳事些亞享京佯依侍佳使佬供例來侃佰併侈佩佻侖佾侏侑佺兔兒兕兩具其典冽函刻券刷刺到刮制剁劾劻卒協卓卑卦卷卸卹取叔受味呵咖呸咕咀呻呷咄咒咆呼咐呱呶和咚呢周咋命咎固垃坷坪坩坡坦坤坼夜奉奇奈奄奔妾妻委妹妮姑姆姐姍始姓姊妯妳姒姅孟孤季宗定官宜宙宛尚屈居屆岷岡岸岩岫岱岳帘帚帖帕帛帑幸庚店府底庖延弦弧弩往征彿彼忝忠忽念忿怏怔怯怵怖怪怕怡性怩怫怛或戕房戾所承拉拌拄抿拂抹拒招披拓拔拋拈抨抽押拐拙拇拍抵拚抱拘拖拗拆抬拎放斧於旺昔易昌昆昂明昀昏昕昊昇服朋杭枋枕東果杳杷枇枝林杯杰板枉松析杵枚枓杼杪杲欣武歧歿氓氛泣注泳沱泌泥河沽沾沼波沫法泓沸泄油況沮泗泅泱沿治泡泛泊沬泯泜泖泠炕炎炒炊炙爬爭爸版牧物狀狎狙狗狐玩玨玟玫玥甽疝疙疚的盂盲直知矽社祀祁秉秈空穹竺糾罔羌羋者肺肥肢肱股肫肩肴肪肯臥臾舍芳芝芙芭芽芟芹花芬芥芯芸芣芰芾芷虎虱初表軋迎返近邵邸邱邶采金長門阜陀阿阻附陂隹雨青非亟亭亮信侵侯便俠俑俏保促侶俘俟俊俗侮俐俄係俚俎俞侷兗冒冑冠剎剃削前剌剋則勇勉勃勁匍南卻厚叛咬哀咨哎哉咸咦咳哇哂咽咪品哄哈咯咫咱咻咩咧咿囿垂型垠垣垢城垮垓奕契奏奎奐姜姘姿姣姨娃姥姪姚姦威姻孩宣宦室客宥封屎屏屍屋峙峒巷帝帥帟幽庠度建弈弭彥很待徊律徇後徉怒思怠急怎怨恍恰恨恢恆恃恬恫恪恤扁拜挖按拼拭持拮拽指拱拷拯括拾拴挑挂政故斫施既春昭映昧是星昨昱昤曷柿染柱柔某柬架枯柵柩柯柄柑枴柚查枸柏柞柳枰柙柢柝柒歪殃殆段毒毗氟泉洋洲洪流津洌洱洞洗活洽派洶洛泵洹洧洸洩洮洵洎洫炫為炳炬炯炭炸炮炤爰牲牯牴狩狠狡玷珊玻玲珍珀玳甚甭畏界畎畋疫疤疥疢疣癸皆皇皈盈盆盃盅省盹相眉看盾盼眇矜砂研砌砍祆祉祈祇禹禺科秒秋穿突竿竽籽紂紅紀紉紇約紆缸美羿耄耐耍耑耶胖胥胚胃胄背胡胛胎胞胤胝致舢苧范茅苣苛苦茄若茂茉苒苗英茁苜苔苑苞苓苟苯茆虐虹虻虺衍衫要觔計訂訃貞負赴赳趴軍軌述迦迢迪迥迭迫迤迨郊郎郁郃酋酊重閂限陋陌降面革韋韭音頁風飛食首香乘亳倌倍倣俯倦倥俸倩倖倆值借倚倒們俺倀倔倨俱倡個候倘俳修倭倪俾倫倉兼冤冥冢凍凌准凋剖剜剔剛剝匪卿原厝叟哨唐唁唷哼哥哲唆哺唔哩哭員唉哮哪哦唧唇哽唏圃圄埂埔埋埃堉夏套奘奚娑娘娜娟娛娓姬娠娣娩娥娌娉孫屘宰害家宴宮宵容宸射屑展屐峭峽峻峪峨峰島崁峴差席師庫庭座弱徒徑徐恙恣恥恐恕恭恩息悄悟悚悍悔悌悅悖扇拳挈拿捎挾振捕捂捆捏捉挺捐挽挪挫挨捍捌效敉料旁旅時晉晏晃晒晌晅晁書朔朕朗校核案框桓根桂桔栩梳栗桌桑栽柴桐桀格桃株桅栓栘桁殊殉殷氣氧氨氦氤泰浪涕消涇浦浸海浙涓浬涉浮浚浴浩涌涊浹涅浥涔烊烘烤烙烈烏爹特狼狹狽狸狷玆班琉珮珠珪珞畔畝畜畚留疾病症疲疳疽疼疹痂疸皋皰益盍盎眩真眠眨矩砰砧砸砝破砷砥砭砠砟砲祕祐祠祟祖神祝祗祚秤秣秧租秦秩秘窄窈站笆笑粉紡紗紋紊素索純紐紕級紜納紙紛缺罟羔翅翁耆耘耕耙耗耽耿胱脂胰脅胭胴脆胸胳脈能脊胼胯臭臬舀舐航舫舨般芻茫荒荔荊茸荐草茵茴荏茲茹茶茗荀茱茨荃虔蚊蚪蚓蚤蚩蚌蚣蚜衰衷袁袂衽衹記訐討訌訕訊託訓訖訏訑豈豺豹財貢起躬軒軔軏辱送逆迷退迺迴逃追逅迸邕郡郝郢酒配酌釘針釗釜釙閃院陣陡陛陝除陘陞隻飢馬骨高鬥鬲鬼乾偺偽停假偃偌做偉健偶偎偕偵側偷偏倏偯偭兜冕凰剪副勒務勘動匐匏匙匿區匾參曼商啪啦啄啞啡啃啊唱啖問啕唯啤唸售啜唬啣唳啁啗圈國圉域堅堊堆埠埤基堂堵執培夠奢娶婁婉婦婪婀娼婢婚婆婊孰寇寅寄寂宿密尉專將屠屜屝崇崆崎崛崖崢崑崩崔崙崤崧崗巢常帶帳帷康庸庶庵庾張強彗彬彩彫得徙從徘御徠徜恿患悉悠您惋悴惦悽情悻悵惜悼惘惕惆惟悸惚惇戚戛扈掠控捲掖探接捷捧掘措捱掩掉掃掛捫推掄授掙採掬排掏掀捻捩捨捺敝敖救教敗啟敏敘敕敔斜斛斬族旋旌旎晝晚晤晨晦晞曹勗望梁梯梢梓梵桿桶梱梧梗械梃棄梭梆梅梔條梨梟梡梂欲殺毫毬氫涎涼淳淙液淡淌淤添淺清淇淋涯淑涮淞淹涸混淵淅淒渚涵淚淫淘淪深淮淨淆淄涪淬涿淦烹焉焊烽烯爽牽犁猜猛猖猓猙率琅琊球理現琍瓠瓶瓷甜產略畦畢異疏痔痕疵痊痍皎盔盒盛眷眾眼眶眸眺硫硃硎祥票祭移窒窕笠笨笛第符笙笞笮粒粗粕絆絃統紮紹紼絀細紳組累終紲紱缽羞羚翌翎習耜聊聆脯脖脣脫脩脰脤舂舵舷舶船莎莞莘荸莢莖莽莫莒莊莓莉莠荷荻荼莆莧處彪蛇蛀蚶蛄蚵蛆蛋蚱蚯蛉術袞袈被袒袖袍袋覓規訪訝訣訥許設訟訛訢豉豚販責貫貨貪貧赧赦趾趺軛軟這逍通逗連速逝逐逕逞造透逢逖逛途部郭都酗野釵釦釣釧釭釩閉陪陵陳陸陰陴陶陷陬雀雪雩章竟頂頃魚鳥鹵鹿麥麻傢傍傅備傑傀傖傘傚最凱割剴創剩勞勝勛博厥啻喀喧啼喊喝喘喂喜喪喔喇喋喃喳單喟唾喲喚喻喬喱啾喉喫喙圍堯堪場堤堰報堡堝堠壹壺奠婷媚婿媒媛媧孳孱寒富寓寐尊尋就嵌嵐崴嵇巽幅帽幀幃幾廊廁廂廄弼彭復循徨惑惡悲悶惠愜愣惺愕惰惻惴慨惱愎惶愉愀愒戟扉掣掌描揀揩揉揆揍插揣提握揖揭揮捶援揪換摒揚揹敞敦敢散斑斐斯普晰晴晶景暑智晾晷曾替期朝棺棕棠棘棗椅棟棵森棧棹棒棲棣棋棍植椒椎棉棚楮棻款欺欽殘殖殼毯氮氯氬港游湔渡渲湧湊渠渥渣減湛湘渤湖湮渭渦湯渴湍渺測湃渝渾滋溉渙湎湣湄湲湩湟焙焚焦焰無然煮焜牌犄犀猶猥猴猩琺琪琳琢琥琵琶琴琯琛琦琨甥甦畫番痢痛痣痙痘痞痠登發皖皓皴盜睏短硝硬硯稍稈程稅稀窘窗窖童竣等策筆筐筒答筍筋筏筑粟粥絞結絨絕紫絮絲絡給絢絰絳善翔翕耋聒肅腕腔腋腑腎脹腆脾腌腓腴舒舜菩萃菸萍菠菅萋菁華菱菴著萊菰萌菌菽菲菊萸萎萄菜萇菔菟虛蛟蛙蛭蛔蛛蛤蛐蛞街裁裂袱覃視註詠評詞証詁詔詛詐詆訴診訶詖象貂貯貼貳貽賁費賀貴買貶貿貸越超趁跎距跋跚跑跌跛跆軻軸軼辜逮逵週逸進逶鄂郵鄉郾酣酥量鈔鈕鈣鈉鈞鈍鈐鈇鈑閔閏開閑間閒閎隊階隋陽隅隆隍陲隄雁雅雄集雇雯雲韌項順須飧飪飯飩飲飭馮馭黃黍黑亂傭債傲傳僅傾催傷傻傯僇剿剷剽募勦勤勢勣匯嗟嗨嗓嗦嗎嗜嗇嗑嗣嗤嗯嗚嗡嗅嗆嗥嗉園圓塞塑塘塗塚塔填塌塭塊塢塒塋奧嫁嫉嫌媾媽媼媳嫂媲嵩嵯幌幹廉廈弒彙徬微愚意慈感想愛惹愁愈慎慌慄慍愾愴愧愍愆愷戡戢搓搾搞搪搭搽搬搏搜搔損搶搖搗搆敬斟新暗暉暇暈暖暄暘暍會榔業楚楷楠楔極椰概楊楨楫楞楓楹榆楝楣楛歇歲毀殿毓毽溢溯滓溶滂源溝滇滅溥溘溼溺溫滑準溜滄滔溪溧溴煎煙煩煤煉照煜煬煦煌煥煞煆煨煖爺牒猷獅猿猾瑯瑚瑕瑟瑞瑁琿瑙瑛瑜當畸瘀痰瘁痲痱痺痿痴痳盞盟睛睫睦睞督睹睪睬睜睥睨睢矮碎碰碗碘碌碉硼碑碓硿祺祿禁萬禽稜稚稠稔稟稞窟窠筷節筠筮筧粱粳粵經絹綑綁綏絛置罩罪署義羨群聖聘肆肄腱腰腸腥腮腳腫腹腺腦舅艇蒂葷落萱葵葦葫葉葬葛萼萵葡董葩葭葆虞虜號蛹蜓蜈蜇蜀蛾蛻蜂蜃蜆蜊衙裟裔裙補裘裝裡裊裕裒覜解詫該詳試詩詰誇詼詣誠話誅詭詢詮詬詹詻訾詨豢貊貉賊資賈賄貲賃賂賅跡跟跨路跳跺跪跤跦躲較載軾輊辟農運遊道遂達逼違遐遇遏過遍遑逾遁鄒鄗酬酪酩釉鈷鉗鈸鈽鉀鈾鉛鉋鉤鉑鈴鉉鉍鉅鈹鈿鉚閘隘隔隕雍雋雉雊雷電雹零靖靴靶預頑頓頊頒頌飼飴飽飾馳馱馴髡鳩麂鼎鼓鼠僧僮僥僖僭僚僕像僑僱僎僩兢凳劃劂匱厭嗾嘀嘛嘗嗽嘔嘆嘉嘍嘎嗷嘖嘟嘈嘐嗶團圖塵塾境墓墊塹墅塽壽夥夢夤奪奩嫡嫦嫩嫗嫖嫘嫣孵寞寧寡寥實寨寢寤察對屢嶄嶇幛幣幕幗幔廓廖弊彆彰徹慇愿態慷慢慣慟慚慘慵截撇摘摔撤摸摟摺摑摧搴摭摻敲斡旗旖暢暨暝榜榨榕槁榮槓構榛榷榻榫榴槐槍榭槌榦槃榣歉歌氳漳演滾漓滴漩漾漠漬漏漂漢滿滯漆漱漸漲漣漕漫漯澈漪滬漁滲滌滷熔熙煽熊熄熒爾犒犖獄獐瑤瑣瑪瑰瑭甄疑瘧瘍瘋瘉瘓盡監瞄睽睿睡磁碟碧碳碩碣禎福禍種稱窪窩竭端管箕箋筵算箝箔箏箸箇箄粹粽精綻綰綜綽綾綠緊綴網綱綺綢綿綵綸維緒緇綬罰翠翡翟聞聚肇腐膀膏膈膊腿膂臧臺與舔舞艋蓉蒿蓆蓄蒙蒞蒲蒜蓋蒸蓀蓓蒐蒼蓑蓊蜿蜜蜻蜢蜥蜴蜘蝕蜷蜩裳褂裴裹裸製裨褚裯誦誌語誣認誡誓誤說誥誨誘誑誚誧豪貍貌賓賑賒赫趙趕跼輔輒輕輓辣遠遘遜遣遙遞遢遝遛鄙鄘鄞酵酸酷酴鉸銀銅銘銖鉻銓銜銨鉼銑閡閨閩閣閥閤隙障際雌雒需靼鞅韶頗領颯颱餃餅餌餉駁骯骰髦魁魂鳴鳶鳳麼鼻齊億儀僻僵價儂儈儉儅凜劇劈劉劍劊勰厲嘮嘻嘹嘲嘿嘴嘩噓噎噗噴嘶嘯嘰墀墟增墳墜墮墩墦奭嬉嫻嬋嫵嬌嬈寮寬審寫層履嶝嶔幢幟幡廢廚廟廝廣廠彈影德徵慶慧慮慝慕憂慼慰慫慾憧憐憫憎憬憚憤憔憮戮摩摯摹撞撲撈撐撰撥撓撕撩撒撮播撫撚撬撙撢撳敵敷數暮暫暴暱樣樟槨樁樞標槽模樓樊槳樂樅槭樑歐歎殤毅毆漿潼澄潑潦潔澆潭潛潸潮澎潺潰潤澗潘滕潯潠潟熟熬熱熨牖犛獎獗瑩璋璃瑾璀畿瘠瘩瘟瘤瘦瘡瘢皚皺盤瞎瞇瞌瞑瞋磋磅確磊碾磕碼磐稿稼穀稽稷稻窯窮箭箱範箴篆篇篁箠篌糊締練緯緻緘緬緝編緣線緞緩綞緙緲緹罵罷羯翩耦膛膜膝膠膚膘蔗蔽蔚蓮蔬蔭蔓蔑蔣蔡蔔蓬蔥蓿蔆螂蝴蝶蝠蝦蝸蝨蝙蝗蝌蝓衛衝褐複褒褓褕褊誼諒談諄誕請諸課諉諂調誰論諍誶誹諛豌豎豬賠賞賦賤賬賭賢賣賜質賡赭趟趣踫踐踝踢踏踩踟踡踞躺輝輛輟輩輦輪輜輞輥適遮遨遭遷鄰鄭鄧鄱醇醉醋醃鋅銻銷鋪銬鋤鋁銳銼鋒鋇鋰銲閭閱霄霆震霉靠鞍鞋鞏頡頫頜颳養餓餒餘駝駐駟駛駑駕駒駙骷髮髯鬧魅魄魷魯鴆鴉鴃麩麾黎墨齒儒儘儔儐儕冀冪凝劑劓勳噙噫噹噩噤噸噪器噥噱噯噬噢噶壁墾壇壅奮嬝嬴學寰導彊憲憑憩憊懍憶憾懊懈戰擅擁擋撻撼據擄擇擂操撿擒擔撾整曆曉暹曄曇暸樽樸樺橙橫橘樹橄橢橡橋橇樵機橈歙歷氅濂澱澡濃澤濁澧澳激澹澶澦澠澴熾燉燐燒燈燕熹燎燙燜燃燄獨璜璣璘璟璞瓢甌甍瘴瘸瘺盧盥瞠瞞瞟瞥磨磚磬磧禦積穎穆穌穋窺篙簑築篤篛篡篩篦糕糖縊縑縈縛縣縞縝縉縐罹羲翰翱翮耨膳膩膨臻興艘艙蕊蕙蕈蕨蕩蕃蕉蕭蕪蕞螃螟螞螢融衡褪褲褥褫褡親覦諦諺諫諱謀諜諧諮諾謁謂諷諭諳諶諼豫豭貓賴蹄踱踴蹂踹踵輻輯輸輳辨辦遵遴選遲遼遺鄴醒錠錶鋸錳錯錢鋼錫錄錚錐錦錡錕錮錙閻隧隨險雕霎霑霖霍霓霏靛靜靦鞘頰頸頻頷頭頹頤餐館餞餛餡餚駭駢駱骸骼髻髭鬨鮑鴕鴣鴦鴨鴒鴛默黔龍龜優償儡儲勵嚎嚀嚐嚅嚇嚏壕壓壑壎嬰嬪嬤孺尷屨嶼嶺嶽嶸幫彌徽應懂懇懦懋戲戴擎擊擘擠擰擦擬擱擢擭斂斃曙曖檀檔檄檢檜櫛檣橾檗檐檠歜殮毚氈濘濱濟濠濛濤濫濯澀濬濡濩濕濮濰燧營燮燦燥燭燬燴燠爵牆獰獲璩環璦璨癆療癌盪瞳瞪瞰瞬瞧瞭矯磷磺磴磯礁禧禪穗窿簇簍篾篷簌篠糠糜糞糢糟糙糝縮績繆縷縲繃縫總縱繅繁縴縹繈縵縿縯罄翳翼聱聲聰聯聳臆臃膺臂臀膿膽臉膾臨舉艱薪薄蕾薜薑薔薯薛薇薨薊虧蟀蟑螳蟒蟆螫螻螺蟈蟋褻褶襄褸褽覬謎謗謙講謊謠謝謄謐豁谿豳賺賽購賸賻趨蹉蹋蹈蹊轄輾轂轅輿避遽還邁邂邀鄹醣醞醜鍍鎂錨鍵鍊鍥鍋錘鍾鍬鍛鍰鍚鍔闊闋闌闈闆隱隸雖霜霞鞠韓顆颶餵騁駿鮮鮫鮪鮭鴻鴿麋黏點黜黝黛鼾齋叢嚕嚮壙壘嬸彝懣戳擴擲擾攆擺擻擷斷曜朦檳檬櫃檻檸櫂檮檯歟歸殯瀉瀋濾瀆濺瀑瀏燻燼燾燸獷獵璧璿甕癖癘癒瞽瞿瞻瞼礎禮穡穢穠竄竅簫簧簪簞簣簡糧織繕繞繚繡繒繙罈翹翻職聶臍臏舊藏薩藍藐藉薰薺薹薦蟯蟬蟲蟠覆覲觴謨謹謬謫豐贅蹙蹣蹦蹤蹟蹕軀轉轍邇邃邈醫醬釐鎔鎊鎖鎢鎳鎮鎬鎰鎘鎚鎗闔闖闐闕離雜雙雛雞霤鞣鞦鞭韹額顏題顎顓颺餾餿餽餮馥騎髁鬃鬆魏魎魍鯊鯉鯽鯈鯀鵑鵝鵠黠鼕鼬儳嚥壞壟壢寵龐廬懲懷懶懵攀攏曠曝櫥櫝櫚櫓瀛瀟瀨瀚瀝瀕瀘爆爍牘犢獸獺璽瓊瓣疇疆癟癡矇礙禱穫穩簾簿簸簽簷籀繫繭繹繩繪羅繳羶羹羸臘藩藝藪藕藤藥藷蟻蠅蠍蟹蟾襠襟襖襞譁譜識證譚譎譏譆譙贈贊蹼蹲躇蹶蹬蹺蹴轔轎辭邊邋醱醮鏡鏑鏟鏃鏈鏜鏝鏖鏢鏍鏘鏤鏗鏨關隴難霪霧靡韜韻類願顛颼饅饉騖騙鬍鯨鯧鯖鯛鶉鵡鵲鵪鵬麒麗麓麴勸嚨嚷嚶嚴嚼壤孀孃孽寶巉懸懺攘攔攙曦朧櫬瀾瀰瀲爐獻瓏癢癥礦礪礬礫竇競籌籃籍糯糰辮繽繼纂罌耀臚艦藻藹蘑藺蘆蘋蘇蘊蠔蠕襤覺觸議譬警譯譟譫贏贍躉躁躅躂醴釋鐘鐃鏽闡霰飄饒饑馨騫騰騷騵鰓鰍鹹麵黨鼯齟齣齡儷儸囁囀囂夔屬巍懼懾攝攜斕曩櫻欄櫺殲灌爛犧瓖瓔癩矓籐纏續羼蘗蘭蘚蠣蠢蠡蠟襪襬覽譴護譽贓躊躍躋轟辯醺鐮鐳鐵鐺鐸鐲鐫闢霸霹露響顧顥饗驅驃驀騾髏魔魑鰭鰥鶯鶴鷂鶸麝黯鼙齜齦齧儼儻囈囊囉孿巔巒彎懿攤權歡灑灘玀瓤疊癮癬禳籠籟聾聽臟襲襯觼讀贖贗躑躓轡酈鑄鑑鑒霽霾韃韁顫饕驕驍髒鬚鱉鰱鰾鰻鷓鷗鼴齬齪龔囌巖戀攣攫攪曬欐瓚竊籤籣籥纓纖纔臢蘸蘿蠱變邐邏鑣鑠鑤靨顯饜驚驛驗髓體髑鱔鱗鱖鷥麟黴囑壩攬灞癱癲矗罐羈蠶蠹衢讓讒讖艷贛釀鑪靂靈靄韆顰驟鬢魘鱟鷹鷺鹼鹽鼇齷齲廳欖灣籬籮蠻觀躡釁鑲鑰顱饞髖鬣黌灤矚讚鑷韉驢驥纜讜躪釅鑽鑾鑼鱷鱸黷豔鑿鸚爨驪鬱鸛鸞籲ヾゝゞ々ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶДЕЁЖЗИЙКЛМУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя①②③④⑤⑥⑦⑧⑨⑩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽���������������������������������������������������������������������������������������������������������������������������������������������������������������乂乜凵匚厂万丌乇亍囗兀屮彳丏冇与丮亓仂仉仈冘勼卬厹圠夃夬尐巿旡殳毌气爿丱丼仨仜仩仡仝仚刌匜卌圢圣夗夯宁宄尒尻屴屳帄庀庂忉戉扐氕氶汃氿氻犮犰玊禸肊阞伎优伬仵伔仱伀价伈伝伂伅伢伓伄仴伒冱刓刉刐劦匢匟卍厊吇囡囟圮圪圴夼妀奼妅奻奾奷奿孖尕尥屼屺屻屾巟幵庄异弚彴忕忔忏扜扞扤扡扦扢扙扠扚扥旯旮朾朹朸朻机朿朼朳氘汆汒汜汏汊汔汋汌灱牞犴犵玎甪癿穵网艸艼芀艽艿虍襾邙邗邘邛邔阢阤阠阣佖伻佢佉体佤伾佧佒佟佁佘伭伳伿佡冏冹刜刞刡劭劮匉卣卲厎厏吰吷吪呔呅吙吜吥吘吽呏呁吨吤呇囮囧囥坁坅坌坉坋坒夆奀妦妘妠妗妎妢妐妏妧妡宎宒尨尪岍岏岈岋岉岒岊岆岓岕巠帊帎庋庉庌庈庍弅弝彸彶忒忑忐忭忨忮忳忡忤忣忺忯忷忻怀忴戺抃抌抎抏抔抇扱扻扺扰抁抈扷扽扲扴攷旰旴旳旲旵杅杇杙杕杌杈杝杍杚杋毐氙氚汸汧汫沄沋沏汱汯汩沚汭沇沕沜汦汳汥汻沎灴灺牣犿犽狃狆狁犺狅玕玗玓玔玒町甹疔疕皁礽耴肕肙肐肒肜芐芏芅芎芑芓芊芃芄豸迉辿邟邡邥邞邧邠阰阨阯阭丳侘佼侅佽侀侇佶佴侉侄佷佌侗佪侚佹侁佸侐侜侔侞侒侂侕佫佮冞冼冾刵刲刳剆刱劼匊匋匼厒厔咇呿咁咑咂咈呫呺呾呥呬呴呦咍呯呡呠咘呣呧呤囷囹坯坲坭坫坱坰坶垀坵坻坳坴坢坨坽夌奅妵妺姏姎妲姌姁妶妼姃姖妱妽姀姈妴姇孢孥宓宕屄屇岮岤岠岵岯岨岬岟岣岭岢岪岧岝岥岶岰岦帗帔帙弨弢弣弤彔徂彾彽忞忥怭怦怙怲怋怴怊怗怳怚怞怬怢怍怐怮怓怑怌怉怜戔戽抭抴拑抾抪抶拊抮抳抯抻抩抰抸攽斨斻昉旼昄昒昈旻昃昋昍昅旽昑昐曶朊枅杬枎枒杶杻枘枆构杴枍枌杺枟枑枙枃杽极杸杹枔欥殀歾毞氝沓泬泫泮泙沶泔沭泧沷泐泂沺泃泆泭泲泒泝沴沊沝沀泞泀洰泍泇沰泹泏泩泑炔炘炅炓炆炄炑炖炂炚炃牪狖狋狘狉狜狒狔狚狌狑玤玡玭玦玢玠玬玝瓝瓨甿畀甾疌疘皯盳盱盰盵矸矼矹矻矺矷祂礿秅穸穻竻籵糽耵肏肮肣肸肵肭舠芠苀芫芚芘芛芵芧芮芼芞芺芴芨芡芩苂芤苃芶芢虰虯虭虮豖迒迋迓迍迖迕迗邲邴邯邳邰阹阽阼阺陃俍俅俓侲俉俋俁俔俜俙侻侳俛俇俖侺俀侹俬剄剉勀勂匽卼厗厖厙厘咺咡咭咥哏哃茍咷咮哖咶哅哆咠呰咼咢咾呲哞咰垵垞垟垤垌垗垝垛垔垘垏垙垥垚垕壴复奓姡姞姮娀姱姝姺姽姼姶姤姲姷姛姩姳姵姠姾姴姭宨屌峐峘峌峗峋峛峞峚峉峇峊峖峓峔峏峈峆峎峟峸巹帡帢帣帠帤庰庤庢庛庣庥弇弮彖徆怷怹恔恲恞恅恓恇恉恛恌恀恂恟怤恄恘恦恮扂扃拏挍挋拵挎挃拫拹挏挌拸拶挀挓挔拺挕拻拰敁敃斪斿昶昡昲昵昜昦昢昳昫昺昝昴昹昮朏朐柁柲柈枺柜枻柸柘柀枷柅柫柤柟枵柍枳柷柶柮柣柂枹柎柧柰枲柼柆柭柌枮柦柛柺柉柊柃柪柋欨殂殄殶毖毘毠氠氡洨洴洭洟洼洿洒洊泚洳洄洙洺洚洑洀洝浂洁洘洷洃洏浀洇洠洬洈洢洉洐炷炟炾炱炰炡炴炵炩牁牉牊牬牰牳牮狊狤狨狫狟狪狦狣玅珌珂珈珅玹玶玵玴珫玿珇玾珃珆玸珋瓬瓮甮畇畈疧疪癹盄眈眃眄眅眊盷盻盺矧矨砆砑砒砅砐砏砎砉砃砓祊祌祋祅祄秕种秏秖秎窀穾竑笀笁籺籸籹籿粀粁紃紈紁罘羑羍羾耇耎耏耔耷胘胇胠胑胈胂胐胅胣胙胜胊胕胉胏胗胦胍臿舡芔苙苾苹茇苨茀苕茺苫苖苴苬苡苲苵茌苻苶苰苪苤苠苺苳苭虷虴虼虳衁衎衧衪衩觓訄訇赲迣迡迮迠郱邽邿郕郅邾郇郋郈釔釓陔陏陑陓陊陎倞倅倇倓倢倰倛俵俴倳倷倬俶俷倗倜倠倧倵倯倱倎党冔冓凊凄凅凈凎剡剚剒剞剟剕剢勍匎厞唦哢唗唒哧哳哤唚哿唄唈哫唑唅哱唊哻哷哸哠唎唃唋圁圂埌堲埕埒垺埆垽垼垸垶垿埇埐垹埁夎奊娙娖娭娮娕娏娗娊娞娳孬宧宭宬尃屖屔峬峿峮峱峷崀峹帩帨庨庮庪庬弳弰彧恝恚恧恁悢悈悀悒悁悝悃悕悛悗悇悜悎戙扆拲挐捖挬捄捅挶捃揤挹捋捊挼挩捁挴捘捔捙挭捇挳捚捑挸捗捀捈敊敆旆旃旄旂晊晟晇晑朒朓栟栚桉栲栳栻桋桏栖栱栜栵栫栭栯桎桄栴栝栒栔栦栨栮桍栺栥栠欬欯欭欱欴歭肂殈毦毤毨毣毢毧氥浺浣浤浶洍浡涒浘浢浭浯涑涍淯浿涆浞浧浠涗浰浼浟涂涘洯浨涋浾涀涄洖涃浻浽浵涐烜烓烑烝烋缹烢烗烒烞烠烔烍烅烆烇烚烎烡牂牸牷牶猀狺狴狾狶狳狻猁珓珙珥珖玼珧珣珩珜珒珛珔珝珚珗珘珨瓞瓟瓴瓵甡畛畟疰痁疻痄痀疿疶疺皊盉眝眛眐眓眒眣眑眕眙眚眢眧砣砬砢砵砯砨砮砫砡砩砳砪砱祔祛祏祜祓祒祑秫秬秠秮秭秪秜秞秝窆窉窅窋窌窊窇竘笐笄笓笅笏笈笊笎笉笒粄粑粊粌粈粍粅紞紝紑紎紘紖紓紟紒紏紌罜罡罞罠罝罛羖羒翃翂翀耖耾耹胺胲胹胵脁胻脀舁舯舥茳茭荄茙荑茥荖茿荁茦茜茢荂荎茛茪茈茼荍茖茤茠茷茯茩荇荅荌荓茞茬荋茧荈虓虒蚢蚨蚖蚍蚑蚞蚇蚗蚆蚋蚚蚅蚥蚙蚡蚧蚕蚘蚎蚝蚐蚔衃衄衭衵衶衲袀衱衿衯袃衾衴衼訒豇豗豻貤貣赶赸趵趷趶軑軓迾迵适迿迻逄迼迶郖郠郙郚郣郟郥郘郛郗郜郤酐酎酏釕釢釚陜陟隼飣髟鬯乿偰偪偡偞偠偓偋偝偲偈偍偁偛偊偢倕偅偟偩偫偣偤偆偀偮偳偗偑凐剫剭剬剮勖勓匭厜啵啶唼啍啐唴唪啑啢唶唵唰啒啅唌唲啥啎唹啈唭唻啀啋圊圇埻堔埢埶埜埴堀埭埽堈埸堋埳埏堇埮埣埲埥埬埡堎埼堐埧堁堌埱埩埰堍堄奜婠婘婕婧婞娸娵婭婐婟婥婬婓婤婗婃婝婒婄婛婈媎娾婍娹婌婰婩婇婑婖婂婜孲孮寁寀屙崞崋崝崚崠崌崨崍崦崥崏崰崒崣崟崮帾帴庱庴庹庲庳弶弸徛徖徟悊悐悆悾悰悺惓惔惏惤惙惝惈悱惛悷惊悿惃惍惀挲捥掊掂捽掽掞掭掝掗掫掎捯掇掐据掯捵掜捭掮捼掤挻掟捸掅掁掑掍捰敓旍晥晡晛晙晜晢朘桹梇梐梜桭桮梮梫楖桯梣梬梩桵桴梲梏桷梒桼桫桲梪梀桱桾梛梖梋梠梉梤桸桻梑梌梊桽欶欳欷欸殑殏殍殎殌氪淀涫涴涳湴涬淩淢涷淶淔渀淈淠淟淖涾淥淜淝淛淴淊涽淭淰涺淕淂淏淉淐淲淓淽淗淍淣涻烺焍烷焗烴焌烰焄烳焐烼烿焆焓焀烸烶焋焂焎牾牻牼牿猝猗猇猑猘猊猈狿猏猞玈珶珸珵琄琁珽琇琀珺珼珿琌琋珴琈畤畣痎痒痏痋痌痑痐皏皉盓眹眯眭眱眲眴眳眽眥眻眵硈硒硉硍硊硌砦硅硐祤祧祩祪祣祫祡离秺秸秶秷窏窔窐笵筇笴笥笰笢笤笳笘笪笝笱笫笭笯笲笸笚笣粔粘粖粣紵紽紸紶紺絅紬紩絁絇紾紿絊紻紨罣羕羜羝羛翊翋翍翐翑翇翏翉耟耞耛聇聃聈脘脥脙脛脭脟脬脞脡脕脧脝脢舑舸舳舺舴舲艴莐莣莨莍荺荳莤荴莏莁莕莙荵莔莩荽莃莌莝莛莪莋荾莥莯莈莗莰荿莦莇莮荶莚虙虖蚿蚷蛂蛁蛅蚺蚰蛈蚹蚳蚸蛌蚴蚻蚼蛃蚽蚾衒袉袕袨袢袪袚袑袡袟袘袧袙袛袗袤袬袌袓袎覂觖觙觕訰訧訬訞谹谻豜豝豽貥赽赻赹趼跂趹趿跁軘軞軝軜軗軠軡逤逋逑逜逌逡郯郪郰郴郲郳郔郫郬郩酖酘酚酓酕釬釴釱釳釸釤釹釪釫釷釨釮镺閆閈陼陭陫陱陯隿靪頄飥馗傛傕傔傞傋傣傃傌傎傝偨傜傒傂傇兟凔匒匑厤厧喑喨喥喭啷噅喢喓喈喏喵喁喣喒喤啽喌喦啿喕喡喎圌堩堷堙堞堧堣堨埵塈堥堜堛堳堿堶堮堹堸堭堬堻奡媯媔媟婺媢媞婸媦婼媥媬媕媮娷媄媊媗媃媋媩婻婽媌媜媏媓媝寪寍寋寔寑寊寎尌尰崷嵃嵫嵁嵋崿崵嵑嵎嵕崳崺嵒崽崱嵙嵂崹嵉崸崼崲崶嵀嵅幄幁彘徦徥徫惉悹惌惢惎惄愔惲愊愖愅惵愓惸惼惾惁愃愘愝愐惿愄愋扊掔掱掰揎揥揨揯揃撝揳揊揠揶揕揲揵摡揟掾揝揜揄揘揓揂揇揌揋揈揰揗揙攲敧敪敤敜敨敥斌斝斞斮旐旒晼晬晻暀晱晹晪晲朁椌棓椄棜椪棬棪棱椏棖棷棫棤棶椓椐棳棡椇棌椈楰梴椑棯棆椔棸棐棽棼棨椋椊椗棎棈棝棞棦棴棑椆棔棩椕椥棇欹欻欿欼殔殗殙殕殽毰毲毳氰淼湆湇渟湉溈渼渽湅湢渫渿湁湝湳渜渳湋湀湑渻渃渮湞湨湜湡渱渨湠湱湫渹渢渰湓湥渧湸湤湷湕湹湒湦渵渶湚焠焞焯烻焮焱焣焥焢焲焟焨焺焛牋牚犈犉犆犅犋猒猋猰猢猱猳猧猲猭猦猣猵猌琮琬琰琫琖琚琡琭琱琤琣琝琩琠琲瓻甯畯畬痧痚痡痦痝痟痤痗皕皒盚睆睇睄睍睅睊睎睋睌矞矬硠硤硥硜硭硱硪确硰硩硨硞硢祴祳祲祰稂稊稃稌稄窙竦竤筊笻筄筈筌筎筀筘筅粢粞粨粡絘絯絣絓絖絧絪絏絭絜絫絒絔絩絑絟絎缾缿罥罦羢羠羡翗聑聏聐胾胔腃腊腒腏腇脽腍脺臦臮臷臸臹舄舼舽舿艵茻菏菹萣菀菨萒菧菤菼菶萐菆菈菫菣莿萁菝菥菘菿菡菋菎菖菵菉萉萏菞萑萆菂菳菕菺菇菑菪萓菃菬菮菄菻菗菢萛菛菾蛘蛢蛦蛓蛣蛚蛪蛝蛫蛜蛬蛩蛗蛨蛑衈衖衕袺裗袹袸裀袾袶袼袷袽袲褁裉覕覘覗觝觚觛詎詍訹詙詀詗詘詄詅詒詈詑詊詌詏豟貁貀貺貾貰貹貵趄趀趉跘跓跍跇跖跜跏跕跙跈跗跅軯軷軺軹軦軮軥軵軧軨軶軫軱軬軴軩逭逴逯鄆鄬鄄郿郼鄈郹郻鄁鄀鄇鄅鄃酡酤酟酢酠鈁鈊鈥鈃鈚鈦鈏鈌鈀鈒釿釽鈆鈄鈧鈂鈜鈤鈙鈗鈅鈖镻閍閌閐隇陾隈隉隃隀雂雈雃雱雰靬靰靮頇颩飫鳦黹亃亄亶傽傿僆傮僄僊傴僈僂傰僁傺傱僋僉傶傸凗剺剸剻剼嗃嗛嗌嗐嗋嗊嗝嗀嗔嗄嗩喿嗒喍嗏嗕嗢嗖嗈嗲嗍嗙嗂圔塓塨塤塏塍塉塯塕塎塝塙塥塛堽塣塱壼嫇嫄嫋媺媸媱媵媰媿嫈媻嫆媷嫀嫊媴媶嫍媹媐寖寘寙尟尳嵱嵣嵊嵥嵲嵬嵞嵨嵧嵢巰幏幎幊幍幋廅廌廆廋廇彀徯徭惷慉慊愫慅愶愲愮慆愯慏愩慀戠酨戣戥戤揅揱揫搐搒搉搠搤搳摃搟搕搘搹搷搢搣搌搦搰搨摁搵搯搊搚摀搥搧搋揧搛搮搡搎敯斒旓暆暌暕暐暋暊暙暔晸朠楦楟椸楎楢楱椿楅楪椹楂楗楙楺楈楉椵楬椳椽楥棰楸椴楩楀楯楄楶楘楁楴楌椻楋椷楜楏楑椲楒椯楻椼歆歅歃歂歈歁殛嗀毻毼毹毷毸溛滖滈溏滀溟溓溔溠溱溹滆滒溽滁溞滉溷溰滍溦滏溲溾滃滜滘溙溒溎溍溤溡溿溳滐滊溗溮溣煇煔煒煣煠煁煝煢煲煸煪煡煂煘煃煋煰煟煐煓煄煍煚牏犍犌犑犐犎猼獂猻猺獀獊獉瑄瑊瑋瑒瑑瑗瑀瑏瑐瑎瑂瑆瑍瑔瓡瓿瓾瓽甝畹畷榃痯瘏瘃痷痾痼痹痸瘐痻痶痭痵痽皙皵盝睕睟睠睒睖睚睩睧睔睙睭矠碇碚碔碏碄碕碅碆碡碃硹碙碀碖硻祼禂祽祹稑稘稙稒稗稕稢稓稛稐窣窢窞竫筦筤筭筴筩筲筥筳筱筰筡筸筶筣粲粴粯綈綆綀綍絿綅絺綎絻綃絼綌綔綄絽綒罭罫罧罨罬羦羥羧翛翜耡腤腠腷腜腩腛腢腲朡腞腶腧腯腄腡舝艉艄艀艂艅蓱萿葖葶葹蒏蒍葥葑葀蒆葧萰葍葽葚葙葴葳葝蔇葞萷萺萴葺葃葸萲葅萩菙葋萯葂萭葟葰萹葎葌葒葯蓅蒎萻葇萶萳葨葾葄萫葠葔葮葐蜋蜄蛷蜌蛺蛖蛵蝍蛸蜎蜉蜁蛶蜍蜅裖裋裍裎裞裛裚裌裐覅覛觟觥觤觡觠觢觜触詶誆詿詡訿詷誂誄詵誃誁詴詺谼豋豊豥豤豦貆貄貅賌赨赩趑趌趎趏趍趓趔趐趒跰跠跬跱跮跐跩跣跢跧跲跫跴輆軿輁輀輅輇輈輂輋遒逿遄遉逽鄐鄍鄏鄑鄖鄔鄋鄎酮酯鉈鉒鈰鈺鉦鈳鉥鉞銃鈮鉊鉆鉭鉬鉏鉠鉧鉯鈶鉡鉰鈱鉔鉣鉐鉲鉎鉓鉌鉖鈲閟閜閞閛隒隓隑隗雎雺雽雸雵靳靷靸靲頏頍頎颬飶飹馯馲馰馵骭骫魛鳪鳭鳧麀黽僦僔僗僨僳僛僪僝僤僓僬僰僯僣僠凘劀劁勩勫匰厬嘧嘕嘌嘒嗼嘏嘜嘁嘓嘂嗺嘝嘄嗿嗹墉塼墐墘墆墁塿塴墋塺墇墑墎塶墂墈塻墔墏壾奫嫜嫮嫥嫕嫪嫚嫭嫫嫳嫢嫠嫛嫬嫞嫝嫙嫨嫟孷寠寣屣嶂嶀嵽嶆嵺嶁嵷嶊嶉嶈嵾嵼嶍嵹嵿幘幙幓廘廑廗廎廜廕廙廒廔彄彃彯徶愬愨慁慞慱慳慒慓慲慬憀慴慔慺慛慥愻慪慡慖戩戧戫搫摍摛摝摴摶摲摳摽摵摦撦摎撂摞摜摋摓摠摐摿搿摬摫摙摥摷敳斠暡暠暟朅朄朢榱榶槉榠槎榖榰榬榼榑榙榎榧榍榩榾榯榿槄榽榤槔榹槊榚槏榳榓榪榡榞槙榗榐槂榵榥槆歊歍歋殞殟殠毃毄毾滎滵滱漃漥滸漷滻漮漉潎漙漚漧漘漻漒滭漊漶潳滹滮漭潀漰漼漵滫漇漎潃漅滽滶漹漜滼漺漟漍漞漈漡熇熐熉熀熅熂熏煻熆熁熗牄牓犗犕犓獃獍獑獌瑢瑳瑱瑵瑲瑧瑮甀甂甃畽疐瘖瘈瘌瘕瘑瘊瘔皸瞁睼瞅瞂睮瞀睯睾瞃碲碪碴碭碨硾碫碞碥碠碬碢碤禘禊禋禖禕禔禓禗禈禒禐稫穊稰稯稨稦窨窫窬竮箈箜箊箑箐箖箍箌箛箎箅箘劄箙箤箂粻粿粼粺綧綷緂綣綪緁緀緅綝緎緄緆緋緌綯綹綖綼綟綦綮綩綡緉罳翢翣翥翞耤聝聜膉膆膃膇膍膌膋舕蒗蒤蒡蒟蒺蓎蓂蒬蒮蒫蒹蒴蓁蓍蒪蒚蒱蓐蒝蒧蒻蒢蒔蓇蓌蒛蒩蒯蒨蓖蒘蒶蓏蒠蓗蓔蓒蓛蒰蒑虡蜳蜣蜨蝫蝀蜮蜞蜡蜙蜛蝃蜬蝁蜾蝆蜠蜲蜪蜭蜼蜒蜺蜱蜵蝂蜦蜧蜸蜤蜚蜰蜑裷裧裱裲裺裾裮裼裶裻裰裬裫覝覡覟覞觩觫觨誫誙誋誒誏誖谽豨豩賕賏賗趖踉踂跿踍跽踊踃踇踆踅跾踀踄輐輑輎輍鄣鄜鄠鄢鄟鄝鄚鄤鄡鄛酺酲酹酳銥銤鉶銛鉺銠銔銪銍銦銚銫鉹銗鉿銣鋮銎銂銕銢鉽銈銡銊銆銌銙銧鉾銇銩銝銋鈭隞隡雿靘靽靺靾鞃鞀鞂靻鞄鞁靿韎韍頖颭颮餂餀餇馝馜駃馹馻馺駂馽駇骱髣髧鬾鬿魠魡魟鳱鳲鳵麧僿儃儰僸儆儇僶僾儋儌僽儊劋劌勱勯噈噂噌嘵噁噊噉噆噘噚噀嘳嘽嘬嘾嘸嘪嘺圚墫墝墱墠墣墯墬墥墡壿嫿嫴嫽嫷嫶嬃嫸嬂嫹嬁嬇嬅嬏屧嶙嶗嶟嶒嶢嶓嶕嶠嶜嶡嶚嶞幩幝幠幜緳廛廞廡彉徲憋憃慹憱憰憢憉憛憓憯憭憟憒憪憡憍慦憳戭摮摰撖撠撅撗撜撏撋撊撌撣撟摨撱撘敶敺敹敻斲斳暵暰暩暲暷暪暯樀樆樗槥槸樕槱槤樠槿槬槢樛樝槾樧槲槮樔槷槧橀樈槦槻樍槼槫樉樄樘樥樏槶樦樇槴樖歑殥殣殢殦氁氀毿氂潁漦潾澇濆澒澍澉澌潢潏澅潚澖潶潬澂潕潲潒潐潗澔澓潝漀潡潫潽潧澐潓澋潩潿澕潣潷潪潻熲熯熛熰熠熚熩熵熝熥熞熤熡熪熜熧熳犘犚獘獒獞獟獠獝獛獡獚獙獢璇璉璊璆璁瑽璅璈瑼瑹甈甇畾瘥瘞瘙瘝瘜瘣瘚瘨瘛皜皝皞皛瞍瞏瞉瞈磍碻磏磌磑磎磔磈磃磄磉禚禡禠禜禢禛歶稹窲窴窳箷篋箾箬篎箯箹篊箵糅糈糌糋緷緛緪緧緗緡縃緺緦緶緱緰緮緟罶羬羰羭翭翫翪翬翦翨聤聧膣膟膞膕膢膙膗舖艏艓艒艐艎艑蔤蔻蔏蔀蔩蔎蔉蔍蔟蔊蔧蔜蓻蔫蓺蔈蔌蓴蔪蓲蔕蓷蓫蓳蓼蔒蓪蓩蔖蓾蔨蔝蔮蔂蓽蔞蓶蔱蔦蓧蓨蓰蓯蓹蔘蔠蔰蔋蔙蔯虢蝖蝣蝤蝷蟡蝳蝘蝔蝛蝒蝡蝚蝑蝞蝭蝪蝐蝎蝟蝝蝯蝬蝺蝮蝜蝥蝏蝻蝵蝢蝧蝩衚褅褌褔褋褗褘褙褆褖褑褎褉覢覤覣觭觰觬諏諆誸諓諑諔諕誻諗誾諀諅諘諃誺誽諙谾豍貏賥賟賙賨賚賝賧趠趜趡趛踠踣踥踤踮踕踛踖踑踙踦踧踔踒踘踓踜踗踚輬輤輘輚輠輣輖輗遳遰遯遧遫鄯鄫鄩鄪鄲鄦鄮醅醆醊醁醂醄醀鋐鋃鋄鋀鋙銶鋏鋱鋟鋘鋩鋗鋝鋌鋯鋂鋨鋊鋈鋎鋦鋍鋕鋉鋠鋞鋧鋑鋓銵鋡鋆銴镼閬閫閮閰隤隢雓霅霈霂靚鞊鞎鞈韐韏頞頝頦頩頨頠頛頧颲餈飺餑餔餖餗餕駜駍駏駓駔駎駉駖駘駋駗駌骳髬髫髳髲髱魆魃魧魴魱魦魶魵魰魨魤魬鳼鳺鳽鳿鳷鴇鴀鳹鳻鴈鴅鴄麃黓鼏鼐儜儓儗儚儑凞匴叡噰噠噮噳噦噣噭噲噞噷圜圛壈墽壉墿墺壂墼壆嬗嬙嬛嬡嬔嬓嬐嬖嬨嬚嬠嬞寯嶬嶱嶩嶧嶵嶰嶮嶪嶨嶲嶭嶯嶴幧幨幦幯廩廧廦廨廥彋徼憝憨憖懅憴懆懁懌憺憿憸憌擗擖擐擏擉撽撉擃擛擳擙攳敿敼斢曈暾曀曊曋曏暽暻暺曌朣樴橦橉橧樲橨樾橝橭橶橛橑樨橚樻樿橁橪橤橐橏橔橯橩橠樼橞橖橕橍橎橆歕歔歖殧殪殫毈毇氄氃氆澭濋澣濇澼濎濈潞濄澽澞濊澨瀄澥澮澺澬澪濏澿澸澢濉澫濍澯澲澰燅燂熿熸燖燀燁燋燔燊燇燏熽燘熼燆燚燛犝犞獩獦獧獬獥獫獪瑿璚璠璔璒璕璡甋疀瘯瘭瘱瘽瘳瘼瘵瘲瘰皻盦瞚瞝瞡瞜瞛瞢瞣瞕瞙瞗磝磩磥磪磞磣磛磡磢磭磟磠禤穄穈穇窶窸窵窱窷篞篣篧篝篕篥篚篨篹篔篪篢篜篫篘篟糒糔糗糐糑縒縡縗縌縟縠縓縎縜縕縚縢縋縏縖縍縔縥縤罃罻罼罺羱翯耪耩聬膱膦膮膹膵膫膰膬膴膲膷膧臲艕艖艗蕖蕅蕫蕍蕓蕡蕘蕀蕆蕤蕁蕢蕄蕑蕇蕣蔾蕛蕱蕎蕮蕵蕕蕧蕠薌蕦蕝蕔蕥蕬虣虥虤螛螏螗螓螒螈螁螖螘蝹螇螣螅螐螑螝螄螔螜螚螉褞褦褰褭褮褧褱褢褩褣褯褬褟觱諠諢諲諴諵諝謔諤諟諰諈諞諡諨諿諯諻貑貒貐賵賮賱賰賳赬赮趥趧踳踾踸蹀蹅踶踼踽蹁踰踿躽輶輮輵輲輹輷輴遶遹遻邆郺鄳鄵鄶醓醐醑醍醏錧錞錈錟錆錏鍺錸錼錛錣錒錁鍆錭錎錍鋋錝鋺錥錓鋹鋷錴錂錤鋿錩錹錵錪錔錌錋鋾錉錀鋻錖閼闍閾閹閺閶閿閵閽隩雔霋霒霐鞙鞗鞔韰韸頵頯頲餤餟餧餩馞駮駬駥駤駰駣駪駩駧骹骿骴骻髶髺髹髷鬳鮀鮅鮇魼魾魻鮂鮓鮒鮐魺鮕魽鮈鴥鴗鴠鴞鴔鴩鴝鴘鴢鴐鴙鴟麈麆麇麮麭黕黖黺鼒鼽儦儥儢儤儠儩勴嚓嚌嚍嚆嚄嚃噾嚂噿嚁壖壔壏壒嬭嬥嬲嬣嬬嬧嬦嬯嬮孻寱寲嶷幬幪徾徻懃憵憼懧懠懥懤懨懞擯擩擣擫擤擨斁斀斶旚曒檍檖檁檥檉檟檛檡檞檇檓檎檕檃檨檤檑橿檦檚檅檌檒歛殭氉濌澩濴濔濣濜濭濧濦濞濲濝濢濨燡燱燨燲燤燰燢獳獮獯璗璲璫璐璪璭璱璥璯甐甑甒甏疄癃癈癉癇皤盩瞵瞫瞲瞷瞶瞴瞱瞨矰磳磽礂磻磼磲礅磹磾礄禫禨穜穛穖穘穔穚窾竀竁簅簏篲簀篿篻簎篴簋篳簂簉簃簁篸篽簆篰篱簐簊糨縭縼繂縳顈縸縪繉繀繇縩繌縰縻縶繄縺罅罿罾罽翴翲耬膻臄臌臊臅臇膼臩艛艚艜薃薀薏薧薕薠薋薣蕻薤薚薞蕷蕼薉薡蕺蕸蕗薎薖薆薍薙薝薁薢薂薈薅蕹蕶薘薐薟虨螾螪螭蟅螰螬螹螵螼螮蟉蟃蟂蟌螷螯蟄蟊螴螶螿螸螽蟞螲褵褳褼褾襁襒褷襂覭覯覮觲觳謞謘謖謑謅謋謢謏謒謕謇謍謈謆謜謓謚豏豰豲豱豯貕貔賹赯蹎蹍蹓蹐蹌蹇轃轀邅遾鄸醚醢醛醙醟醡醝醠鎡鎃鎯鍤鍖鍇鍼鍘鍜鍶鍉鍐鍑鍠鍭鎏鍌鍪鍹鍗鍕鍒鍏鍱鍷鍻鍡鍞鍣鍧鎀鍎鍙闇闀闉闃闅閷隮隰隬霠霟霘霝霙鞚鞡鞜鞞鞝韕韔韱顁顄顊顉顅顃餥餫餬餪餳餲餯餭餱餰馘馣馡騂駺駴駷駹駸駶駻駽駾駼騃骾髾髽鬁髼魈鮚鮨鮞鮛鮦鮡鮥鮤鮆鮢鮠鮯鴳鵁鵧鴶鴮鴯鴱鴸鴰鵅鵂鵃鴾鴷鵀鴽翵鴭麊麉麍麰黈黚黻黿鼤鼣鼢齔龠儱儭儮嚘嚜嚗嚚嚝嚙奰嬼屩屪巀幭幮懘懟懭懮懱懪懰懫懖懩擿攄擽擸攁攃擼斔旛曚曛曘櫅檹檽櫡櫆檺檶檷櫇檴檭歞毉氋瀇瀌瀍瀁瀅瀔瀎濿瀀濻瀦濼濷瀊爁燿燹爃燽獶璸瓀璵瓁璾璶璻瓂甔甓癜癤癙癐癓癗癚皦皽盬矂瞺磿礌礓礔礉礐礒礑禭禬穟簜簩簙簠簟簭簝簦簨簢簥簰繜繐繖繣繘繢繟繑繠繗繓羵羳翷翸聵臑臒臐艟艞薴藆藀藃藂薳薵薽藇藄薿藋藎藈藅薱薶藒蘤薸薷薾虩蟧蟦蟢蟛蟫蟪蟥蟟蟳蟤蟔蟜蟓蟭蟘蟣螤蟗蟙蠁蟴蟨蟝襓襋襏襌襆襐襑襉謪謧謣謳謰謵譇謯謼謾謱謥謷謦謶謮謤謻謽謺豂豵貙貘貗賾贄贂贀蹜蹢蹠蹗蹖蹞蹥蹧蹛蹚蹡蹝蹩蹔轆轇轈轋鄨鄺鄻鄾醨醥醧醯醪鎵鎌鎒鎷鎛鎝鎉鎧鎎鎪鎞鎦鎕鎈鎙鎟鎍鎱鎑鎲鎤鎨鎴鎣鎥闒闓闑隳雗雚巂雟雘雝霣霢霥鞬鞮鞨鞫鞤鞪鞢鞥韗韙韖韘韺顐顑顒颸饁餼餺騏騋騉騍騄騑騊騅騇騆髀髜鬈鬄鬅鬩鬵魊魌魋鯇鯆鯃鮿鯁鮵鮸鯓鮶鯄鮹鮽鵜鵓鵏鵊鵛鵋鵙鵖鵌鵗鵒鵔鵟鵘鵚麎麌黟鼁鼀鼖鼥鼫鼪鼩鼨齌齕儴儵劖勷厴嚫嚭嚦嚧嚪嚬壚壝壛夒嬽嬾嬿巃幰徿懻攇攐攍攉攌攎斄旞旝曞櫧櫠櫌櫑櫙櫋櫟櫜櫐櫫櫏櫍櫞歠殰氌瀙瀧瀠瀖瀫瀡瀢瀣瀩瀗瀤瀜瀪爌爊爇爂爅犥犦犤犣犡瓋瓅璷瓃甖癠矉矊矄矱礝礛礡礜礗礞禰穧穨簳簼簹簬簻糬糪繶繵繸繰繷繯繺繲繴繨罋罊羃羆羷翽翾聸臗臕艤艡艣藫藱藭藙藡藨藚藗藬藲藸藘藟藣藜藑藰藦藯藞藢蠀蟺蠃蟶蟷蠉蠌蠋蠆蟼蠈蟿蠊蠂襢襚襛襗襡襜襘襝襙覈覷覶觶譐譈譊譀譓譖譔譋譕譑譂譒譗豃豷豶貚贆贇贉趬趪趭趫蹭蹸蹳蹪蹯蹻軂轒轑轏轐轓辴酀鄿醰醭鏞鏇鏏鏂鏚鏐鏹鏬鏌鏙鎩鏦鏊鏔鏮鏣鏕鏄鏎鏀鏒鏧镽闚闛雡霩霫霬霨霦鞳鞷鞶韝韞韟顜顙顝顗颿颽颻颾饈饇饃馦馧騚騕騥騝騤騛騢騠騧騣騞騜騔髂鬋鬊鬎鬌鬷鯪鯫鯠鯞鯤鯦鯢鯰鯔鯗鯬鯜鯙鯥鯕鯡鯚鵷鶁鶊鶄鶈鵱鶀鵸鶆鶋鶌鵽鵫鵴鵵鵰鵩鶅鵳鵻鶂鵯鵹鵿鶇鵨麔麑黀黼鼭齀齁齍齖齗齘匷嚲嚵嚳壣孅巆巇廮廯忀忁懹攗攖攕攓旟曨曣曤櫳櫰櫪櫨櫹櫱櫮櫯瀼瀵瀯瀷瀴瀱灂瀸瀿瀺瀹灀瀻瀳灁爓爔犨獽獼璺皫皪皾盭矌矎矏矍矲礥礣礧礨礤礩禲穮穬穭竷籉籈籊籇籅糮繻繾纁纀羺翿聹臛臙舋艨艩蘢藿蘁藾蘛蘀藶蘄蘉蘅蘌藽蠙蠐蠑蠗蠓蠖襣襦覹觷譠譪譝譨譣譥譧譭趮躆躈躄轙轖轗轕轘轚邍酃酁醷醵醲醳鐋鐓鏻鐠鐏鐔鏾鐕鐐鐨鐙鐍鏵鐀鏷鐇鐎鐖鐒鏺鐉鏸鐊鏿鏼鐌鏶鐑鐆闞闠闟霮霯鞹鞻韽韾顠顢顣顟飁飂饐饎饙饌饋饓騲騴騱騬騪騶騩騮騸騭髇髊髆鬐鬒鬑鰋鰈鯷鰅鰒鯸鱀鰇鰎鰆鰗鰔鰉鶟鶙鶤鶝鶒鶘鶐鶛鶠鶔鶜鶪鶗鶡鶚鶢鶨鶞鶣鶿鶩鶖鶦鶧麙麛麚黥黤黧黦鼰鼮齛齠齞齝齙龑儺儹劘劗囃嚽嚾孈孇巋巏廱懽攛欂櫼欃櫸欀灃灄灊灈灉灅灆爝爚爙獾甗癪矐礭礱礯籔籓糲纊纇纈纋纆纍罍羻耰臝蘘蘪蘦蘟蘣蘜蘙蘧蘮蘡蘠蘩蘞蘥蠩蠝蠛蠠蠤蠜蠫衊襭襩襮襫觺譹譸譅譺譻贐贔趯躎躌轞轛轝酆酄酅醹鐿鐻鐶鐩鐽鐼鐰鐹鐪鐷鐬鑀鐱闥闤闣霵霺鞿韡顤飉飆飀饘饖騹騽驆驄驂驁騺騿髍鬕鬗鬘鬖鬺魒鰫鰝鰜鰬鰣鰨鰩鰤鰡鶷鶶鶼鷁鷇鷊鷏鶾鷅鷃鶻鶵鷎鶹鶺鶬鷈鶱鶭鷌鶳鷍鶲鹺麜黫黮黭鼛鼘鼚鼱齎齥齤龒亹囆囅囋奱孋孌巕巑廲攡攠攦攢欋欈欉氍灕灖灗灒爞爟犩獿瓘瓕瓙瓗癭皭礵禴穰穱籗籜籙籛籚糴糱纑罏羇臞艫蘴蘵蘳蘬蘲蘶蠬蠨蠦蠪蠥襱覿覾觻譾讄讂讆讅譿贕躕躔躚躒躐躖躗轠轢酇鑌鑐鑊鑋鑏鑇鑅鑈鑉鑆霿韣顪顩飋饔饛驎驓驔驌驏驈驊驉驒驐髐鬙鬫鬻魖魕鱆鱈鰿鱄鰹鰳鱁鰼鰷鰴鰲鰽鰶鷛鷒鷞鷚鷋鷐鷜鷑鷟鷩鷙鷘鷖鷵鷕鷝麶黰鼵鼳鼲齂齫龕龢儽劙壨壧奲孍巘蠯彏戁戃戄攩攥斖曫欑欒欏毊灛灚爢玂玁玃癰矔籧籦纕艬蘺虀蘹蘼蘱蘻蘾蠰蠲蠮蠳襶襴襳觾讌讎讋讈豅贙躘轤轣醼鑢鑕鑝鑗鑞韄韅頀驖驙鬞鬟鬠鱒鱘鱐鱊鱍鱋鱕鱙鱌鱎鷻鷷鷯鷣鷫鷸鷤鷶鷡鷮鷦鷲鷰鷢鷬鷴鷳鷨鷭黂黐黲黳鼆鼜鼸鼷鼶齃齏齱齰齮齯囓囍孎屭攭曭曮欓灟灡灝灠爣瓛瓥矕礸禷禶籪纗羉艭虃蠸蠷蠵衋讔讕躞躟躠躝醾醽釂鑫鑨鑩雥靆靃靇韇韥驞髕魙鱣鱧鱦鱢鱞鱠鸂鷾鸇鸃鸆鸅鸀鸁鸉鷿鷽鸄麠鼞齆齴齵齶囔攮斸欘欙欗欚灢爦犪矘矙礹籩籫糶纚纘纛纙臠臡虆虇虈襹襺襼襻觿讘讙躥躤躣鑮鑭鑯鑱鑳靉顲饟鱨鱮鱭鸋鸍鸐鸏鸒鸑麡黵鼉齇齸齻齺齹圞灦籯蠼趲躦釃鑴鑸鑶鑵驠鱴鱳鱱鱵鸔鸓黶鼊龤灨灥糷虪蠾蠽蠿讞貜躩軉靋顳顴飌饡馫驤驦驧鬤鸕鸗齈戇欞爧虌躨钂钀钁驩驨鬮鸙爩虋讟钃鱹麷癵驫鱺鸝灩灪麤齾齉龘�����������������������������������������") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_charsets.json.go b/_third_party/code.google.com/p/go-charset/data/data_charsets.json.go deleted file mode 100644 index 96ca4179..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_charsets.json.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("charsets.json", func() (io.ReadCloser, error) { - r := strings.NewReader("{\n\"8bit\": {\n\t\"Desc\": \"raw 8-bit data\",\n\t\"Class\": \"8bit\",\n\t\"Comment\": \"special class for raw 8bit data that has been converted to utf-8\"\n},\n\"big5\": {\n\t\"Desc\": \"Big 5 (HKU)\",\n\t\"Class\": \"big5\",\n\t\"Comment\": \"Traditional Chinese\"\n},\n\"euc-jp\": {\n\t\"Aliases\":[\"x-euc-jp\"],\n\t\"Desc\": \"Japanese Extended UNIX Code\",\n\t\"Class\": \"euc-jp\"\n},\n\"gb2312\": {\n\t\"Aliases\":[\"iso-ir-58\", \"chinese\", \"gb_2312-80\"],\n\t\"Desc\": \"Chinese mixed one byte\",\n\t\"Class\": \"gb2312\"\n},\n\"ibm437\": {\n\t\"Aliases\":[\"437\", \"cp437\"],\n\t\"Desc\": \"IBM PC: CP 437\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"ibm437.cp\",\n\t\"Comment\": \"originally from jhelling@cs.ruu.nl (Jeroen Hellingman)\"\n},\n\"ibm850\": {\n\t\"Aliases\":[\"850\", \"cp850\"],\n\t\"Desc\": \"IBM PS/2: CP 850\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"ibm850.cp\",\n\t\"Comment\": \"originally from jhelling@cs.ruu.nl (Jeroen Hellingman)\"\n},\n\"ibm866\": {\n\t\"Aliases\":[\"cp866\", \"866\"],\n\t\"Desc\": \"Russian MS-DOS CP 866\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"ibm866.cp\"\n},\n\"iso-8859-1\": {\n\t\"Aliases\":[\"iso-ir-100\", \"ibm819\", \"l1\", \"iso8859-1\", \"iso-latin-1\", \"iso_8859-1:1987\", \"cp819\", \"iso_8859-1\", \"iso8859_1\", \"latin1\"],\n\t\"Desc\": \"Latin-1\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-1.cp\"\n},\n\"iso-8859-10\": {\n\t\"Aliases\":[\"iso_8859-10:1992\", \"l6\", \"iso-ir-157\", \"latin6\"],\n\t\"Desc\": \"Latin-6\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-10.cp\",\n\t\"Comment\": \"originally from dkuug.dk:i18n/charmaps/ISO_8859-10:1993\"\n},\n\"iso-8859-15\": {\n\t\"Aliases\":[\"l9-iso-8859-15\", \"latin9\"],\n\t\"Desc\": \"Latin-9\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-15.cp\"\n},\n\"iso-8859-2\": {\n\t\"Aliases\":[\"iso-ir-101\", \"iso_8859-2:1987\", \"l2\", \"iso_8859-2\", \"latin2\"],\n\t\"Desc\": \"Latin-2\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-2.cp\"\n},\n\"iso-8859-3\": {\n\t\"Aliases\":[\"iso-ir-109\", \"l3\", \"iso_8859-3:1988\", \"iso_8859-3\", \"latin3\"],\n\t\"Desc\": \"Latin-3\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-3.cp\"\n},\n\"iso-8859-4\": {\n\t\"Aliases\":[\"iso-ir-110\", \"iso_8859-4:1988\", \"l4\", \"iso_8859-4\", \"latin4\"],\n\t\"Desc\": \"Latin-4\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-4.cp\"\n},\n\"iso-8859-5\": {\n\t\"Aliases\":[\"cyrillic\", \"iso_8859-5\", \"iso-ir-144\", \"iso_8859-5:1988\"],\n\t\"Desc\": \"Part 5 (Cyrillic)\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-5.cp\"\n},\n\"iso-8859-6\": {\n\t\"Aliases\":[\"ecma-114\", \"iso_8859-6:1987\", \"arabic\", \"iso_8859-6\", \"asmo-708\", \"iso-ir-127\"],\n\t\"Desc\": \"Part 6 (Arabic)\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-6.cp\"\n},\n\"iso-8859-7\": {\n\t\"Aliases\":[\"greek8\", \"elot_928\", \"ecma-118\", \"greek\", \"iso_8859-7\", \"iso_8859-7:1987\", \"iso-ir-126\"],\n\t\"Desc\": \"Part 7 (Greek)\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-7.cp\"\n},\n\"iso-8859-8\": {\n\t\"Aliases\":[\"iso_8859-8:1988\", \"hebrew\", \"iso_8859-8\", \"iso-ir-138\"],\n\t\"Desc\": \"Part 8 (Hebrew)\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-8.cp\"\n},\n\"iso-8859-9\": {\n\t\"Aliases\":[\"l5\", \"iso_8859-9:1989\", \"iso_8859-9\", \"iso-ir-148\", \"latin5\"],\n\t\"Desc\": \"Latin-5\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"iso-8859-9.cp\"\n},\n\"koi8-r\": {\n\t\"Desc\": \"KOI8-R (RFC1489)\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"koi8-r.cp\"\n},\n\"shift_jis\": {\n\t\"Aliases\":[\"sjis\", \"ms_kanji\", \"x-sjis\"],\n\t\"Desc\": \"Shift-JIS Japanese\",\n\t\"Class\": \"cp932\",\n\t\"Arg\": \"shiftjis\"\n},\n\"utf-16\": {\n\t\"Aliases\":[\"utf16\"],\n\t\"Desc\": \"Unicode UTF-16\",\n\t\"Class\": \"utf16\"\n},\n\"utf-16be\": {\n\t\"Aliases\":[\"utf16be\"],\n\t\"Desc\": \"Unicode UTF-16 big endian\",\n\t\"Class\": \"utf16\",\n\t\"Arg\": \"be\"\n},\n\"utf-16le\": {\n\t\"Aliases\":[\"utf16le\"],\n\t\"Desc\": \"Unicode UTF-16 little endian\",\n\t\"Class\": \"utf16\",\n\t\"Arg\": \"le\"\n},\n\"utf-8\": {\n\t\"Aliases\":[\"utf8\", \"ascii\", \"us-ascii\"],\n\t\"Desc\": \"Unicode UTF-8\",\n\t\"Class\": \"utf8\"\n},\n\"windows-1250\": {\n\t\"Desc\": \"MS Windows CP 1250 (Central Europe)\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"windows-1250.cp\"\n},\n\"windows-1251\": {\n\t\"Desc\": \"MS Windows CP 1251 (Cyrillic)\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"windows-1251.cp\"\n},\n\"windows-1252\": {\n\t\"Desc\": \"MS Windows CP 1252 (Latin 1)\",\n\t\"Class\": \"cp\",\n\t\"Arg\": \"windows-1252.cp\"\n},\n\"windows-31j\": {\n\t\"Aliases\":[\"cp932\"],\n\t\"Desc\": \"MS-Windows Japanese (cp932)\",\n\t\"Class\": \"cp932\",\n\t\"Arg\": \"cp932\"\n}\n}\n") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_cp932.dat.go b/_third_party/code.google.com/p/go-charset/data/data_cp932.dat.go deleted file mode 100644 index 0f8c87d7..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_cp932.dat.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("cp932.dat", func() (io.ReadCloser, error) { - r := strings.NewReader("\u3000、。,.・:;?!゛゜´`¨^ ̄_ヽヾゝゞ〃仝々〆〇ー―‐/\~∥|…‥‘’“”()〔〕[]{}〈〉《》「」『』【】+-±×�÷=≠<>≦≧∞∴♂♀°′″℃¥$¢£%#&*@§☆★○●◎◇◆□■△▲▽▼※〒→←↑↓〓�����������∈∋⊆⊇⊂⊃∪∩��������∧∨¬⇒⇔∀∃�����������∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬�������ʼn♯♭♪†‡¶����◯���������������0123456789�������ABCDEFGHIJKLMNOPQRSTUVWXYZ�������abcdefghijklmnopqrstuvwxyz����ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん�����������ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミ�ムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ��������ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ��������αβγδεζηθικλμνξοπρστυφχψω��������������������������������������АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ���������������абвгдеёжзийклмн�опрстуфхцчшщъыьэюя�������������─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂��������������������������������������������������������������①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ�㍉㌔㌢㍍㌘㌧㌃㌶㍑㍗㌍㌦㌣㌫㍊㌻㎜㎝㎞㎎㎏㏄㎡��������㍻�〝〟№㏍℡㊤㊥㊦㊧㊨㈱㈲㈹㍾㍽㍼≒≡∫∮∑√⊥∠∟⊿∵∩∪�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������亜唖娃阿哀愛挨姶逢葵茜穐悪握渥旭葦芦鯵梓圧斡扱宛姐虻飴絢綾鮎或粟袷安庵按暗案闇鞍杏以伊位依偉囲夷委威尉惟意慰易椅為畏異移維緯胃萎衣謂違遺医井亥域育郁磯一壱溢逸稲茨芋鰯允印咽員因姻引飲淫胤蔭院陰隠韻吋右宇烏羽迂雨卯鵜窺丑碓臼渦嘘唄欝蔚鰻姥厩浦瓜閏噂云運雲荏餌叡営嬰影映曳栄永泳洩瑛盈穎頴英衛詠鋭液疫益駅悦謁越閲榎厭円�園堰奄宴延怨掩援沿演炎焔煙燕猿縁艶苑薗遠鉛鴛塩於汚甥凹央奥往応押旺横欧殴王翁襖鴬鴎黄岡沖荻億屋憶臆桶牡乙俺卸恩温穏音下化仮何伽価佳加可嘉夏嫁家寡科暇果架歌河火珂禍禾稼箇花苛茄荷華菓蝦課嘩貨迦過霞蚊俄峨我牙画臥芽蛾賀雅餓駕介会解回塊壊廻快怪悔恢懐戒拐改魁晦械海灰界皆絵芥蟹開階貝凱劾外咳害崖慨概涯碍蓋街該鎧骸浬馨蛙垣柿蛎鈎劃嚇各廓拡撹格核殻獲確穫覚角赫較郭閣隔革学岳楽額顎掛笠樫�橿梶鰍潟割喝恰括活渇滑葛褐轄且鰹叶椛樺鞄株兜竃蒲釜鎌噛鴨栢茅萱粥刈苅瓦乾侃冠寒刊勘勧巻喚堪姦完官寛干幹患感慣憾換敢柑桓棺款歓汗漢澗潅環甘監看竿管簡緩缶翰肝艦莞観諌貫還鑑間閑関陥韓館舘丸含岸巌玩癌眼岩翫贋雁頑顔願企伎危喜器基奇嬉寄岐希幾忌揮机旗既期棋棄機帰毅気汽畿祈季稀紀徽規記貴起軌輝飢騎鬼亀偽儀妓宜戯技擬欺犠疑祇義蟻誼議掬菊鞠吉吃喫桔橘詰砧杵黍却客脚虐逆丘久仇休及吸宮弓急救�朽求汲泣灸球究窮笈級糾給旧牛去居巨拒拠挙渠虚許距鋸漁禦魚亨享京供侠僑兇競共凶協匡卿叫喬境峡強彊怯恐恭挟教橋況狂狭矯胸脅興蕎郷鏡響饗驚仰凝尭暁業局曲極玉桐粁僅勤均巾錦斤欣欽琴禁禽筋緊芹菌衿襟謹近金吟銀九倶句区狗玖矩苦躯駆駈駒具愚虞喰空偶寓遇隅串櫛釧屑屈掘窟沓靴轡窪熊隈粂栗繰桑鍬勲君薫訓群軍郡卦袈祁係傾刑兄啓圭珪型契形径恵慶慧憩掲携敬景桂渓畦稽系経継繋罫茎荊蛍計詣警軽頚鶏芸迎鯨�劇戟撃激隙桁傑欠決潔穴結血訣月件倹倦健兼券剣喧圏堅嫌建憲懸拳捲検権牽犬献研硯絹県肩見謙賢軒遣鍵険顕験鹸元原厳幻弦減源玄現絃舷言諺限乎個古呼固姑孤己庫弧戸故枯湖狐糊袴股胡菰虎誇跨鈷雇顧鼓五互伍午呉吾娯後御悟梧檎瑚碁語誤護醐乞鯉交佼侯候倖光公功効勾厚口向后喉坑垢好孔孝宏工巧巷幸広庚康弘恒慌抗拘控攻昂晃更杭校梗構江洪浩港溝甲皇硬稿糠紅紘絞綱耕考肯肱腔膏航荒行衡講貢購郊酵鉱砿鋼閤降�項香高鴻剛劫号合壕拷濠豪轟麹克刻告国穀酷鵠黒獄漉腰甑忽惚骨狛込此頃今困坤墾婚恨懇昏昆根梱混痕紺艮魂些佐叉唆嵯左差査沙瑳砂詐鎖裟坐座挫債催再最哉塞妻宰彩才採栽歳済災采犀砕砦祭斎細菜裁載際剤在材罪財冴坂阪堺榊肴咲崎埼碕鷺作削咋搾昨朔柵窄策索錯桜鮭笹匙冊刷察拶撮擦札殺薩雑皐鯖捌錆鮫皿晒三傘参山惨撒散桟燦珊産算纂蚕讃賛酸餐斬暫残仕仔伺使刺司史嗣四士始姉姿子屍市師志思指支孜斯施旨枝止�死氏獅祉私糸紙紫肢脂至視詞詩試誌諮資賜雌飼歯事似侍児字寺慈持時次滋治爾璽痔磁示而耳自蒔辞汐鹿式識鴫竺軸宍雫七叱執失嫉室悉湿漆疾質実蔀篠偲柴芝屡蕊縞舎写射捨赦斜煮社紗者謝車遮蛇邪借勺尺杓灼爵酌釈錫若寂弱惹主取守手朱殊狩珠種腫趣酒首儒受呪寿授樹綬需囚収周宗就州修愁拾洲秀秋終繍習臭舟蒐衆襲讐蹴輯週酋酬集醜什住充十従戎柔汁渋獣縦重銃叔夙宿淑祝縮粛塾熟出術述俊峻春瞬竣舜駿准循旬楯殉淳�準潤盾純巡遵醇順処初所暑曙渚庶緒署書薯藷諸助叙女序徐恕鋤除傷償勝匠升召哨商唱嘗奨妾娼宵将小少尚庄床廠彰承抄招掌捷昇昌昭晶松梢樟樵沼消渉湘焼焦照症省硝礁祥称章笑粧紹肖菖蒋蕉衝裳訟証詔詳象賞醤鉦鍾鐘障鞘上丈丞乗冗剰城場壌嬢常情擾条杖浄状畳穣蒸譲醸錠嘱埴飾拭植殖燭織職色触食蝕辱尻伸信侵唇娠寝審心慎振新晋森榛浸深申疹真神秦紳臣芯薪親診身辛進針震人仁刃塵壬尋甚尽腎訊迅陣靭笥諏須酢図厨�逗吹垂帥推水炊睡粋翠衰遂酔錐錘随瑞髄崇嵩数枢趨雛据杉椙菅頗雀裾澄摺寸世瀬畝是凄制勢姓征性成政整星晴棲栖正清牲生盛精聖声製西誠誓請逝醒青静斉税脆隻席惜戚斥昔析石積籍績脊責赤跡蹟碩切拙接摂折設窃節説雪絶舌蝉仙先千占宣専尖川戦扇撰栓栴泉浅洗染潜煎煽旋穿箭線繊羨腺舛船薦詮賎践選遷銭銑閃鮮前善漸然全禅繕膳糎噌塑岨措曾曽楚狙疏疎礎祖租粗素組蘇訴阻遡鼠僧創双叢倉喪壮奏爽宋層匝惣想捜掃挿掻�操早曹巣槍槽漕燥争痩相窓糟総綜聡草荘葬蒼藻装走送遭鎗霜騒像増憎臓蔵贈造促側則即息捉束測足速俗属賊族続卒袖其揃存孫尊損村遜他多太汰詑唾堕妥惰打柁舵楕陀駄騨体堆対耐岱帯待怠態戴替泰滞胎腿苔袋貸退逮隊黛鯛代台大第醍題鷹滝瀧卓啄宅托択拓沢濯琢託鐸濁諾茸凧蛸只叩但達辰奪脱巽竪辿棚谷狸鱈樽誰丹単嘆坦担探旦歎淡湛炭短端箪綻耽胆蛋誕鍛団壇弾断暖檀段男談値知地弛恥智池痴稚置致蜘遅馳築畜竹筑蓄�逐秩窒茶嫡着中仲宙忠抽昼柱注虫衷註酎鋳駐樗瀦猪苧著貯丁兆凋喋寵帖帳庁弔張彫徴懲挑暢朝潮牒町眺聴脹腸蝶調諜超跳銚長頂鳥勅捗直朕沈珍賃鎮陳津墜椎槌追鎚痛通塚栂掴槻佃漬柘辻蔦綴鍔椿潰坪壷嬬紬爪吊釣鶴亭低停偵剃貞呈堤定帝底庭廷弟悌抵挺提梯汀碇禎程締艇訂諦蹄逓邸鄭釘鼎泥摘擢敵滴的笛適鏑溺哲徹撤轍迭鉄典填天展店添纏甜貼転顛点伝殿澱田電兎吐堵塗妬屠徒斗杜渡登菟賭途都鍍砥砺努度土奴怒倒党冬�凍刀唐塔塘套宕島嶋悼投搭東桃梼棟盗淘湯涛灯燈当痘祷等答筒糖統到董蕩藤討謄豆踏逃透鐙陶頭騰闘働動同堂導憧撞洞瞳童胴萄道銅峠鴇匿得徳涜特督禿篤毒独読栃橡凸突椴届鳶苫寅酉瀞噸屯惇敦沌豚遁頓呑曇鈍奈那内乍凪薙謎灘捺鍋楢馴縄畷南楠軟難汝二尼弐迩匂賑肉虹廿日乳入如尿韮任妊忍認濡禰祢寧葱猫熱年念捻撚燃粘乃廼之埜嚢悩濃納能脳膿農覗蚤巴把播覇杷波派琶破婆罵芭馬俳廃拝排敗杯盃牌背肺輩配倍培媒梅�楳煤狽買売賠陪這蝿秤矧萩伯剥博拍柏泊白箔粕舶薄迫曝漠爆縛莫駁麦函箱硲箸肇筈櫨幡肌畑畠八鉢溌発醗髪伐罰抜筏閥鳩噺塙蛤隼伴判半反叛帆搬斑板氾汎版犯班畔繁般藩販範釆煩頒飯挽晩番盤磐蕃蛮匪卑否妃庇彼悲扉批披斐比泌疲皮碑秘緋罷肥被誹費避非飛樋簸備尾微枇毘琵眉美鼻柊稗匹疋髭彦膝菱肘弼必畢筆逼桧姫媛紐百謬俵彪標氷漂瓢票表評豹廟描病秒苗錨鋲蒜蛭鰭品彬斌浜瀕貧賓頻敏瓶不付埠夫婦富冨布府怖扶敷�斧普浮父符腐膚芙譜負賦赴阜附侮撫武舞葡蕪部封楓風葺蕗伏副復幅服福腹複覆淵弗払沸仏物鮒分吻噴墳憤扮焚奮粉糞紛雰文聞丙併兵塀幣平弊柄並蔽閉陛米頁僻壁癖碧別瞥蔑箆偏変片篇編辺返遍便勉娩弁鞭保舗鋪圃捕歩甫補輔穂募墓慕戊暮母簿菩倣俸包呆報奉宝峰峯崩庖抱捧放方朋法泡烹砲縫胞芳萌蓬蜂褒訪豊邦鋒飽鳳鵬乏亡傍剖坊妨帽忘忙房暴望某棒冒紡肪膨謀貌貿鉾防吠頬北僕卜墨撲朴牧睦穆釦勃没殆堀幌奔本翻凡盆�摩磨魔麻埋妹昧枚毎哩槙幕膜枕鮪柾鱒桝亦俣又抹末沫迄侭繭麿万慢満漫蔓味未魅巳箕岬密蜜湊蓑稔脈妙粍民眠務夢無牟矛霧鵡椋婿娘冥名命明盟迷銘鳴姪牝滅免棉綿緬面麺摸模茂妄孟毛猛盲網耗蒙儲木黙目杢勿餅尤戻籾貰問悶紋門匁也冶夜爺耶野弥矢厄役約薬訳躍靖柳薮鑓愉愈油癒諭輸唯佑優勇友宥幽悠憂揖有柚湧涌猶猷由祐裕誘遊邑郵雄融夕予余与誉輿預傭幼妖容庸揚揺擁曜楊様洋溶熔用窯羊耀葉蓉要謡踊遥陽養慾抑欲�沃浴翌翼淀羅螺裸来莱頼雷洛絡落酪乱卵嵐欄濫藍蘭覧利吏履李梨理璃痢裏裡里離陸律率立葎掠略劉流溜琉留硫粒隆竜龍侶慮旅虜了亮僚両凌寮料梁涼猟療瞭稜糧良諒遼量陵領力緑倫厘林淋燐琳臨輪隣鱗麟瑠塁涙累類令伶例冷励嶺怜玲礼苓鈴隷零霊麗齢暦歴列劣烈裂廉恋憐漣煉簾練聯蓮連錬呂魯櫓炉賂路露労婁廊弄朗楼榔浪漏牢狼篭老聾蝋郎六麓禄肋録論倭和話歪賄脇惑枠鷲亙亘鰐詫藁蕨椀湾碗腕��������������������������������������������弌丐丕个丱丶丼丿乂乖乘亂亅豫亊舒弍于亞亟亠亢亰亳亶从仍仄仆仂仗仞仭仟价伉佚估佛佝佗佇佶侈侏侘佻佩佰侑佯來侖儘俔俟俎俘俛俑俚俐俤俥倚倨倔倪倥倅伜俶倡倩倬俾俯們倆偃假會偕偐偈做偖偬偸傀傚傅傴傲僉僊傳僂僖僞僥僭僣僮價僵儉儁儂儖儕儔儚儡儺儷儼儻儿兀兒兌兔兢竸兩兪兮冀冂囘册冉冏冑冓冕冖冤冦冢冩冪冫决冱冲冰况冽凅凉凛几處凩凭�凰凵凾刄刋刔刎刧刪刮刳刹剏剄剋剌剞剔剪剴剩剳剿剽劍劔劒剱劈劑辨辧劬劭劼劵勁勍勗勞勣勦飭勠勳勵勸勹匆匈甸匍匐匏匕匚匣匯匱匳匸區卆卅丗卉卍凖卞卩卮夘卻卷厂厖厠厦厥厮厰厶參簒雙叟曼燮叮叨叭叺吁吽呀听吭吼吮吶吩吝呎咏呵咎呟呱呷呰咒呻咀呶咄咐咆哇咢咸咥咬哄哈咨咫哂咤咾咼哘哥哦唏唔哽哮哭哺哢唹啀啣啌售啜啅啖啗唸唳啝喙喀咯喊喟啻啾喘喞單啼喃喩喇喨嗚嗅嗟嗄嗜嗤嗔嘔嗷嘖嗾嗽嘛嗹噎噐營嘴嘶嘲嘸�噫噤嘯噬噪嚆嚀嚊嚠嚔嚏嚥嚮嚶嚴囂嚼囁囃囀囈囎囑囓囗囮囹圀囿圄圉圈國圍圓團圖嗇圜圦圷圸坎圻址坏坩埀垈坡坿垉垓垠垳垤垪垰埃埆埔埒埓堊埖埣堋堙堝塲堡塢塋塰毀塒堽塹墅墹墟墫墺壞墻墸墮壅壓壑壗壙壘壥壜壤壟壯壺壹壻壼壽夂夊夐夛梦夥夬夭夲夸夾竒奕奐奎奚奘奢奠奧奬奩奸妁妝佞侫妣妲姆姨姜妍姙姚娥娟娑娜娉娚婀婬婉娵娶婢婪媚媼媾嫋嫂媽嫣嫗嫦嫩嫖嫺嫻嬌嬋嬖嬲嫐嬪嬶嬾孃孅孀孑孕孚孛孥孩孰孳孵學斈孺宀�它宦宸寃寇寉寔寐寤實寢寞寥寫寰寶寳尅將專對尓尠尢尨尸尹屁屆屎屓屐屏孱屬屮乢屶屹岌岑岔妛岫岻岶岼岷峅岾峇峙峩峽峺峭嶌峪崋崕崗嵜崟崛崑崔崢崚崙崘嵌嵒嵎嵋嵬嵳嵶嶇嶄嶂嶢嶝嶬嶮嶽嶐嶷嶼巉巍巓巒巖巛巫已巵帋帚帙帑帛帶帷幄幃幀幎幗幔幟幢幤幇幵并幺麼广庠廁廂廈廐廏廖廣廝廚廛廢廡廨廩廬廱廳廰廴廸廾弃弉彝彜弋弑弖弩弭弸彁彈彌彎弯彑彖彗彙彡彭彳彷徃徂彿徊很徑徇從徙徘徠徨徭徼忖忻忤忸忱忝悳忿怡恠�怙怐怩怎怱怛怕怫怦怏怺恚恁恪恷恟恊恆恍恣恃恤恂恬恫恙悁悍惧悃悚悄悛悖悗悒悧悋惡悸惠惓悴忰悽惆悵惘慍愕愆惶惷愀惴惺愃愡惻惱愍愎慇愾愨愧慊愿愼愬愴愽慂慄慳慷慘慙慚慫慴慯慥慱慟慝慓慵憙憖憇憬憔憚憊憑憫憮懌懊應懷懈懃懆憺懋罹懍懦懣懶懺懴懿懽懼懾戀戈戉戍戌戔戛戞戡截戮戰戲戳扁扎扞扣扛扠扨扼抂抉找抒抓抖拔抃抔拗拑抻拏拿拆擔拈拜拌拊拂拇抛拉挌拮拱挧挂挈拯拵捐挾捍搜捏掖掎掀掫捶掣掏掉掟掵捫�捩掾揩揀揆揣揉插揶揄搖搴搆搓搦搶攝搗搨搏摧摯摶摎攪撕撓撥撩撈撼據擒擅擇撻擘擂擱擧舉擠擡抬擣擯攬擶擴擲擺攀擽攘攜攅攤攣攫攴攵攷收攸畋效敖敕敍敘敞敝敲數斂斃變斛斟斫斷旃旆旁旄旌旒旛旙无旡旱杲昊昃旻杳昵昶昴昜晏晄晉晁晞晝晤晧晨晟晢晰暃暈暎暉暄暘暝曁暹曉暾暼曄暸曖曚曠昿曦曩曰曵曷朏朖朞朦朧霸朮朿朶杁朸朷杆杞杠杙杣杤枉杰枩杼杪枌枋枦枡枅枷柯枴柬枳柩枸柤柞柝柢柮枹柎柆柧檜栞框栩桀桍栲桎�梳栫桙档桷桿梟梏梭梔條梛梃檮梹桴梵梠梺椏梍桾椁棊椈棘椢椦棡椌棍棔棧棕椶椒椄棗棣椥棹棠棯椨椪椚椣椡棆楹楷楜楸楫楔楾楮椹楴椽楙椰楡楞楝榁楪榲榮槐榿槁槓榾槎寨槊槝榻槃榧樮榑榠榜榕榴槞槨樂樛槿權槹槲槧樅榱樞槭樔槫樊樒櫁樣樓橄樌橲樶橸橇橢橙橦橈樸樢檐檍檠檄檢檣檗蘗檻櫃櫂檸檳檬櫞櫑櫟檪櫚櫪櫻欅蘖櫺欒欖鬱欟欸欷盜欹飮歇歃歉歐歙歔歛歟歡歸歹歿殀殄殃殍殘殕殞殤殪殫殯殲殱殳殷殼毆毋毓毟毬毫毳毯�麾氈氓气氛氤氣汞汕汢汪沂沍沚沁沛汾汨汳沒沐泄泱泓沽泗泅泝沮沱沾沺泛泯泙泪洟衍洶洫洽洸洙洵洳洒洌浣涓浤浚浹浙涎涕濤涅淹渕渊涵淇淦涸淆淬淞淌淨淒淅淺淙淤淕淪淮渭湮渮渙湲湟渾渣湫渫湶湍渟湃渺湎渤滿渝游溂溪溘滉溷滓溽溯滄溲滔滕溏溥滂溟潁漑灌滬滸滾漿滲漱滯漲滌漾漓滷澆潺潸澁澀潯潛濳潭澂潼潘澎澑濂潦澳澣澡澤澹濆澪濟濕濬濔濘濱濮濛瀉瀋濺瀑瀁瀏濾瀛瀚潴瀝瀘瀟瀰瀾瀲灑灣炙炒炯烱炬炸炳炮烟烋烝�烙焉烽焜焙煥煕熈煦煢煌煖煬熏燻熄熕熨熬燗熹熾燒燉燔燎燠燬燧燵燼燹燿爍爐爛爨爭爬爰爲爻爼爿牀牆牋牘牴牾犂犁犇犒犖犢犧犹犲狃狆狄狎狒狢狠狡狹狷倏猗猊猜猖猝猴猯猩猥猾獎獏默獗獪獨獰獸獵獻獺珈玳珎玻珀珥珮珞璢琅瑯琥珸琲琺瑕琿瑟瑙瑁瑜瑩瑰瑣瑪瑶瑾璋璞璧瓊瓏瓔珱瓠瓣瓧瓩瓮瓲瓰瓱瓸瓷甄甃甅甌甎甍甕甓甞甦甬甼畄畍畊畉畛畆畚畩畤畧畫畭畸當疆疇畴疊疉疂疔疚疝疥疣痂疳痃疵疽疸疼疱痍痊痒痙痣痞痾痿�痼瘁痰痺痲痳瘋瘍瘉瘟瘧瘠瘡瘢瘤瘴瘰瘻癇癈癆癜癘癡癢癨癩癪癧癬癰癲癶癸發皀皃皈皋皎皖皓皙皚皰皴皸皹皺盂盍盖盒盞盡盥盧盪蘯盻眈眇眄眩眤眞眥眦眛眷眸睇睚睨睫睛睥睿睾睹瞎瞋瞑瞠瞞瞰瞶瞹瞿瞼瞽瞻矇矍矗矚矜矣矮矼砌砒礦砠礪硅碎硴碆硼碚碌碣碵碪碯磑磆磋磔碾碼磅磊磬磧磚磽磴礇礒礑礙礬礫祀祠祗祟祚祕祓祺祿禊禝禧齋禪禮禳禹禺秉秕秧秬秡秣稈稍稘稙稠稟禀稱稻稾稷穃穗穉穡穢穩龝穰穹穽窈窗窕窘窖窩竈窰�窶竅竄窿邃竇竊竍竏竕竓站竚竝竡竢竦竭竰笂笏笊笆笳笘笙笞笵笨笶筐筺笄筍笋筌筅筵筥筴筧筰筱筬筮箝箘箟箍箜箚箋箒箏筝箙篋篁篌篏箴篆篝篩簑簔篦篥籠簀簇簓篳篷簗簍篶簣簧簪簟簷簫簽籌籃籔籏籀籐籘籟籤籖籥籬籵粃粐粤粭粢粫粡粨粳粲粱粮粹粽糀糅糂糘糒糜糢鬻糯糲糴糶糺紆紂紜紕紊絅絋紮紲紿紵絆絳絖絎絲絨絮絏絣經綉絛綏絽綛綺綮綣綵緇綽綫總綢綯緜綸綟綰緘緝緤緞緻緲緡縅縊縣縡縒縱縟縉縋縢繆繦縻縵縹繃縷�縲縺繧繝繖繞繙繚繹繪繩繼繻纃緕繽辮繿纈纉續纒纐纓纔纖纎纛纜缸缺罅罌罍罎罐网罕罔罘罟罠罨罩罧罸羂羆羃羈羇羌羔羞羝羚羣羯羲羹羮羶羸譱翅翆翊翕翔翡翦翩翳翹飜耆耄耋耒耘耙耜耡耨耿耻聊聆聒聘聚聟聢聨聳聲聰聶聹聽聿肄肆肅肛肓肚肭冐肬胛胥胙胝胄胚胖脉胯胱脛脩脣脯腋隋腆脾腓腑胼腱腮腥腦腴膃膈膊膀膂膠膕膤膣腟膓膩膰膵膾膸膽臀臂膺臉臍臑臙臘臈臚臟臠臧臺臻臾舁舂舅與舊舍舐舖舩舫舸舳艀艙艘艝艚艟艤�艢艨艪艫舮艱艷艸艾芍芒芫芟芻芬苡苣苟苒苴苳苺莓范苻苹苞茆苜茉苙茵茴茖茲茱荀茹荐荅茯茫茗茘莅莚莪莟莢莖茣莎莇莊荼莵荳荵莠莉莨菴萓菫菎菽萃菘萋菁菷萇菠菲萍萢萠莽萸蔆菻葭萪萼蕚蒄葷葫蒭葮蒂葩葆萬葯葹萵蓊葢蒹蒿蒟蓙蓍蒻蓚蓐蓁蓆蓖蒡蔡蓿蓴蔗蔘蔬蔟蔕蔔蓼蕀蕣蕘蕈蕁蘂蕋蕕薀薤薈薑薊薨蕭薔薛藪薇薜蕷蕾薐藉薺藏薹藐藕藝藥藜藹蘊蘓蘋藾藺蘆蘢蘚蘰蘿虍乕虔號虧虱蚓蚣蚩蚪蚋蚌蚶蚯蛄蛆蚰蛉蠣蚫蛔蛞蛩蛬�蛟蛛蛯蜒蜆蜈蜀蜃蛻蜑蜉蜍蛹蜊蜴蜿蜷蜻蜥蜩蜚蝠蝟蝸蝌蝎蝴蝗蝨蝮蝙蝓蝣蝪蠅螢螟螂螯蟋螽蟀蟐雖螫蟄螳蟇蟆螻蟯蟲蟠蠏蠍蟾蟶蟷蠎蟒蠑蠖蠕蠢蠡蠱蠶蠹蠧蠻衄衂衒衙衞衢衫袁衾袞衵衽袵衲袂袗袒袮袙袢袍袤袰袿袱裃裄裔裘裙裝裹褂裼裴裨裲褄褌褊褓襃褞褥褪褫襁襄褻褶褸襌褝襠襞襦襤襭襪襯襴襷襾覃覈覊覓覘覡覩覦覬覯覲覺覽覿觀觚觜觝觧觴觸訃訖訐訌訛訝訥訶詁詛詒詆詈詼詭詬詢誅誂誄誨誡誑誥誦誚誣諄諍諂諚諫諳諧�諤諱謔諠諢諷諞諛謌謇謚諡謖謐謗謠謳鞫謦謫謾謨譁譌譏譎證譖譛譚譫譟譬譯譴譽讀讌讎讒讓讖讙讚谺豁谿豈豌豎豐豕豢豬豸豺貂貉貅貊貍貎貔豼貘戝貭貪貽貲貳貮貶賈賁賤賣賚賽賺賻贄贅贊贇贏贍贐齎贓賍贔贖赧赭赱赳趁趙跂趾趺跏跚跖跌跛跋跪跫跟跣跼踈踉跿踝踞踐踟蹂踵踰踴蹊蹇蹉蹌蹐蹈蹙蹤蹠踪蹣蹕蹶蹲蹼躁躇躅躄躋躊躓躑躔躙躪躡躬躰軆躱躾軅軈軋軛軣軼軻軫軾輊輅輕輒輙輓輜輟輛輌輦輳輻輹轅轂輾轌轉轆轎轗轜�轢轣轤辜辟辣辭辯辷迚迥迢迪迯邇迴逅迹迺逑逕逡逍逞逖逋逧逶逵逹迸遏遐遑遒逎遉逾遖遘遞遨遯遶隨遲邂遽邁邀邊邉邏邨邯邱邵郢郤扈郛鄂鄒鄙鄲鄰酊酖酘酣酥酩酳酲醋醉醂醢醫醯醪醵醴醺釀釁釉釋釐釖釟釡釛釼釵釶鈞釿鈔鈬鈕鈑鉞鉗鉅鉉鉤鉈銕鈿鉋鉐銜銖銓銛鉚鋏銹銷鋩錏鋺鍄錮錙錢錚錣錺錵錻鍜鍠鍼鍮鍖鎰鎬鎭鎔鎹鏖鏗鏨鏥鏘鏃鏝鏐鏈鏤鐚鐔鐓鐃鐇鐐鐶鐫鐵鐡鐺鑁鑒鑄鑛鑠鑢鑞鑪鈩鑰鑵鑷鑽鑚鑼鑾钁鑿閂閇閊閔閖閘閙�閠閨閧閭閼閻閹閾闊濶闃闍闌闕闔闖關闡闥闢阡阨阮阯陂陌陏陋陷陜陞陝陟陦陲陬隍隘隕隗險隧隱隲隰隴隶隸隹雎雋雉雍襍雜霍雕雹霄霆霈霓霎霑霏霖霙霤霪霰霹霽霾靄靆靈靂靉靜靠靤靦靨勒靫靱靹鞅靼鞁靺鞆鞋鞏鞐鞜鞨鞦鞣鞳鞴韃韆韈韋韜韭齏韲竟韶韵頏頌頸頤頡頷頽顆顏顋顫顯顰顱顴顳颪颯颱颶飄飃飆飩飫餃餉餒餔餘餡餝餞餤餠餬餮餽餾饂饉饅饐饋饑饒饌饕馗馘馥馭馮馼駟駛駝駘駑駭駮駱駲駻駸騁騏騅駢騙騫騷驅驂驀驃�騾驕驍驛驗驟驢驥驤驩驫驪骭骰骼髀髏髑髓體髞髟髢髣髦髯髫髮髴髱髷髻鬆鬘鬚鬟鬢鬣鬥鬧鬨鬩鬪鬮鬯鬲魄魃魏魍魎魑魘魴鮓鮃鮑鮖鮗鮟鮠鮨鮴鯀鯊鮹鯆鯏鯑鯒鯣鯢鯤鯔鯡鰺鯲鯱鯰鰕鰔鰉鰓鰌鰆鰈鰒鰊鰄鰮鰛鰥鰤鰡鰰鱇鰲鱆鰾鱚鱠鱧鱶鱸鳧鳬鳰鴉鴈鳫鴃鴆鴪鴦鶯鴣鴟鵄鴕鴒鵁鴿鴾鵆鵈鵝鵞鵤鵑鵐鵙鵲鶉鶇鶫鵯鵺鶚鶤鶩鶲鷄鷁鶻鶸鶺鷆鷏鷂鷙鷓鷸鷦鷭鷯鷽鸚鸛鸞鹵鹹鹽麁麈麋麌麒麕麑麝麥麩麸麪麭靡黌黎黏黐黔黜點黝黠黥黨黯�黴黶黷黹黻黼黽鼇鼈皷鼕鼡鼬鼾齊齒齔齣齟齠齡齦齧齬齪齷齲齶龕龜龠堯槇遙瑤凜熙����������������������������������������������������������������������������������������纊褜鍈銈蓜俉炻昱棈鋹曻彅丨仡仼伀伃伹佖侒侊侚侔俍偀倢俿倞偆偰偂傔僴僘兊兤冝冾凬刕劜劦勀勛匀匇匤卲厓厲叝﨎咜咊咩哿喆坙坥垬埈埇﨏�塚增墲夋奓奛奝奣妤妺孖寀甯寘寬尞岦岺峵崧嵓﨑嵂嵭嶸嶹巐弡弴彧德忞恝悅悊惞惕愠惲愑愷愰憘戓抦揵摠撝擎敎昀昕昻昉昮昞昤晥晗晙晴晳暙暠暲暿曺朎朗杦枻桒柀栁桄棏﨓楨﨔榘槢樰橫橆橳橾櫢櫤毖氿汜沆汯泚洄涇浯涖涬淏淸淲淼渹湜渧渼溿澈澵濵瀅瀇瀨炅炫焏焄煜煆煇凞燁燾犱犾猤猪獷玽珉珖珣珒琇珵琦琪琩琮瑢璉璟甁畯皂皜皞皛皦益睆劯砡硎硤硺礰礼神祥禔福禛竑竧靖竫箞精絈絜綷綠緖繒罇羡羽茁荢荿菇菶葈蒴蕓蕙�蕫﨟薰蘒﨡蠇裵訒訷詹誧誾諟諸諶譓譿賰賴贒赶﨣軏﨤逸遧郞都鄕鄧釚釗釞釭釮釤釥鈆鈐鈊鈺鉀鈼鉎鉙鉑鈹鉧銧鉷鉸鋧鋗鋙鋐﨧鋕鋠鋓錥錡鋻﨨錞鋿錝錂鍰鍗鎤鏆鏞鏸鐱鑅鑈閒隆﨩隝隯霳霻靃靍靏靑靕顗顥飯飼餧館馞驎髙髜魵魲鮏鮱鮻鰀鵰鵫鶴鸙黑��ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ¬¦'"ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ¬¦'"㈱№℡∵纊褜鍈銈蓜俉炻昱棈鋹曻彅丨仡仼伀伃伹佖侒侊侚侔俍偀倢俿倞偆偰偂傔僴僘兊�兤冝冾凬刕劜劦勀勛匀匇匤卲厓厲叝﨎咜咊咩哿喆坙坥垬埈埇﨏塚增墲夋奓奛奝奣妤妺孖寀甯寘寬尞岦岺峵崧嵓﨑嵂嵭嶸嶹巐弡弴彧德忞恝悅悊惞惕愠惲愑愷愰憘戓抦揵摠撝擎敎昀昕昻昉昮昞昤晥晗晙晴晳暙暠暲暿曺朎朗杦枻桒柀栁桄棏﨓楨﨔榘槢樰橫橆橳橾櫢櫤毖氿汜沆汯泚洄涇浯涖涬淏淸淲淼渹湜渧渼溿澈澵濵瀅瀇瀨炅炫焏焄煜煆煇凞燁燾犱犾猤猪獷玽珉珖珣珒琇珵琦琪琩琮瑢璉璟甁畯皂皜皞皛皦益睆劯砡硎硤硺礰礼神�祥禔福禛竑竧靖竫箞精絈絜綷綠緖繒罇羡羽茁荢荿菇菶葈蒴蕓蕙蕫﨟薰蘒﨡蠇裵訒訷詹誧誾諟諸諶譓譿賰賴贒赶﨣軏﨤逸遧郞都鄕鄧釚釗釞釭釮釤釥鈆鈐鈊鈺鉀鈼鉎鉙鉑鈹鉧銧鉷鉸鋧鋗鋙鋐﨧鋕鋠鋓錥錡鋻﨨錞鋿錝錂鍰鍗鎤鏆鏞鏸鐱鑅鑈閒隆﨩隝隯霳霻靃靍靏靑靕顗顥飯飼餧館馞驎髙髜魵魲鮏鮱鮻鰀鵰鵫鶴鸙黑���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_ibm437.cp.go b/_third_party/code.google.com/p/go-charset/data/data_ibm437.cp.go deleted file mode 100644 index a1f44c97..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_ibm437.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("ibm437.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007fÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞∅∈∩≡±≥≤⌠⌡÷≈°•·√ⁿ²∎\u00a0") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_ibm850.cp.go b/_third_party/code.google.com/p/go-charset/data/data_ibm850.cp.go deleted file mode 100644 index 51853b2b..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_ibm850.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("ibm850.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007fÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´\u00ad±‗¾¶§÷¸°¨·¹³²∎\u00a0") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_ibm866.cp.go b/_third_party/code.google.com/p/go-charset/data/data_ibm866.cp.go deleted file mode 100644 index 6f3d80f8..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_ibm866.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("ibm866.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007fАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп������������������������������������������������рстуфхцчшщъыьэюяЁё��������������") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-1.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-1.cp.go deleted file mode 100644 index 2cf11d68..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-1.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-1.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-10.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-10.cp.go deleted file mode 100644 index 8a848b55..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-10.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-10.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0ĄĒĢĪĨĶ§ĻĐŠŦŽ\u00adŪŊ°ąēģīĩķ·ļĐšŧž—ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-15.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-15.cp.go deleted file mode 100644 index 376614ca..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-15.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-15.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0¡¢£€¥Š§š©ª«¬\u00ad®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-2.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-2.cp.go deleted file mode 100644 index 407f016b..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-2.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-2.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0Ą˘Ł¤ĽŚ§¨ŠŞŤŹ\u00adŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-3.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-3.cp.go deleted file mode 100644 index 70a87d61..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-3.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-3.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0Ħ˘£¤�Ĥ§¨İŞĞĴ\u00ad�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-4.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-4.cp.go deleted file mode 100644 index 4d9580a3..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-4.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-4.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0ĄĸŖ¤ĨĻ§¨ŠĒĢŦ\u00adŽ¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-5.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-5.cp.go deleted file mode 100644 index cef3807d..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-5.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-5.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0ЁЂЃЄЅІЇЈЉЊЋЌ\u00adЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-6.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-6.cp.go deleted file mode 100644 index eb48fa0d..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-6.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-6.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0���¤�������،\u00ad�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ�������������") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-7.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-7.cp.go deleted file mode 100644 index 477a6a15..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-7.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-7.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0‘’£��¦§¨©�«¬\u00ad�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-8.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-8.cp.go deleted file mode 100644 index a15fe2e0..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-8.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-8.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0�¢£¤¥¦§¨©×«¬\u00ad®‾°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת�����") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-9.cp.go b/_third_party/code.google.com/p/go-charset/data/data_iso-8859-9.cp.go deleted file mode 100644 index 923693bf..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_iso-8859-9.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("iso-8859-9.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_jisx0201kana.dat.go b/_third_party/code.google.com/p/go-charset/data/data_jisx0201kana.dat.go deleted file mode 100644 index c8a30688..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_jisx0201kana.dat.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("jisx0201kana.dat", func() (io.ReadCloser, error) { - r := strings.NewReader("。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_koi8-r.cp.go b/_third_party/code.google.com/p/go-charset/data/data_koi8-r.cp.go deleted file mode 100644 index d02dca08..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_koi8-r.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("koi8-r.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥\u00a0⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_windows-1250.cp.go b/_third_party/code.google.com/p/go-charset/data/data_windows-1250.cp.go deleted file mode 100644 index 99f4302e..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_windows-1250.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("windows-1250.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź\u00a0ˇ˘Ł¤Ą¦§¨©Ş«¬\u00ad®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_windows-1251.cp.go b/_third_party/code.google.com/p/go-charset/data/data_windows-1251.cp.go deleted file mode 100644 index 3274ac6f..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_windows-1251.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("windows-1251.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007fЂЃ‚ѓ„…†‡�‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ\u00a0ЎўЈ¤Ґ¦§Ё©Є«¬\u00ad®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/data_windows-1252.cp.go b/_third_party/code.google.com/p/go-charset/data/data_windows-1252.cp.go deleted file mode 100644 index 18f1c3cb..00000000 --- a/_third_party/code.google.com/p/go-charset/data/data_windows-1252.cp.go +++ /dev/null @@ -1,18 +0,0 @@ -// This file is automatically generated by generate-charset-data. -// Do not hand-edit. - -package data - -import ( - "github.com/mjibson/goread/_third_party/code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" -) - -func init() { - charset.RegisterDataFile("windows-1252.cp", func() (io.ReadCloser, error) { - r := strings.NewReader("\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ\u00a0¡¢£¤¥¦§¨©ª«¬\u00ad®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ") - return ioutil.NopCloser(r), nil - }) -} diff --git a/_third_party/code.google.com/p/go-charset/data/doc.go b/_third_party/code.google.com/p/go-charset/data/doc.go deleted file mode 100644 index 630a83d5..00000000 --- a/_third_party/code.google.com/p/go-charset/data/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// The data package embeds all the charset -// data files as Go data. It registers the data with the charset -// package as a side effect of its import. To use: -// -// import _ "code.google.com/p/go-charset" -package data diff --git a/_third_party/code.google.com/p/go-charset/data/generate.go b/_third_party/code.google.com/p/go-charset/data/generate.go deleted file mode 100644 index 156ee2c6..00000000 --- a/_third_party/code.google.com/p/go-charset/data/generate.go +++ /dev/null @@ -1,97 +0,0 @@ -// +build ignore - -// go run generate.go && go fmt - -// The generate-charset-data command generates the Go source code -// for code.google.com/p/go-charset/data from the data files -// found in code.google.com/p/go-charset/datafiles. -// It should be run in the go-charset root directory. -// The resulting Go files will need gofmt'ing. -package main - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "text/template" -) - -type info struct { - Path string -} - -var tfuncs = template.FuncMap{ - "basename": func(s string) string { - return filepath.Base(s) - }, - "read": func(path string) ([]byte, error) { - return ioutil.ReadFile(path) - }, -} - -var tmpl = template.Must(template.New("").Funcs(tfuncs).Parse(` - // This file is automatically generated by generate-charset-data. - // Do not hand-edit. - - package data - import ( - "code.google.com/p/go-charset/charset" - "io" - "io/ioutil" - "strings" - ) - - func init() { - charset.RegisterDataFile({{basename .Path | printf "%q"}}, func() (io.ReadCloser, error) { - r := strings.NewReader({{read .Path | printf "%q"}}) - return ioutil.NopCloser(r), nil - }) - } -`)) - -var docTmpl = template.Must(template.New("").Funcs(tfuncs).Parse(` - // This file is automatically generated by generate-charset-data. - // Do not hand-edit. - - // The {{basename .Package}} package embeds all the charset - // data files as Go data. It registers the data with the charset - // package as a side effect of its import. To use: - // - // import _ "code.google.com/p/go-charset" - package {{basename .Package}} -`)) - -func main() { - dataDir := filepath.Join("..", "datafiles") - d, err := os.Open(dataDir) - if err != nil { - fatalf("%v", err) - } - names, err := d.Readdirnames(0) - if err != nil { - fatalf("cannot read datafiles dir: %v", err) - } - for _, name := range names { - writeFile("data_"+name+".go", tmpl, info{ - Path: filepath.Join(dataDir, name), - }) - } -} - -func writeFile(name string, t *template.Template, data interface{}) { - w, err := os.Create(name) - if err != nil { - fatalf("cannot create output file: %v", err) - } - defer w.Close() - err = t.Execute(w, data) - if err != nil { - fatalf("template execute %q: %v", name, err) - } -} - -func fatalf(f string, a ...interface{}) { - fmt.Fprintf(os.Stderr, "%s\n", fmt.Sprintf(f, a...)) - os.Exit(2) -} diff --git a/_third_party/github.com/MiniProfiler/go/miniprofiler/doc.go b/_third_party/github.com/MiniProfiler/go/miniprofiler/doc.go deleted file mode 100644 index de8231e5..00000000 --- a/_third_party/github.com/MiniProfiler/go/miniprofiler/doc.go +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -Package miniprofiler is a simple but effective mini-profiler for websites. - -To use this package, change your HTTP handler functions to use this signature: - - func(miniprofiler.Timer, http.ResponseWriter, *http.Request) - -Register them in the usual way, wrapping them with NewHandler. - -By default, all requests are profiled. This should be changed to profile -only developer requests. Set miniprofiler.Enable to a function that returns -true if profiling is enabled. It might resemble this: - - miniprofiler.Enable = func(r *http.Request) bool { - return isUserAuthenticated(r) - } - -By default, profile results are stored in memory in a concurrent-safe -data structure. To store in redis, memcache, or something else, set -miniprofiler.Store and miniprofiler.Get to functions to back the profile -data. The key is Profile.Id. - -Send output of t.Includes() to your HTML (it is empty if Enable returns -false). - -Step - -The Step function can be used to profile more specific parts of your code. It -should be called with the name of the step and a closure. Further Timers are -used so concurrent work can be done and results applied to the correct location. - - t.Step("something", func(t miniprofiler.Timer) { - // do some work - // t.Step("another", func(t miniprofiler.Timer) { ... }) - }) - -StepCustomTiming - -StepCustomTiming can be used to record any kind of call (redis, RPC, etc.) - - t.StepCustomTiming( - "redis", // call type - "get", // execute type - "get key_name" // command string - func() { - // do work - } - ) - -Example - -This is a small example using this package. - - package main - - import ( - "fmt" - "net/http" - - "github.com/MiniProfiler/go/miniprofiler" - ) - - func Index(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) { - t.Step("something", func(t miniprofiler.Timer) { - t.StepCustomTiming("RPC", "get", "get key_name", func() { - // some RPC call - }) - }) - fmt.Fprintf(w, "%v", p.Includes()) - } - - func main() { - http.Handle("/", miniprofiler.NewHandler(Index)) - http.ListenAndServe(":8080", nil) - } - -Configuration - -Refer to the variables section of the documentation: http://godoc.org/github.com/MiniProfiler/go/miniprofiler#pkg-variables. - -Other implementations and resources: http://miniprofiler.com. - -Frameworks - -Various frameworks have explicit support. - -Google App Engine: http://godoc.org/github.com/MiniProfiler/go/miniprofiler_gae - -Revel: http://godoc.org/github.com/MiniProfiler/go/miniprofiler_revel - -Martini: http://godoc.org/github.com/MiniProfiler/go/miniprofiler_martini - -Beego: http://godoc.org/github.com/MiniProfiler/go/miniprofiler_beego - -Traffic: http://godoc.org/github.com/MiniProfiler/go/miniprofiler_traffic - -gocraft/web: http://godoc.org/github.com/MiniProfiler/go/miniprofiler_gocraftweb - -RPCs - -Various RPCs have explicit support. - -Redis: http://godoc.org/github.com/MiniProfiler/go/redis - -SQL: http://godoc.org/github.com/MiniProfiler/go/sql -*/ -package miniprofiler diff --git a/_third_party/github.com/MiniProfiler/go/miniprofiler/miniprofiler.go b/_third_party/github.com/MiniProfiler/go/miniprofiler/miniprofiler.go deleted file mode 100644 index dfcee72a..00000000 --- a/_third_party/github.com/MiniProfiler/go/miniprofiler/miniprofiler.go +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package miniprofiler - -import ( - "bytes" - "encoding/json" - "html/template" - "log" - "net/http" - "os" - "reflect" - "runtime" - "sort" - "strconv" - "strings" - "sync" - "time" - "unicode" -) - -var ( - // Enable returns true if the request should be profiled. - Enable func(*http.Request) bool = EnableAll - - // Store stores the Profile by its Id field. - Store func(*http.Request, *Profile) = StoreMemory - - // Get retrieves a Profile by its Id field. - Get func(*http.Request, string) *Profile = GetMemory - - // MachineName returns the machine name to display. - // The default is to use the machine's hostname. - MachineName func() string = Hostname - - // Valid positions: left, right, bottomleft, bottomright - Position = "left" - - ShowTrivial = false - ShowChildren = false - MaxTracesToShow = 15 - ShowControls = true - ToggleShortcut = "Alt+P" - StartHidden = false - TrivialMilliseconds = 12.0 - - Version = "3.0.11" - - staticFiles map[string][]byte -) - -const ( - PATH = "/mini-profiler-resources/" - - clientTimingsPrefix = "clientPerformance[timing][" -) - -var ( - webFS = FS(false) - fsHandler = http.FileServer(webFS) -) - -func init() { - http.Handle(PATH, http.StripPrefix(PATH, http.HandlerFunc(MiniProfilerHandler))) -} - -// miniProfilerHandler serves requests to the /mini-profiler-resources/ -// path. For use only by miniprofiler helper libraries. -func MiniProfilerHandler(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "results" { - results(w, r) - } else { - fsHandler.ServeHTTP(w, r) - } -} - -func results(w http.ResponseWriter, r *http.Request) { - id := r.FormValue("id") - isPopup := r.FormValue("popup") == "1" - p := Get(r, id) - if p == nil { - http.Error(w, "", http.StatusNotFound) - return - } - - needsSave := false - if p.ClientTimings == nil { - p.ClientTimings = getClientTimings(r) - if p.ClientTimings != nil { - needsSave = true - } - } - - if needsSave { - Store(r, p) - } - - var j []byte - j, err := json.Marshal(p) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - if isPopup { - w.Write(j) - } else { - v := map[string]interface{}{ - "name": p.Name, - "duration": p.DurationMilliseconds, - "path": PATH, - "json": template.JS(j), - "includes": p.Includes(), - "version": Version, - } - - w.Header().Add("Content-Type", "text/html") - shareHtmlTmpl.Execute(w, v) - } -} - -func getClientTimings(r *http.Request) *ClientTimings { - var navigationStart int64 - if i, err := strconv.ParseInt(r.FormValue(clientTimingsPrefix+"navigationStart]"), 10, 64); err != nil { - return nil - } else { - navigationStart = i - } - ct := new(ClientTimings) - - if i, err := strconv.ParseInt(r.FormValue("clientPerformance[navigation][redirectCount]"), 10, 64); err == nil { - ct.RedirectCount = i - } - - r.ParseForm() - clientPerf := make(map[string]ClientTiming) - for k, v := range r.Form { - if len(v) < 1 || !strings.HasPrefix(k, clientTimingsPrefix) { - continue - } - - if i, err := strconv.ParseInt(v[0], 10, 64); err == nil && i > navigationStart { - i -= navigationStart - name := k[len(clientTimingsPrefix) : len(k)-1] - - if strings.HasSuffix(name, "Start") { - shortName := name[:len(name)-5] - if c, present := clientPerf[shortName]; !present { - clientPerf[shortName] = ClientTiming{ - Name: shortName, - Duration: -1, - Start: i, - } - } else { - c.Start = i - c.Duration -= i - clientPerf[shortName] = c - } - } else if strings.HasSuffix(name, "End") { - shortName := name[:len(name)-3] - if c, present := clientPerf[shortName]; !present { - clientPerf[shortName] = ClientTiming{ - Duration: i, - Name: shortName, - } - } else { - c.Duration = i - c.Start - clientPerf[shortName] = c - } - } - } - } - for _, v := range clientPerf { - ct.Timings = append(ct.Timings, &ClientTiming{ - Name: sentenceCase(v.Name), - Start: v.Start, - Duration: v.Duration, - }) - } - sort.Sort(ct) - - return ct -} - -func sentenceCase(s string) string { - var buf bytes.Buffer - for k, v := range s { - if k == 0 { - buf.WriteRune(unicode.ToUpper(v)) - continue - } - if unicode.IsUpper(v) { - buf.WriteString(" ") - } - buf.WriteRune(v) - } - return buf.String() -} - -func static(w http.ResponseWriter, r *http.Request) { - fname := r.URL.Path[strings.LastIndex(r.URL.Path, "/")+1:] - if v, present := staticFiles[fname]; present { - h := w.Header() - - if strings.HasSuffix(r.URL.Path, ".css") { - h.Set("Content-type", "text/css") - } else if strings.HasSuffix(r.URL.Path, ".js") { - h.Set("Content-type", "text/javascript") - } - - h.Set("Cache-Control", "public, max-age=expiry") - expires := time.Now().Add(time.Hour) - h.Set("Expires", expires.Format(time.RFC1123)) - - w.Write(v) - } -} - -// Includes renders the JavaScript includes for this request, if enabled. -func (p *Profile) Includes() template.HTML { - if !Enable(p.r) { - return "" - } - - current := p.Id - authorized := true - - v := map[string]interface{}{ - "ids": current, - "path": PATH, - "version": Version, - "position": Position, - "showTrivial": ShowTrivial, - "showChildren": ShowChildren, - "maxTracesToShow": MaxTracesToShow, - "showControls": ShowControls, - "currentId": current, - "authorized": authorized, - "toggleShortcut": ToggleShortcut, - "startHidden": StartHidden, - "trivialMilliseconds": TrivialMilliseconds, - } - - var w bytes.Buffer - if err := includePartialHtmlTmpl.Execute(&w, v); err != nil { - log.Print(err) - return "" - } - return template.HTML(w.String()) -} - -type Handler struct { - f func(Timer, http.ResponseWriter, *http.Request) - p *Profile -} - -// NewHandler returns a new profiled handler. -func NewHandler(f func(Timer, http.ResponseWriter, *http.Request)) Handler { - return Handler{ - f: f, - } -} - -func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - switch r.URL.Query().Get("pp") { - default: - h.ProfileRequest(w, r) - } -} - -func (h Handler) ProfileRequest(w http.ResponseWriter, r *http.Request) { - h.p = NewProfile(w, r, FuncName(h.f)) - h.f(h.p, w, r) - h.p.Finalize() -} - -// Since returns the number of milliseconds since t. -func Since(t time.Time) float64 { - d := time.Since(t) - return float64(d.Nanoseconds()) / 1000000 -} - -// Hostname returns the os.Hostname() of the current machine, -// or "" if unavailable. -func Hostname() string { - name, err := os.Hostname() - if err != nil { - return "" - } - return name -} - -// FuncName returns the name of the function f, or "" if f is not a function. -func FuncName(f interface{}) string { - v := reflect.ValueOf(f) - if v.Kind() != reflect.Func { - return "" - } - fp := v.Pointer() - if fn := runtime.FuncForPC(fp); fn != nil { - return fn.Name() - } - return "" -} - -// EnableAll returns true. -func EnableAll(r *http.Request) bool { - return true -} - -var profiles map[string]*Profile -var profileLock sync.Mutex - -func init() { - profiles = make(map[string]*Profile) -} - -// StoreMemory stores a profile in memory (concurrent-safe). Note that profiles -// do not expire, so memory usage will increase until restart. This function is -// provided as an example: it is not designed for production use. -func StoreMemory(r *http.Request, p *Profile) { - profileLock.Lock() - defer profileLock.Unlock() - profiles[string(p.Id)] = p -} - -// GetMemory fetches a profile stored by StoreMemory (concurrent-safe). -func GetMemory(r *http.Request, id string) *Profile { - profileLock.Lock() - defer profileLock.Unlock() - return profiles[id] -} - -//go:generate esc -o static.go -pkg miniprofiler -prefix ../ui ../ui/include.partial.html ../ui/includes.css ../ui/includes.js ../ui/includes.tmpl ../ui/share.html diff --git a/_third_party/github.com/MiniProfiler/go/miniprofiler/static.go b/_third_party/github.com/MiniProfiler/go/miniprofiler/static.go deleted file mode 100644 index 685b8aa6..00000000 --- a/_third_party/github.com/MiniProfiler/go/miniprofiler/static.go +++ /dev/null @@ -1,748 +0,0 @@ -package miniprofiler - -import ( - "bytes" - "compress/gzip" - "io/ioutil" - "net/http" - "os" - "path" - "sync" - "time" -) - -type _esc_localFS struct{} - -var _esc_local _esc_localFS - -type _esc_staticFS struct{} - -var _esc_static _esc_staticFS - -type _esc_file struct { - compressed string - size int64 - local string - isDir bool - - data []byte - once sync.Once - name string -} - -func (_esc_localFS) Open(name string) (http.File, error) { - f, present := _esc_data[name] - if !present { - return nil, os.ErrNotExist - } - return os.Open(f.local) -} - -func (_esc_staticFS) Open(name string) (http.File, error) { - f, present := _esc_data[path.Clean(name)] - if !present { - return nil, os.ErrNotExist - } - var err error - f.once.Do(func() { - f.name = path.Base(name) - if f.size == 0 { - return - } - var gr *gzip.Reader - gr, err = gzip.NewReader(bytes.NewBufferString(f.compressed)) - if err != nil { - return - } - f.data, err = ioutil.ReadAll(gr) - }) - if err != nil { - return nil, err - } - return f.File() -} - -func (f *_esc_file) File() (http.File, error) { - type httpFile struct { - *bytes.Reader - *_esc_file - } - return &httpFile{ - Reader: bytes.NewReader(f.data), - _esc_file: f, - }, nil -} - -func (f *_esc_file) Close() error { - return nil -} - -func (f *_esc_file) Readdir(count int) ([]os.FileInfo, error) { - return nil, nil -} - -func (f *_esc_file) Stat() (os.FileInfo, error) { - return f, nil -} - -func (f *_esc_file) Name() string { - return f.name -} - -func (f *_esc_file) Size() int64 { - return f.size -} - -func (f *_esc_file) Mode() os.FileMode { - return 0 -} - -func (f *_esc_file) ModTime() time.Time { - return time.Time{} -} - -func (f *_esc_file) IsDir() bool { - return f.isDir -} - -func (f *_esc_file) Sys() interface{} { - return f -} - -// FS returns a http.Filesystem for the embedded assets. If useLocal is true, -// the filesystem's contents are instead used. -func FS(useLocal bool) http.FileSystem { - if useLocal { - return _esc_local - } - return _esc_static -} - -var _esc_data = map[string]*_esc_file{ - - "/include.partial.html": { - local: "../ui/include.partial.html", - size: 502, - compressed: "\x1f\x8b\b\x00\x00\tn\x88\x00\xff\\\x91Ar\xf3 \f\x85\xf7\xff)<\xec\xf9s\x818]t\xd3.\xbaJ.\xc0\x00\x8d\x95\xc1\xe0\x91d7\xa9\xc7w\xafl\xc0\xedd\xe3\xe1{Oz\x12\xe6H\x16a\xe0\xc6\xd0#چ\x1f\x83o\x15\xfb;\x1fnf2\xd9S\r\xb8V\xf5\x10A\x0f\x98>!xT\r\xa1m\xd5<\x18\xee\x16\x88" + - "6\x8c\xce\xd3\xff\x1b\xbdL\xed\x80\x90\x85\xe0 \x90\x9c\xeb,\xee\x95\xc4y\x1f\xce\v\xfa{\xc3YE(\xe69\xc7홊LJ\xe1\xcd\xffΘ\x13\xdcf\xbf\x1f\xb2\xac`\x94\xf1m\xf6\xd7z\xbd\xde" + - "\xc9GJj\x9c\x1f19\x1c\xc56{Ro*V\x8b\xbc%\xbf\xb0|~n>v\x0f\u007f\x1e\\\xdcY\xc31\x84\xdfym\x16\x17\xac\x04W\xbb\xef\xcdr\x8a\xf6\x98B\xeb\xbd\x0f\x06@\xa0=\x05\tx\x1fz\x80=+?A\x00\xf7C\x0fpĨ\x04\x01\xdc\x0f=@\xc5\x18h\x01\xefC\x0f\xc0\xc1\xd5\x1cd\x06\xe6\x04Z\n3]" + - "jG8!~ \xf56[)\xa37\xa8,I}0O{\xc6K\xcc̓\xed\x0f\xabտ\xfaWی\xd4G\x89P\xa8\x17\x17\xcc\x05)\x10\xcd\x11%\a\x89s\x8fZ\xac\xed1\x14\xae\x00m\x8d|\xe5?\xacn\x19E\xedcvb5S[\x11Kw\tz\x8aKq$\xe1\x93\xfeE\xe0H]\xb1\xc1\xcbM\xc0\xe2*Ҥ\x00Z\xf4ѩ\v1\xd2e\x90\x8cR\x14W31H)/\xca`\xc4 \xba\x1e\x89\xc0:\x1aa\xe5\x10W\x8e\x9a\x98K\x98\x1d" + - "\"\x8e]\xb0\xf3B\xed_UU\xed\x00\a\x9d/\xfd@j\xda\xfb\xfae\xe5\x9d\"Yj:\xb2k~b\x1c\xcf\xdf1\x1e\xae\xf2܅\xb4y~\xe8{\xd8r\xfd\xd9\xde \x83O\xb7#(\x16\xc2ND\xaf\xd1\x00\xe7\xa33\x81\\\xabk\xde\xc6L\xc6\xe5Ż\x89|\x95\x82~d\rS\x82\xe4j\x1fm\xb3\x1fQ\r\x14\xe7V\xb0\x93" + - "\xc1\xaec\xf7\x85\xe0\xabF\xd5\xefIc\x17\xf5\xc2T;*u\x04\xd2|\x14\xf3\x94K\xcf\xf7\x87 \x91\xadtB\x91\x17GBK#\xccX3o\xf1\xe4G\xea\xf7P֔\xb6\xa3\x18\xf1힉c\x12\x1a4l\x95\xae\b\xfc\xb9\xd65\xe0m\x1f\x92Z\xf7\x10{ʊ\xf7\xdd@\xb3c6\xd8Axd\xb6\x15\xe1\x8e\xdc#L\xf1\x9c" + - "/\xd8\xe1 e\x93\x95\xc4M\x03\xb6\x1bH\x84\xd3\xf0v\x97t_9\xe3㴢\x99\x90AZ&i\xe9>\xb6\x89\xa4=\xa4;H\x85\xad\xa3rZ\xdd\xd6\xdc06\xf2]\t\x9f'\x04\xe4\xa1È\xe4\x18SM\xdf$\x91;M\xb2B\xca[\xaf\xa9\x19\xbd\x9a\xa2~\xcfh9\xea<:ɗ\xa4\f\xa7\xb1\xf10\xda[\xb3\xcb\xd2a" + - "1\x12\t\xb9\x9b\xb4ߢ\xbc\x13\xee9݊\xc3\x1bV\x96\xbd\b\x00wx\xad\xfe\xe6\xbb\x1b\xa9\v\xac\x9c\x8eCm\xe7\x14\xe4(8ύn>:]\xfb\x94\xe4\x12B\xe7\xed\x84\xde\x1d\xa4W\xe5{\x8eѻ\xf4\x19\xf5\x1f\tG\xfb\x0e\xf1JJq\xdcf/\xabxt\xf09:\xa0Fs5S/=\u0604\xad\x8ahN\x9cD\xfb" + - "]}\xfd\xec\x92\r,\xfdR\xdc\x13\xa9|\xb3\xd9|\x05\xde\xc5\xd5u\x18\xbb\xd7ڨ/\xed\xecb\xd0'`\xa1\x93\xa6\xab\x05\x92y\x8c{\xcc\x17\xb8\xeb\xd2Ӑ\xb7bܒ\xbc\xad\xd4/\x15\xfa\xfdZ:\xf5\xd5j\xf5\xb6O\x85.\xd8ɡ\xad\xfeR\xa1\xc5g3\x82~\xde\xff|B\xc9\xf9\x8d:\xee4O\xee\xe6\\{rπ" + - "\xa6\xf7@\vt\xb8\x83s$ƴ\xabj\x1e\xf4\xc5\xe3<9\v}/q\xe1q\x1e\xb5\xf7\x15\xf1Zf\xaaɠg\xd6dߒV\xc1m\xc3\x1d\xa0Sa\xaa\x8a*\xd7\xe0\xf6']a1g\xac\x859\xbe\x1b\x81#\xb2=-L\x16\xbc>\xeb\xd2އ\x02+\xaf\x14T\xe9lt\xe1\xf8\x97\xeei?d\xfd\xf3\xf4\xbay}{\xf9" + - "\xf1\xfa\xa2K<֒n\x8eX\x91\x0f\xac\xab>ݑ\x04\x92vk\xf5\x06\xb2Z{\xcc&\x16tłZf\xfa\xe8\x89V\xc1\xc1kI\xcbt\xf8猶\x1e-\xbbгȞ%\xd9ڷ\xb7C\xc2n\xf7z\x02\x8aMi\x8a\xfd;\x11\xf9\xa8b\xeejǜ\xa3\x92\x9cۡ]\xcbO\xecW\xbf\xb0\xfbf֛R\xb3_\x17" + - "\xc7\x15\xd5ȗ\b8\tc\x99k\x16-\x10n\xa4\xd2^CF)C\xef\xf1\xa6\u007f\x11\xe95X\x82\xa3\xe9u\x99&h(\xc55\xab\x17\xfe\xcd\xce\xd6\xf15\xcb۔2ӝ\xcdt\xf3\xa0\xaf\x01\x98\xe2\n\xf9\x1a\xf9\x12\x9cf\x015\x18\x10r7\xa3\x96\x99\xde\x06z\xb3\x17\x83\xef\xdd\x16\vD\\\xceÄ\xb2\xfe\xe1\xcc\x05d\xfe" + - "\xe8_us\xa9\xc5\xdaKް\xbf\xfb\x8cc\x1dY\xde؉\xfa넹FC+Wm\xd0\xe6\x93\\\xa4\xc7y\xb9\x18\x0e\xf2!,\tb\xc0&_$Gj\x04\x91k\xc1\xf0\x11\xc0\xf1\xe7\x01\xa8.\x12\\2\xb4U\x9d\x1e\x11\xaaRV\xd3\xe3\xab\xde-\xa7\x86_\xb7\xa1ӫ\x84\xdb\xf8s\xa7۔\xc3;\xfd\x85\x8a)W\\\xf7" + - "9G\x85 \x17\xe0D\x0e\xd2B\x0080\xbc8!\xceX}\x17[\t\xa7\x0fs\xf8\x9c\x87-\x9d3]\xe2~\x1dk@\xf1ݹFR\xf1\xbdD\x04\xd5)|\x15\xff~\xa3\x050_3~B\xe0\xf8)\xbe\xfbn\xe7\x03\xde\xfd\xa2y\aqf\xfb\x94\xb8B\x92\xae\xbb\xcd\xc2\xc3\x1a\x90C\x89\xbd\x9e.\x1f\x87\x03Sg\xc4kƓ" + - "fh9~9s\x8f\x8f\xd8q'\xcbc\xceBs.\x1b]Ús\x93\x1a\xfa\x9e\xc6\r\x1a\xdaK\xb9\xcf\"pqg<\xe9w\xf54\n\x83R\x13\xb7x\x0f\xcd\xdf\xc7\xf7\xce\u07ba\x85\xc3\x05\ft\x16\xccJ'\x1f\xb2IF\xa5\xfa\xa0\xce\xef\x14Y5۷/u\f\xf9)\xbe6\xbe&E\xc1\xc3\xf3m\xe6\xe9L\xb0_:\xa9" + - "z\xc7\xe9_?\x03E\xf4H\x97e\x19\r\x11 \vV4\xba\xddM\xb06\xdb\xd3pykV8J\xa15<*\x1b\"J\xc7\xc7\a\xd19\xed\fz\xee\xad\t\xf7hr\x1e\xf2\xa9k\rIpΙ\xd3*tr\x9d\xc6D\xe0\xb0\xd5u\xa1\x97\xe54\xac\x06\xfevG\xca:Jy\xde\x04\x8e\xae\x80\xf3\xfb\xd4\x18\xf3r\x9b\xf8\xbc\x98" + - "\x88\xd0Ճ\xfd\x93\x89m\xfd#0.\xea\x03C\xfe9\x84\x86ۻ\x8f\xe1]\xfa\xa9\x1e$\x8e\xaf\xfe\xa7M\xb4\xac\x96Z\xf5;\xa84\x9f\x0f!\xf1\xd3\xd3\x17\xe0\x1a-ȥŃ\xd9\xc5\xf6f;\xc9\x01\xbdR?\xc2\xdc\x1f\x02\xf3\xbf\xe7\x1d\xe4\"\x83\x99\xba\x99\xb76\xa7\xba\xfb\"\xe4\xa2\xd5\xf7M8'\rs\xc3ѰO\xb2(" + - "\x852.\xdc\xddR\xf5u\x94WgJa[\x19ȟkG`\xe5\x92ƹ\x92\xf1\x81\xedSԀQd\xc1\xa4c\xb9\xeb\xf3:\x96Z\xfcr\xc6IVN\n\v\x1dd/c7\x92%\xdcC\xf4\x95U\x1dv\x02\xbeu)\xecv\xe0\x01\x0f\vf37\x04s?\t,Gv\x04\xae5\xbd\x8dK\x02#i\xe0J\xcfW\x91\xee\x8d" + - "\x19\bfw\xa8ˋ\x97\xafp\xc9\x13\xb8\xcfv\ae\xef\xba\xd0Xϡy\xc8b\x8a\x91\xb4\xb9^/%h\xe7\xd2>\xec\xa8]\a\xdfRKF7܀_\x16\x15\x93\xb2\xe3\x0f\xd3\xeeL\xfc\x93\x92\xe7{\xf5\x02]\xea\x99\xe8,\xee\xa0\xe4\x04\xab\xd9wU\xfe<\xfc?\x00\x00\xff\xff\xb5z\x1a\xba\x843\x00\x00", - }, - - "/includes.js": { - local: "../ui/includes.js", - size: 168291, - compressed: "\x1f\x8b\b\x00\x00\tn\x88\x00\xff\xec\xbdk\u007f\xdb\xc6\xd1(\xfe\xfa\x9fO\x01\xa2\xae\b\x98 E\xdaIڀ\x86x\x1c_j\xf7\x89/\xb5ܦ\xe7\xa1\x18\xff rI\xc1\x06\x01\x06\x00u\x89\xc8~\xf6\xff\xcc\xec\x05\v`A\xc9i\x9fs\xde\x1c\xb6\xb1H`/\xb3\xb3\xb3s\xdb\xd9Yg\xb9M\xe6E\x94&\xceU\x94,\xd2+\xf7" + - "\xf6\x1b{\x9b3+/\xb2h^\xd8\xe3o\xbe9>\xb62\xb6\x89\xc39\xb3\x8a\vf-\xd82J\x98\xb5f\xc5E\xba\xb0\x96Y\xba\x86\u05ffn\xa3\x8c}\xce=+Zb\xa1\x8cYQn\x85\xc9\xcd\x00k\x17\x17\xf0\x03\xfe\x9f\xb09\xcb\xf30\xbb\xb1\x8a\xd4\n/\xd3ha\xad\xd3E\xb4\xbc\x89\x92\x155\xbd\x8e\x92h\x19\xb1\x85\xb5M" + - "\x16,\xcb\xe7)\xb4\x13&\v\xeb\xf3\xaf[\x06\xb5\xf2t\x9b\xcd\x195\x19\x15]h/-\xacM\x9a\xe7\xd1y̰\xc9\xee\x82Ŭ`]jk\x93\xa5\x1b\x96\x15\x12\x82:\xdc\x00N\xc6\xf2\x02zXX\x0e\x00}\x15\xe6\x16\xbb\x8e\xf2\x02`q\xadpY\xb0\x8cj\x99!\x89\xa3\xf3\fǁ\xb52\xb6\x82j0\xe4\xc57\x97af\xa5" + - "Y\xb4\x8a\x920~λ\v,\x8e\xd6\x01\xef~\xfc\r\xf4\xe5T˸\xd5\"PEN\t\x8cp\xe3\xb8֭\xb5\x87i\xc0\xc6\xdf\x00\x82\xdeg\xe92\x8a\x01\xbc\xc0Rsga\xa9o,\xf8T\xe7\x0e\x9f`\xbd\a\x1e}\xc5\xcf'\xf5\rڔ\xef\xd3\r\xb6\x92\x97\xa5\xe6iR\x84\x00LV}\x94\xa5\xb1V\xa8Xo\xe2g\xe1\xfc" + - "\x02A\xbeݗϗ\xac\x80\x87\x8b\u05cb\x1c^Lg\xb5\x17\x80`\xf5Ƃ\xb9\xc9S\xeb\x8a\x01m\\\u00906\xdb8\xb6\x00\x15\x89\x15\xe2\x04\xf2q\x16Wќ\xa96\xc2\xcf\xe1\xf5i\x11f\xc5\xc7h\xcdLc\xb9\b\xf3\x9f\xd2y\x18\x9f\xc2䆫\n:\x15\x96\bz\x98\xbf\xf2\x17~2Vl\xb3\xc4\xea\xc6Z\xf5\xae\x15%" + - "b~\xac\xa3#\xf1mZ-2\xb3:A`%\x00\xfbX\xb5\xb7\xb7\xe6!\f\xd6r\x98k\xeee\x19\xc69\xd3\xcaӷ\xbd6\x8e\x15+\xfe\x01\xa4\ap\xb3\xc5\u007f\xb1\x9b\xca8\xbe\xb0\x9b\xf7\x19P˵\u07b8hX\xbd\xb3zV\xb7߅\u007f\xc5\xec\x0e.ys\xe3FWyx\xc9\xcc\xed{\xf0>\xdeVƀ\x04ܩ!\xd9" + - "q\x91J9\x00c\x18\x8b*\f\xf3;\x8f\x19RX\xbc@\xc8r\xc0`q\xc19\xc2F\xf4\x00\r\x02\xa7(\x89$\xcd,\a\xa1\x8a\x00\xa4\xe1\x18\xfe<\xb1tt\x0fb\x96\xac\x8a\vx\xd1\xeb\xd5q\x8b\xb09\x95\xc2Ч\x13\xb9\xd6ngu\xbb\xee\x00f\x8f]\xbf[\xea\xf8;\xb1\xfa\xa3z3\xf8\xa9\xb4\x92\xb1uz\xc9^\x17l" + - "mj\xdd\x1dWj\xef\xb5I\xd5\x11AX&~\xc2\xc7/\xa6\xe3\x1bS\x8f\xd3\xda\xeck\x10\xcf\x00-4)\xcdy\x8c\xd3pq7\x9d\x00(\x88c\xea\x0e\xb8\xe2\xa5g\x85q\f\xe4\xcd\xc2\xfc\xc6:\xbfل\xc0Q\x81!\xa7K aX\xc7wL<\xa2V\xf0/l\x11\xfb\x1d\\@\x9f\n\xd7\xdd\xf5&I\xa9\xa5\xa0\xab\xd0-\x89" + - "\x95\x16\x8d\x8e'\xf1\xfc\xbe\xb8h\xe2\x80x\xccG\x06\xac),X^\xc1F\xbe\x9d\xa3\x00\xd2q\x815\xbe\xd0\xe2\xea\x16\xb2N\u05ebL'\x81\x8ehE\xecb\xdf\xee\xf8\x9b\nNx\x81:\r=p\xba\xe7\xe9\xe2\x06\x88.\xdclX\xb2\x90Ū\xb4\"@r\xdc:'\xc0\x0f\x03\x0eQou\x00\xc8p\xe4\x82ބ\xb0\x96`\x95G" + - "\xc9<\xde.X>@\x8e<\xb9\f\f\x8b\xde\xd3\xf0\xb0\b\x8b\xd0D\xf28\x98\xb6w\x04,\x100\"\xc0\xb3\xa8\xd4\xd8X\xa81\xee\x03e\r\xa3ob\x81~5\xf0S\xe3\x94\xcf\xe2\x88%\xc5{\x96\x01e\xaf\xc3d\xae\xb33\xc7\xc0$\x05\xc5n\xf4\n\x9c\x85[\x13\xfe\xc77\x94i\xa1\xb6\x0f,\xdf\xc6E\x95֢E\x83\xce\xe6u" + - "\x18=\xf9(K\xcf\x19\xeaN\x9e\xf5ٳ6\xf0e\x81\xff]ktFLQc\x88\xd0\xfcA>\x88\xf4\ne\xa6\xd1Lk\x04?\r \xac\xba\xe4\xd2J\x11\\\xaa@\x83\xd3\n\x04\xad\xdf\x17&\x8a\xa9\xb5\x01\xa5\x80\x8d\x12\xa2L\xf3M\x03\xfc\xcc\a\xf8\x19\x06\xa8\xd7V#\xfd\xdc\x1c\xa9\xa9\xb7\xe9\xe7\xd9\x00\x11\xd0x\x86\x8b\aՆ" + - "\xbb\t\x0e?\b\xf12\xde\xe6\x17\xf5\xe2\xfb&*\x10\xe1\x81Zs\xf3m\x96Aϯ\x89)\xb4!\xa62\x05&\x12v\xdcq\xb321\x9cF\x03\x1d>Gm\xc8A\x85\x994\xf2\xf3\xedjuC\xea\xe1\xc6J\xb7\x85\xa2\xd7\xdcX\x8d\x886\xdd w\xbc\xb5\x92\xf02Z\x11{\xf7Qٳ\x8a\b\xb4\xf5\x15~W\v\xc2T\x9f\x17\x83" + - "\x16\x1e\f\xd8u\x81\xfc\x00+7F0\xe0\xe5L#\xc6\x0fQ\xc7\x06U1Q\xaee\xa0\x12C\xbc\xd4\x00\x84ջ\xab佰\x04\x9c\x8d\x8b*\\\xe7\xc1 \xca_J\xde\xc0KN73\xf7P\x9b\xf8AL\fTq\x18\x91\xfanfn\xf8i\x12U\xfbS\xe3\xcc\x0eJ\xb4\x1f\x82\x8f`+\x8b\xc2B[\x80=6/\x9e\xa5ۤ" + - "(W\x82\xb1\xddja\xf3X\xcc\x10\x9b\b\x19!i\x99D\xa0\u008bp\xfe\x85\x8c\xbf\xc5\u009a_\x80\xe9\xc8\x04\x16\xcd\x04\xa81\x19QZ\xa9\xe0\xe2\xc1\x00\x852.\xe9\xbc\x1d=D\xc6T\x9a\n\x96&Y\xbd\t\x13[(\x01њ\x18,\xa3,/ރ\x81D\xec\xe4\xe0̴P\xfa\xd4~\x89mXԈ\x85\xad\xd8HSo@" + - "\xa2\x0f2\x98\x88Ł\xfe\xac\x87\xd6h8\x1c\xb6Bk\x9e\xad\xff\xf9Q<%\xab\xf9'TB\xef? \xaa\xf4\x93\x98\x82\xbbGvO\xf2\xac\xa9\x0f\\\x95\xc2\xf1W\xccG\xc97\x91\xac*\xe2\xaa\xf6[\b P^\x87\a$]e\x1dܖ\fRc\x9dԳ_\xb5aK\xa1d\x11+\xad\xb7^\x85\xd8$\xad\r\xf2\bx\\\xf2" + - "4\xcbB0O@\x97(\rr\x17D\xeb\x10\x87g(\xc0\rs*a\xd4\x0e\x17ר\xe1\x94%\a\x1b\x94\x8d\x11\b\xb9\xbe52\xac\xf9\a\x03\x04\xdd1S\xd56\x8b}\xab\xae\xc7\n\xfd\xa0\xa6\x80\xcb\x0f*\x92\x88\xcehᓆ\xd4@\xbb\u007f\x97\x8a\xe5\xd7\x14\xaeM\xba\xd9n|kd\xed\xdb{\xfcx\xb3\x81\x86\xbb\x9f\xf34i" + - "\x81\xab\xe0%\u07bf;\xfd\xd8R\x02]'\xd0-o\xca\x06\xbd8\x8e\xb8\xa5t|ݿ\xba\xba\xea#\xb4}\xc0\bK\xe6\xe9\x82-\xc6\xc0\xae\xc2,gE\xf0\xf7\x8f/\xfb\u007f\xb6͍n\xb2\x14\x95\xe7焕\"\xdb\xc2X\r\x9fCz\xb7\xaf\xe9\xab8\xbeC\x1c\xa0$!5\xed\xedb\x0f)\x10\x1b\xc4\xf5e_D\x8b\x05K\xec" + - "\xbb\xc4\xeb\xf9\xb6(`\x81\\\xa4W\x1c\x96\xaf\x16\xaam\xa8\a\x93\x88\x15\xcco\xf1\x02\x19\xc7)\xe8;\xc7yb0\xd4k\xcf\x1a\xb5\x00d`=\a\xdc\x01\xf4\xaff>\x889\xfc+\xe2*80\x1b\xf8{\xf0*̟o9\xe9\xb0gۼH\xd7\x1f\xb9\xecĪUo\x92,\u007f\xcfb\x1f\xb3\xe82\n\xe3\xc3\xe5\xf4\xb6\x80\x1f\x91" + - "\xbds\xbb7\x16\xfa)J\xbe\xe0\xebƣݮYEt\xfe&\x8a\xe3(g\xb0T\xc89(YC\xd1|[\xab\xff!M\x8b\xc1\xfb\x10\x15n\x0e\xdc\xeb\x85\xec\xfa\xf5\xa2,\xab\xbb?\x16\xd1rɰ\x82\x95\xb3\fZ\x8f~\x03#\x19\x94\x93d\x113\\\xf4 \x01T\x91\xb8\xf4L\xe5W\x11\xb9\xf4p\xc1\xa7K\xde\x05q\xe6\xa6\xf5" + - "?\x0fA\xdet\x93\xed\xfa\x9ce]\xbfA#zUd\xe9\xecʂu̜J\x93M\x82;\xcfX\xf8el\xe8\b5\xfade\xe8\b\x06;x\xfb\xe2c7\xb7\xfe\x1a^\x86\xa7sP\xfc\x8bS5f\x18>b\x9b\x8f8̭c\x02b\xf4x\xf8\xe7\xe1\xa3o\x1f?z4\xfc\xfe;\xf7\xb8\xd1&\x12n\x88\xa2\x03 ?\xeeO" + - "\xce\x16\xbdc\xd0\xed\xd9\xfc.\xe8I\xfcb=)N\xc1b2\xba\xde\x0eah\x83\x8c\xf1uR\xf0\x96\xa6\xc3Y\xdd\xfb\x86\x9f梬aN\x93\x98b\trҡ!x%]y\x96\xd4E\f\xab\xf6\xa34m\xaa\xebV\x9aF\x9e\xb5`\x9b\xe2\xa2\xe2r\xe6f\xc9\xf3mF\xdc\xff稸\x00+\xec\xd9E\x14/\x80\xd4j+\xa0" + - "Vؼ\x02d!\xec\t\xeaP\x8f\x8d\xb7\x06F \xdeT\x1fOH\x8cX~}\xf9\x97ʹ\xf2\x9fƪ6\xf4i~\x0e,\xa1\x05̚\x9bM\x82,\xb0U'\x1c\x93۸V\xe5\x90\xc7D\x1b\xa7,>\x8dfM\xbe\"\xca\xe8\x9c\xe5\x10%5\x9b\x14d\x01\xea\x8eI\xa4|\x05\x85\xf4\x03\x13\xc0\x87ɥ\xba8\xf6&\x0fc\xad" + - "Mڧ1.\x1c\xe4\xa3)\xf7d\xf3\xed\xb2|{^d\xe1\x1cw\xd0@\x81\x81\xea\xd6B\x00\x93\xd7I\xe9\xb5\x149M:?4\xe4'_!\x16Lb\xad\xe5EI\x82\n\xae\x16\xda\xd3ɳNA\x862&1Y\xa1\xd59/\f\xf2\xa4\xf4m\x1c\xee\x05?Z̓\vzZ6o\xf0Q\x94\xad \x98\b\xa5\x91\x11\xcby\xf1" + - "\xad\xa1Y\xc3\"\xb7\x01\xbcmras\x9f\v\xc9CL\x98\xa9`G[ɕ\xe1\u07b5\x8eM8B\xd7D\x057Q\x8b\xdbF/\xf5U˿\xac\x8c\xf8T\xf4l\xf5\xaa=\xdfc\x85\x1aZ#$\xf7z\xe6rd\xd7\xeb]\xb6\xf6J\xf4\xba\xabw\x05z\xa5\xe8\xe9\n$\xa4\x85p\xa1.\x90\xc0\xb4d\x00\x95\f \xc1\x88\xaf\x02\x14H\xde\x12\xca9\xa9mZ}t\xf3\xf1\x8d\x86\x1cq\xbf`0\xa0\xb8TBy\xf3\x03*T\r\xa1\x12\xaf\x9e\xd1\x1b\xfe]x\t\xdd19vt(\xf3u\x88\xd1J\xb2\u05fc`\x9b\x9c\x82\xc4\x10\xb8y\x1a" + - "o\xd7\t\a6\\\xad2\xb6\xc2Ť\x14b0\xa0\x99\xc5=c\xd6\xf9\rƦ\x85\x80\x9d\xb1\x88\xc4(\xd2\xd5\n\x87T\xae2|\xc0^QyG\xc0S\x81%\x8eV\x17\xc5yzMj$t\x8faj\x11+\x87Lu\x1a\xc8\x17\xa5\xfa\x88\xa5\xaekD\x88(B~\xb9\a\x0ej\xfb\xae'\xe6Ҁ\x92\x18X]\x01c\a~\xd9" + - "\xa0X\xa2\xa9\x06\b\xbc)\xe8\\\xb9إ\x8a\xbf\x0e\xaf?\x829\xc1\xf2\x8f)\xf6n\"\xf6\x0f\x14\x96s\x9f\xd6i\xbf\xc1\xd1\x19\x8a \x02\x1c\xbac\xe2\u007f\x1a\xc6+\x8b\x97c\xbf\xb6z\ve͘\x11\xcd[\xeb\x8bb\xf5%\xc2\xdf>#\x8a\xc9\xefj\x83\x13M\x9f\xd3W\xdeh\x8a\xf7\xf0\x97pS6\xb4!%\xd6q\uf02a\xbf" + - "\x82J\xdd\xfa\xa2\xe7e^\x17U9\x90.\x1aL\x93⏢\xe4\vn\xf5\xf2\x02M\xed\xe0K\x1c\xe6\b\x17\x96\x1b\xa0s\xdd\xe9\n\x18\xe6\xf8\xa6>\x18\xfc\xc0p\xd9Gv]Tk\xe1\xd3~\x01\x8fMUpJ\x9bU\xf0\xa9\xacB!P\xb4q5\xc7%L|\xe6\x9c\xd1\xceJS\xd9\xca\x15\x11Pk\xd8\x04\xac\x8cN\xa0@\xabm" + - "}\xc8H\xaft\x8b\\+*\x90.\xb0\x12\xed{\xd2\xf2\xce0ֱ\xd0\xd77u\x84Z\x9d\x84ݤ\xbb\xd5\xc7\xc5!ij9\xc6A{\xaa\xfa\xe1`\x063\xc9`@\x11M\x9e;\xe0\x13\xe6H\xb4\xd4Z+\x01Sx\x9b\x94s\xe8\xeb@4\xbb}\x8f\x88I\x8aWi\x16\xfd\x86K:>\x9d\x83\xf0\x8a\x15\xc3S k\x95+kg" + - "\x10.\x16\x8e gW\xff\x81\xeb\xc1\xc8\xdf\f\xeb\xf0u\xc1ٜ\xd6_\x8d\xcb\xc1Lq&\x85!\x159+,P\x10\x90\x8ep\xc6\xc5v6\xf1wѹg\xad`\xe6/X\xb8 \xe9@\"\tx\xf4\xba\xc2!%\xd7#\x04\tn\x82~\t\xfeU\x9f\xce4\xe9\xe3\x8eu\xb7\x11\xb0P\x82/0`\x8a)3\x80o\x84\x0f\xf7\x1aI" + - "xͅ#\xa6\x15Z\xe9\xa91\xed!\x97 \xe9\xd3t\x0f\x9d\x89$p\x85\xe7T\xa5q5\x9c\xf1\x8au\x11\xddBjr\x9f\x14/\u007fL\xc5+\xb0s\n\x8fr\xa7\xeb_F\x14;\xdeD%\x95\x01\xfaeu%\xc0\x80Q\x83\xfa\x8f\xe3\x10m\xbf\xc7z9\x05F\xb4\t)\xbe\v\xa9`i24 \x96(\xfb\x91\x00\xc1\x96*-\x0f" + - "\xf0;R\x9cI\x13kr&\\\x8a\x18mk\xa5\x18\xa5\xcfG\x95\xb7\f]\xef֫\xf6jh\xf9\x9c4N\xa2\x1e\x19Ο&\fC\xbbiٱE\xb3\x17R*\x0e#\xb8\xe2v\x97u\xeeG\x17B\xc0\x03\x17x\x86\x9c\xcb\xe9\xd6\xd0\xd3GW\xe5%\xab`\x89w\xc1\x8a\xe7@\xcb\t\x86M\xe6\r\xf8j*\x95\xd4\x1f\xaa\x8f\xef\xc3" + - "ɚC\xd3\xfb\xbd\xdf\x18\xb9\x84F\xf5Z\x8cv\x93\xe6\x11\x8fy\x1c\xe0\xf3\xbe5\"a'\x1f[\x89\x10D8=R\xcb6\xcf\x10\x8f\x91y\xc5P\xb1$\x99.\x8e\x87\f.\xe8\x91S\xa3S\xd0\xd6T\xd9Jվ\xc5\x01\xf9vH\x90\xac\xc3/@$ی\x9f%\xe1\xc6\xc1\"ey\xd2-,\x1e \x06\x94\x14s\x0ei-Ӹ" + - "\nT\x94\xff\x98\x02\xd0km\x83\x90\xdbK\xef\xc5\x00UԱ}N\x05m\x92\xd4\xfdј\x18_\xceY\x03\xafB1\xce\\[\xe6e\xe9\x1cH\x92z\xf8\x88x#\x02^*\xe7n\xd5\b\x93\xa0\x98\xf4\xa0s\td\x13k\x80\t1U\xe9r\t\xccWM\x94|\xba-X\xf6J\xa2\x18\xa1^\x81\x80\x11\r\xa6KQ̠\xa5\xfc\xc4" + - "\x96\xc5=\xd0\x12C1\x85\x94o\x9aV\xb4\xa2XY\x15\x03Iy\xe3\x13\x8b\xd7\x061ng\b\xa0=n\xae\xe9\x06d\x839\xac\xbd[\xabˇ\xd0\xf5\xc5X<\xab\v$\xd3\xe7h\x81\xa7%\xfd\xec]s\x1bMм\n\xd2~\x8e\x16\xc5\x05!\xf8\xb1KӍ\xb6\x81\x85\x10\xa3|&\x80\xa1B\x98\xb3\x05N;\xb0\xe3e\xb4\xba\x1f" + - ";?<0\x98>\x80\x1f\xfe\xfd\xfa!\x99'\xeb?>\xac\x06\xa7iaOw\xdb9R\x19PK}\xd8`\x88\xb2\b\x106\v\xe7\x175s\xb2\xd6@\x0f\x97\bi[j\x81ԌJ\xd1(G\xf5\x06\x989,\xdb~&0\\k\xedD\x94Vkm\x02\\\a\xa8u4TA\x19\rT\xa0\xa4\xfb*y\u008f\x82\xdc)R\xaa\xf0" + - "\xa3\xd85Y\x99\xba\x19[\x81BX\xd85\xf4\x9fS \xadɂ?_\xd5\x15\a\xf1\xa6\xdd\xf3\"\n\xe8\xc0\x12\a\x00P\xff\xa6\ua7afj\x9a\x12\xee&\x88\x9a\xf8Ɩol\xad\x19d\x8fZ3u\x0e\tmr$\x9aO=\bp\xabE\xf6%\xce4\x8fD\x05ehz(ׄ\x1ewMs\x8d\xb1k\x8fk\x0ek\xe0\xcd:" + - "\x8f\xae\xbe\xbcФ\x99ν\x1fY\x0f\xa1\xb5ߏk]oM7!\xbc\x81\xd5;\xff\xb2\xa2\x18I\xf5\x12&\xf9\xc9\"\xba\xb4\xc8.\x0el\xc3|\xdb\xc7'\xea\x8c\xc5\xc7T\x1d\xba\x10+E1\xa1\a\xce\"\x9doA\xab(4\x19\xb4w+~\x0f\xfc\xe8`͡\xb48\xfe(G\x86\x86\x01h&(\xb7\xe3\x14\xf7wyD\x1bY" + - "\x10\xc4;4\xedA\x92\x87\x00\xa5\xc2\x13/$C\xac\"\xe2\x02\rf\xe9\xaeC\xeb\xf8\xa6\xc0 ,\xa9T\xa2\x8a\x12&$\t\xc3R\x97\xc1}B\xd2\x12Ȓ\xa7\x83\x99\r\x18\x1aꙤ\x1e\x02\xfauR\xa4\xff\x88ؕ\xa0\x1d\xf1N}\xa9\xfb\xfbn\x80U^\xc3\x02Y]\x90\xbbM7\xe07\x19+\x8a\x9b\xf7\xa0T\x14\xa6un" + - "\xec\xd5@\xbd\n\x82\xab\x8b\xb0\xf8\x98\xf2\xf2u.@\x87;\xc8О\xc7i\xce\xf2\xc2\xe9\x16\x19\xd2BQdN\x17-\xc5>\xb7B\xfbѢ\xce\x15\xe6,\x8e\x91N%~8\xa1\x16ٴZ-\xb0\xd1⇎zVמYŢN\xb9\x82\x16\x00\xfd7hz\xc1B\xba\x84\x11\xa9\x12:\xf8\x03N \x1fӍ\xd3\xf2\u0605n" + - "\b0\xe9\xa63\xa8\xb1\x14\x14\\!\x199\r\xd2\xe5\x8aG*\x17|1!)\xc93\xb6\xc84\xe7i\x9cfc\fW\x88\n\xb4\xd2s\x16_2\xd4\xefp\xdeP\x12\x92I\x84\xb2\x13\x14\xe1\"\xb7\xae\x8e\xc5A\xdf\xc1\xdf_\xa3\x94\xe5\xc6R\x84\x91\x84\xb8\x92\x84\v\x17\xb4\xb1\x0f,\x8fVݜw`m\xe2-t\xf9M\x05\xd7\x06!" + - "\xd8P\xba\xb0\xa0\xa5$\xa1\xc9\a&\x86\xfa\x8a!\x1b\xeb\xfe\xe1%|~\xfc\xd1\x10l\xaaJ~X\x9d\xf3S%\x1f\xfe\xf2\xa3\xa3\xd774/1U\xa9\x830\xd1\n\xee\x96ܩO\xc3\x04k\xb9\xd9\x06\x9e_\xc1\x97ϣ\xe5\xb2B\xd7K<\xe0y\xe0\\J\xb8\b7\x18\xe2E\xe7\xc8\xff\x9a^$F\x9c\x02\xe3(\x8a\x8d\u007f|\xcc" + - "\u007f\xe6\x031=\xf3t}\f\xbc\xf13\x9b\x17\xc7T\xde؍\xd8\xfe\xa1Pt\xe0F\x0e\xff\x12%e0\x19\x80\x894\a\xac\xddѰ1\x8df@z:Nቋ\xd4Z\u007f\xe6Y\x8f\xbe\xfb\xce-\xa3\xc5\xf4O\xfdt\f\xf9+\xc0\x10\x83A\xa3G0\x89ָ3\x90\xe3\xe9\x06a\x94\x8b\xf3*D\x9f\xd1ju\xd3'\x9a\x16\xb6" + - "\nn3(\xfczxz\xfa5\xe8A)0\x02\xeb&\xddz(S\xe6Qq\xd3i,{ɏE\x01`\xc6`\x1b6g\u05ef\x92\x9bIu\x150\xd7\x1a\xb3\xf6\x1e(x\v\xb5;\xfch8\x04\x93\x0f\xc1\xf5+\xae\xe3+\xcfZ^\xb7Q\x04\xcc\x03\x83E6ȋ\x9b\x98M5舺\xba\xb8]hg\xabs\a\xf7ަ:" + - "\xd1\x11\xa1\ra\n\x1a\x0fG\xa6\x87\x8f\xdc\xd9\xe0s\n$`{6N\xa8\xed\xda\xf7ٔ\xde\u05fc\x82\xfa\xfc¼R\x1f\xf0o\"\x0e]\x96\xe7\xab8}+̾\x04N%+\xfdxc\xfd\x18\x87\x11\x1e\xee\xc7\x10\xebx\r\x12O\xbe\x13T/\xa8\x1d,\xc6Ͷ\x18\xcc\xc3\xe3JCDz\xf4{$g\x8bǂ\xe6 \xa7\xd3" + - "/(CQL\xf2\xb5Tl\x81\x81\xe5\xd6\x14h\xd5\x13\xff͔\x88\xe2뾲v\xa9\x96y\xa3\xb2ʋ\x9f]0 P̢@\x8e\xb80\xceX\xb8@\xc39$\u007f\x1c\xdf\x04KD\xd0(\x9e+Ɔ\xf3\x8a\xbe\xc8!\xc4s\x17\xf8e\x80[\xb0E\xb6\x9d\x17\xf00\b,:\xa9P\xbe-\xe3G\x1f\xbbrus\x1e_\x01\xeb" + - "'\xc0\x00\r\x1f)&ٮ=\xf1\x9f[\xe9Y\xed\xbc\x1eC\xb13\xe7,\u007f\xe8L\x87\xfd\x1ff\xb7#\xef\xf1ޅ\x9f\u07bd\x1e\x9d\xb9\"\n\x96cM\xc15UL\x86w4\x1d!\xbb\xa8?|dz\xf8x\xe6\xce\x0e\x8f菞\xfa\xe7~\x83\xea9\x13\xffl\xc0\xbf\xba\x13\xf7쏕\xc1|\xfd\xdbã~\x19\xa7\xa1>n" + - "\u0bcf\x06@xV\xf3\xed\xa3\x83o\x1f\xab\xb7m\b\xf9C8<\x1f\xcd\x1f\xb5 \xe1\x0f\xce4\xec/\x9f\xf6_Ҕ=ڻw\xfd\xbe\xf7\\\x02\u007f\xf9\xde8\x9f-/\x1e\xf3\x17\xad\xc3X.\x97\xf7\x19\x83\xdb\xfe\xe3ޠ\x03ۻ{\x18e\xa1\x03C*\v\xdd1< \xc6\xd0\x01\xa9 \xfe\xef\xe2\x12.\xb20\xc9\xf9\x86\x13" + - "ꑧ\xe12\xcc\"\xebq;9\x87gZ\x13m\x04\xc8Y̴\xab\xb5\xdeա\xd2\xf3\x0f4\xf7 @+~.̦\x17\xa8\x1f\xe6\xadYDt\xfb꜔i\x1e{\xf0\x85\xddl7]\xfd\xd4=k\x1c\x06\x96\xa9q.Ȋ\xcbQ\u0093\xedC\x892\x8a,\xfd\xc2\xf2\x17\xf9\xfc=\U00104430\x01\x9e;\xc1\x15\xd3\xe5ą\xf2\x90\r\xae.\xa29\x89\xc2G\u007f2\uf7bf\x173HA\xfd\xe6\"\xa5\xbfGD\xfe7f\xa5\xe1\a2\xcdL\xb5)\rx\x8c\xfb\xd2\xc0\xa7\x15\xd2\x15g\xb1ž" + - "X\xee\bTL\x87\xc0B\xa0p\x98\x81F\xe2\xd6\v\xd1tT\x8b\xb4\x1e\xb7\u008f:\xf7y\x9f]\xbf:ƾv\x04\x06\xe0\xeaE8\xc95˨\xe7\xe8\x99Wo\x0e\x12\xf9\x1d^6\xfc\x18=m\xf2#]\x00\xbao\xf2\x8e\xae\xde\xd7}\xa2\xf2s\xf7~iuj\xf65o\xa1\n\xeb\xa7m\xe2Ӌ4+\xe6ۂ\x90g~\x05" + - "v\x1c(\xcb\xce\xf1/o\x81\x95<8\x8e\x1as\xd9\xe4˰h0\xb3T׳\xccM\x96\xbc\xba\x19\x11\xc8[l\xac~X\xe42\x1e\xa2>ԃ;\x99\x18\x16\xf2\x12$O\xc3\vT\x11\x112H\x85\xcc\x17\x99y\f\xe3\x1b\xc5\x0e\x15\xdf5 N\x8f#\x14\xe7\xd74\xbd\xba\x9a\n\xc7i\xe9Ft\xa5\xd2m\xc9h\x18\x9e\x8dl!" + - "#ʖxNz\x83\xe9\xae@`\x81z_\xa9_\vZ\x94m\xb9wD\x15J|\x1c\x122\xb5\xe2\x87#\xe1\x88\x16\xab\xae\xb8\xfa8\xf3\b\x0fh+\xbf\xa6f\xae\xa0\xaf\x10\x0f\u007fm\xf3\xa2\xe6]\xe2\xae*\xeb\n\xb1NK\x1f\xad\x9aвGV\xfekl\x93/\xae\xb9a\xf4;\xa2\xed\xda\xd6h\xcd[\xa9\xe2\xf0L\xa2\xa4K\xcf" + - "\x15\xf1\x1f\xa2K\x83\xa3\x12)\xf3\x99\b\x1a\xadقr\xfej\xa9\xc0*\xa1 2ܴ\x19P+[lsl\xcb\"\xf6\xc9\x13Pג\xc6\xfbu\x94\xf4\xd7\xe1\xb5}\xb2~r\x8c\x05Z\x8aQ\xb21\xfbd.\v\x1dC_\x15?y+\x1dVp\xa9\x00\x1e\xd4\x01\xb8\xe7ĕ\xd1\x1e\"\xf2\xa5\xb6_\x04\xadu\rS\xd3\xc0\x1ao" + - "\xe3\x02XxvG\x8ft\xea_\ue945\xb9\xb1\xc36\xaf\x8b\xacW\xa7\xd8r\xcc\xf5\xed\x02\x05tu\bU\xf5\xe2\xff&\xc0&\xa9f\x00\xf8k\xa9\x80\xe8\xeb\xabi\xa05,\xd5,\x9d\x9b\xc2\x03?\x86\x8d\xe9\xb2\aC\x94K\x92\xaa\x01t\xef\x94F$\xd9\x0f\x8b#}\xb1\x87ۂ\xb6\xe3\x9b\a\x9f\xd1\xf4\x00V)\xd2\x05\x94\xd1\xd9" + - "9\x97+\xab\x14\xe5\t&\b5\x0f\xe4\x00\x87\x10\"\u05fc\xef\xd5\xe4\xf3z\xaa\xcc\xc1\a\x92O\xafE\x9a4\x18W\xce\xd0\xcdO\xaa\xb3\b+/R)P#\x8c \x17A\x1fh\x1em\xa1\xaf\x8cv\xdc\xefB~\t\xac\xade`\xab\xee\xee7A\x15A\xa2\x80M\x119\xce'\xad\xaa\x81i|\xb9\x9d\x87\xf1P8@\xb3\x18\x89@\x19" + - "\x9d\xf2\xb0.\xa3\x10d\x96p%\xd2\x01\x8d\xbe8\xb8y\xc5Hà\x98z\xa9-x\xa2%\x9aHz%cY\xa91tM\x03\xc9\xd0\t\x91\xa8\x8a\x97\x83Z\x87U\xfb\x88\xf8\x96u\x88\x19TI\xbd(\x15\x11\x01}\xa3\x8e\x9esMQ$\xe6[k_Eu\xfa\xcd\xf1`\xb9\b`\xd5\xf9l\x8di\x1c\\|\xf7\x00c_݄\xfe" + - "\x8c\xaa\xfa\xcd\xd3\xcf\xe1\xf53\x91\x95\xa2\xb2\xda\xc0F\xbf\xbe\xc8<\xa4\xcd\xc2t\xf4\x13\a\x00\x05Z\xd0\b\x1cz\x1bc\xf0T\xc5\xd3*\x9c\xc1hm\xac\x06\xd6\xd4\x1e\x0e\xff<\xff\xf6ϣ\xc7\xfd\x1f\xce\x17\u007f\xea\u007f\xfb\xed\xe3E\xff\x87\xc7\u007f\xfa\xbe\xff÷ߎ\xd8\xfc\xdb\xc5\xf7\xe1\x9f\xe7\xb6g\x8f\xbe_.\x1f\xff\xe9O\xe7\xfd" + - "?\x9f\xff0\xef\u007f;\u007f4\xec\x87\u007f:\xff\xae\xffß\xe6\x8b\x1f\x96\xe1\x9f\x18\v\xffd\xcf\x1a`P.Q\xea\x91gx\x05h1\xbb\r i\x03\xc8a\xaf@\xcd\x029\xd6\xfdg__\x9c}([\x97\x85r\xb8\xaa\xb1C\xc7<#~\\\x9e'e\xf8\xeb黷hCu1\xd1&)\xb0]kBO\a\xe4\xb7қ\xf4" + - "-v\x19\xc6\xda\x13\xf3\xa9\xbe\xcaD7\xe9\x8cO\xb4\xf9\u05fe\xea\a\xd3\xf7}\x8a\"\x84\x85\x85!Ø%G\xe5)\x91Z\xbc\f\xd2\xe3\xb1\t\xa0sK\xa5z\x81'b\xba\xb9K\x99\xb6<ʁ\xcc#\xcda\x01%\x18l\x9c\xa4j'\xb3\x91b\x14\xd1\xc5[|P\xa6\xc1\xe2dY\x85\x94/{ѥ\xe2#\xe8\xc2ÝR\x0e" + - "1\xf0\xf9\xaa\x0f_\xb6\xac\x92tiz\xa8\xf1!%\b\x92k\xa1>ŇK;\xcd\xc5d\xf2&\x89F\x06*\x89\x92\x89\x90\xcc=Q\xf1\x9ao\xab\x91\x8bI\xa6\xa5\x10aK-T`@\xadD)\xe7\xc0OO\xdf[O\xcdH\x15t\xed\x9c\xde\xe4n\x9d\xb0\x01\xa7\xda\xeb\xc1\xcf\xec\xfce\x9a\xad\xef]n\xf0\x1e\xf8\xed\a\x06\x12!" + - "/ބ\t\xfc\xc8\xeaU\r\xe2\xfd/BTD\tpQ\xb4\xa5\xa0\xd9fCMOb\xb3\f \xf0\x0ep\x90{\xbc\x16\xfd4\x8c9Cq\x90ğ@\xf4\x89\xa7\xda\xe4\xe5$\x10=`\x8c\xe6#\xf5<7\x89\xf9\x9d\x1c@&\xd8\x18\x80\x8dE\x11\xb6O\xf2Y[\xea8ἦ2\x95\nO/\xc3(\x0e\xcf\xd1s\x80ӣ\xca" + - "|\xba^ǯ\x8ab#\x86pWfG\t\x9b\xceu\r\xc0\xfd~.\xac\x0f\xe4Nn\xacC\xf4?͕\xe5\xe7\x1e\xdcY~\ue6cd\xf1P\xeeY}%\xe3N\xad\xf54\xdf\f\xde2~\x92\b\xb7\xabͫW\xd0\xf8\xa7\x17\xd7l\xbe-\xd83Q\x986@lI\xa6\x8d\x1cY-\xb5\xacJ\xe6w\xd9\xf1\xbbs\f\x83h\xd1\x0e" + - "0\x952+cbdm\xa3\x04W\xa5\x826\x00\f\xc9\xdedV\xf3\xaf\x00\v?\xb2\xafz\xf1\x03\x19EuR\xaf\xd6\x1a\xc0\xda\x11\xeb\xe6\xdf#\xf8{\x13\xfb\xff)B\xbf'\x91\x9bH\xb9F\xcbN+5\x87q\x9e\x1a\x85Ӌ\xeb\u2be7t\xc7\x03 \x16\xd3\x14'<\xebTD\xd6\xd19Cg\xd86\xd7\x02\x00u\xc2\u007f\x81g" + - "\xd9\xda\xc5\x11\xbc\x1e\xa0\xe0\xbbO\x99\x01\x9e\x9a\xbeS<\xc9\xd2t\x01\x05z\xfbV\xa0\x1b\x88H\x19п\xb8wO\x84\x1b\n%\xac\xc0\xb8\xb0\x1c\xd3\x0f\xd2\x10\xa5*ֵ(6\xacҁ\x06\x8b\xd3(\xaf{\x90\xef\xd0\xe59\xb0\xd12\v\xd7\x18\xfc\x84J\xd6v\x83Ǻrk\x91\xe2Y\b\x02\xf1\x82(\xb7i\x01\xd1>\x19\xb4\x8f" + - "\xdb\x12\x1d\xa3\x92\xddF\xb4\xa6\xcd3\x03\x9d\xe0\xe7\xff)\xf3\xfc\x97y\xc1\xe84\xfe&M?\xa6\xe4\xf6l'b\xc1\x97\x0e\x13\xb0d^\xa0w\x17)\xd6D\x85\x86o@\xd7\xd2h\xa6ɳFbC\x83\x81]\x9fC\xf4\x9a\r\xfe\x8d\x89\xbcs\x1a\xff\xa7\xa7\xf0\xce\xe9k\xb3\xc4\x0e\xc9q\xccF\x9co7\x9b4+\xc8\xc4y\x9a\xac\xb6" + - "q\x98\xfd\xf5\xd4\x13.\"\xbcS\x85\xce\t\x85y4\xb7\xfe\xf9\xe6']CK\xb9\xec1XB\x83\x907\xa4\xd3A\xb5\xf2ar@d~B\xcd\x15\xd0Y\xad\xa7Q\b\xbe\xafH˃%u\x87CN\x9a2]\xec\x83V\x8f1\xf5?\x919\x12M\x9a\xd0&\t\xa8\xe2\x05\x9b\x83\x8d\xba2\xee\x91髂\xaa\xe1\x8d>j7\x88\xb6" + - "N5:\xc0\xf3\xadm\x85\a\x18\x99\xfb\xc9\xd4kpP\x02\xc8O\xa3AL\xbfb\xb54\xea[-clMm\xdeV^Co\x9a|\xc0\xb7\x98A\x86=\xa3\xb7:\xb2\xef\xcc`\x8e\x1dd\xaa\x01\x1c\xf5\xb7\xf7Q\xbb\x1b\xab\xfd\xdf\xd6\xfc%D\xf7\xd6\xfe%(\xff\xa7,\x00\xfc|\x85\x15\x80\x9f\xb6\f٭\x19\xa6\xf1\x13}\r\x9d*" + - "\xc3\xed \x1cBk\xbew\xab\xe8\xf7\x8eo\b\n\xb2e\xc9]Ѫ\r\xde\xed\xa7\xfa\xc6\x00\fq\x9c{t\xd4z\xcd\rF23\x1e)\x9f[WaB\aN\xcfU\xba\x13<\xa5\xc62\xf4\xb8\x82\xaa3\xe7:\x96\x96\x9b\xa5\x11zU?O!\xc0\xd4w&\x92\xa88\x94ߗ\xd6\x05\xa5>\xc5\x14\x99\xa2q\\\x18/8\x94?\xde" + - "\xbc^8]\xc4\u007f_N@}A\xf0\xe4\f\xbc\rT\xba\xf8Wl\xe3i\x01dz\xbeE\xff\x95T\xae*5\xd1\xd1VًxPm\xf9S\xfd\xfd\xa7Z\x03µl\x19\xaf\xfb\xaa\x0fS\x06\x1e\a\x96\x01Bq8D\x941\xadyڌ\x0f)\x95h{},\xd0\xd8q\x91\xb5\xd5\xd5\x17\a\x9b\x10\xa5\xe8\x80JKC\x9c{\xb4" + - "7\x11\xb5+\x9at\xf7\x8ah \x12y\x9c\v\xa7\xeb\xb5\xf6\xb5)Ϻ\x1e\x18\xb6(\xd4\xdaJ-x\xe5P[\"\xebI.\xca\x1a\x9b$\x9e\xdb\xda\x02\x9e\xaa*(=N\xd75\xf3\x18\x04I\xe5\xd0\xc1H6\x19\xb6y\xcfF\xbf\x1a$\x99Gf\xad%6<\x04\x9c!\x87\xe7\xfd\xc0l\xe9\xe8\xf7\x02\xdcE\x9d\x02/\x80ʶx\xc0" + - "\xb1\x9a\xcfǜ\xec\xefp\xbb\xf2Xj\x97++Z\xbb\xf32\xab\xea\xefjX\xed\xe76\x1a.#,~O\xc3\xe5~n\xb3\xe9\xf2\xdd\xefl\x9c6\xdbDޢf\xf3\xdaV\x9cj\xbfͻd\xd6;`\x89\xe3\x85\x00yK\x9a\xfc\x103\xb7\xe1\xbf\xe6\xf7\x82\x1b\xfa\xf2\x8b\xb9Tu\x0f\xd7W\x1c\xc3\\ZK\xe2\xe2\xab,0f=" + - "\xb2\xb9\x06|\xd3\xc3\xf6~\xf4\xf4+\xe5\x89hs\xf9ZJ-\xbf|p\xa0}AY\xbe\xe1\x02H\xfd\xa3\x18\xbf_~5\x97,\t\xca\u05fe\xb7\xe0\xa7\xc2S\xfd\xda\xef\x16\xa8K\x8a\xf2\xf5\x1fw\x1a\xfa\x8d\x1d\x06JW\x9b\xbe\x06\xf5\xa25\xfe[~pw\xaf\f\xca\xe3\xf1a\xf9E\x981\xbc]C\x86\xcey<\x1e\x1b\xa3\x1b(\x1a" + - "\x82.\x1cm4U\v\x86\xa8\x87\x8d\xf4\xb1\xb96\xd1W\xeee\xb7\aP˲\ao\xed\xb3\x8f\x04\x15\x06#\xdbm\xbb\xf8D~Lɋ\xf8Z\xbe\xa7\x9b\x92@҂\"\xefwAׁ\x84\xae\x95\x98\x96{\xc4\x01\x19&\xfe*\x8cD\x86\x83\xfa\x1b0_\xa2\xfc\xc2j\\\x93 ߃\x81\x83\xc1&\x15\xaai\r\x81⍹\xad\x9e" + - "9m\xa6\xf4\xdb\xeaʋ\x906\x8d[y\x0e\xbe\xa4\xeb\x8eH\xb3~\x91Хet\x1d\f\r\xf6\t]\xbe\xd3:\xd39\xbf\xa7&\xdd\x16\x8e\x1a\xa1'N\xe6\x9a\xcaS\x9b\xbd\x00K\x18\xf0\u007fh\xf6\x14\x82\xdbS\xed\xe2\x04\xff\xbey\x8d\xee91w\xc7:\xe9\xadn\xb3X˾\".\xb4\xb1\xd5Ō\xf3<\x9f\\\x06v\xdbe\xac" + - "\xa6\xfe\x95\xa12\a+\xb0`\xa7x\"\xf2\xf4\x82\xb1ֽ\x14\xfc\xb4Vr\x00\xc06;\xf1\xae\xcc\xc8\xc0\x84\xd0\x13]^\xe9\x88!Z\x94\xeb/cq`\xd3Y\xcd\x1c;\xb1\xc9\xda\x0flL\x00w\fC\xb6-\xe4)\xfc09\"\bO\x93[\x18\xbf\xf5\x15\xfb\x17\xcd\x11\xbe6L}}\xa2\x1f\x94$\xaa\xbb\xfd<-q\xdcz\x13" + - "\xfb\x87s\xdb\xe2GZ\xe82\xb4Y\x1637\xaa\xae\xf1\xe39\u007f\u007f\xbcy\x1b\xae+W\xcf̵\xb7\x1e\xe5\x92m\xc4b\x1bӟk\xd5\x06\xf7̂^\xde'W\xad\x87\xb7\x04 Xt\xe1e\xd8~\xef\x97\xfb/\x9f\xf6\xfe" + - "\xa2d\x99Z\xe19^\x88KI\t\xf9Yd\xd1|\x91Z\x98\xc2\xc5\xd2Q\x81\xb1\x04\u007f\u007fM9\x89\xb8T\xfa*\x88+\xb7\x8apI,\xf1\x8d\xbf\xee\xde\xec\xa8^O\x11\xc61QE\xa0\x91\xc8\xddm\x88DU\xc4_\xf4\xf6\xfe\x8d\x8d\x13\xf3\xd3;WB\xcb}N\xfa\xe7?p\xb7\x93\xfeїo\x1d\f\xcc\xe6\xf2\x1f\x88 3\x9c" + - ";#6\xc6\x13\xd8Y!\xa74d>t\xc0,cs\xccJd\xe1\x01\xc5oZA%^U\xe7}4\x8d\x15\x1e*Yh\x9b\x17-\xe4̺z\x99\x14\xb0\xd7\xc6\xd3\x1a\xef6yG\xf8\x01\x16%\xda4\xb3\nٱ\xa7$IC˕\r$\xec\xea'\xb3\xaa\x81\x1f\xd3ēШ\xcdv\xabY\x16\x81\xe2Nٲ\xf2\xa2\xf5\xc6" + - "\x1f2\xb6\x04\x9cBڜPE\xfe㮝ZsUi\xd6\x1f\xa6D1zq\xa5&Իc\xf9\xa1{'J\x0eݐӾ@+}\xddJ\xc9]\x8e\xd3\x13f\xb7o\xd5FT\x97\xb7eWw\xa3SX\xf2O\ue2d4\x03\x95\uf70c\xc6 \xff\xaf \xb4\x06}\x89U\r\x03\aP\xda|Ҷ\x8cE\xf7\x87\xed\xe0\xeau" + - "\x85\xac\xaa\xad\xe0&\xad'\xc4]ۆ\xe2\xa2\\\xdaj\x88\x94\xa1\xa9\xc1-ʑ:\xe6\x02x]\n\xbe0]\x80\xe5\x9av\xab\xa9t\x16\xcd/\x94\xa4\x9fJp\fK\x99N\xf9s\xd1}G\xd04\xb5+\x8a\x06b\xfc\xe6\xf9\xd0JV\x01\xa9\xf2=\xc7\\Nc\u007f\xf7\x8a\xb8\xc3\x11PKw\xc9D\x13[\xacT\xbc\xaf4\xd4I\xa3" + - "\xda5\xddT\x88O~\xa7\xab\xa6N\x88\x95\x9e2\xbaZ\x93\xa6\xc8 (1\fKF\xa0\x9e\xdfP*\xfa;e\x9e\xc1n\xb8\xaf\x903\v\xb6\x05\x18\x82\x19L\"{wɲ8\xdc\xe8\xa2m\x15n\xf0\x98M\xf3\x0e\fY9Uu\f\x9eO\xd3\xe4ac\x1a\xe1\xdc\xff\x82\xbbL\x10q\xad\x81\x83\xb2N\xd4R\xf2\n\x86s\x0f\xcel" + - "\xb8{V~Z\xfc\xf9ZW\x8a\x93c_w2\xf2\xc3L\xb9E\xecH\x9c\xf7ĝ\xf3\x98߯\x1c\x99gUA\xc1L\xae*\x1f\xa0\x02\xaa,\xc5a\xbc\xcf&\x84\xf4\xd1\xf0\xee\xef\xe6Ɗ\xb0\xfeR!*\xab\xa4*Ϣ\xe4\x16w\x13W\x9dF5\xc24\xb3Gj\x97\xfc~\xb8#\xb5۩\xb6Nx\x97\x03]]3!Y4" + - "@wړ#\x0fɎ\xfc\b\x9a\xcf@6z\xafk\xdeT\x82\x16\x0e@\"\x1d\x93\xb2ა(xq֍3\xc0;5\"\x83\xba\xf8=\x9c\xb6R\xf1\xbe\x9cVbN\x9f\xfer\xbe\xaal\x97O\xff\xefw\x91\v\x92\xa4f\xee&Ȃ\x1fe3\xecsa\x10\x9a\x15h9\xb2\xe4\xe7\x01\xcfj\xca\x19\xb1w\xc7\xce(\x05\xb7a" + - "S\x9c\xe0\xcd(*\xa9\x87\x87ؙ\x987\x02\x8a\xf9V^F\xd7l\xe1<2\xe4K\u008f\xf4HEm\xce-\xa9\xa5\x98\xfb\xb9Ӕ\xab\x0f\t\x13\xd4~`!\xbf\xc1\xbd2\xbbz)\xcfj\x97y\xd4\"\x9f\x84\x96\xb1\xf7\xf8\x8b\xfb\xdd\x1c*f\rk\x18\f\xb8\x86\xe7VHSu\xfd\x96q\xfb\x8fb\x89\x98\xcao=\xadV\xea[" + - "#\x83\xb8Y\xb3\x01\xde6q\xcfYG\xf4\x18\a\xf8\x9f\x9f\xf8֮Ls\xdf>\xaa\xf6\x89/\xcbԦ\xbdҶ1\xf8\xf2О\x01m\xe4\x16安\xb6\x05\xd2¶E\xa3\xea=\xb2\xfca\x89\xc9Q\xcb.\x96\x1eL\xebW~}#\xb0\"b%@[\xc3\xcf\xdf\xd1\x05\x96\xcfӌ\r>\xe7\xd6h\xf0\xdd\xe0\x91|%\x12\x98" + - "nU\x89\xcf\xf9 \xcdV\xf2\xb53w1O\xec\x0f\xfdG\xc3\xd1c\xeb\xaf\f\xd4\xea\x1b\xebi~\xf1\x85%!\x18\x142\x10\xf4Y\x9cn\xf9\xe5D\xaf\x93K\x96\x17\xd1*\xc4<\xfb\xd6\a\x861\xfbxw\xff\x91\xf5b\x11\x15\x98T\xb4\x01\x13\xf0\xc1\x1b\f?]f\x8c\xc57\x98\x02O\x84'-,\x02\x8b<1o^\u007f\xb4\xe2h" + - "\xce\xf0\b\xe67\xa5'Ž%\x1fE@q\xb0E\x90\f>yYp\xbb\xf7X@\x19I\xcb\xe0zo\x1b\x883h\xe5\xa3(x)\xda\xd1\x1e\x86\x01#\x83\xd1K\xe1K\x8e]zs\xf8\x06\xf47\x0f\v/\x0e\xb60;\xfc\xaaYo\t?.\xc2\xfc\xddU\xf2^d\x04\xf6r(\nd\xf0\x02\xb8\xaf\xb7\x81\xefk \xb1\v\xf8\x9b" + - "\xb1\xc5\x16Z\xbaT_?н\x10+,N9\xfa\xbc\x05|\xa5\xe4\x82\xde\x1a;Na\x91\xdc\xc0\x17\x11\xee\xe1\x9d\xc3\xf78̋\xd7\xe2\xf7\xb5\x18`\x94\xd3_\xefJ\x0e\x0fS\x13z\x9f\x82\x88\x92jy\x9f\x03\x85\xaaĽ\x95\x86\xa9:\x1a\x9c.\xadϓħ\xa0\x97\xca3\xce\x1b?]e\xb8\xa1\xbc\b\x12\xef2\x8d\x16@\x9a" + - ">\x1e\xa8\xfe\fm\xedǶ\n\x14\xb7;\x81\b\"g\xd78\xdf\xf9\xc41\xbd\\\xa7\x8bm̎\x8e\xf8߁({t\xe4\x88oA\xf5E\xf0\xd9\xf5\xc4\xd7\xc1'\xf8\xe1'\xf8\xc7\xfb<\xf8Nj\x0f\xa7\xaf\u07fd\rl\"d{\x8c\x14\xf04\xf8L\"\x0f\xfe\b\xf4k\x03\xf7\n\x8f\xb9\xb7\xd1\xd2\xc1U\xde\t\x12\x17\xbeB\xbf\x89" + - "*\x1a\x04\xb9\xab~9Xz,\xd4\x1eG\xea\x0fP\xa6'\xbf\xbb\xb7P\x94\x94\x8em0\x04*R:Ft\xb2\x1doÀz\x98\x058\x8e\x1d\xe6%\xd3\xed\xcc\xdbz\x89\v-d.\x9f\x81=\xb5.\x1b\t\x01h\x9c5\xc0\xaa\xc7\x1b\f\x0f7\x18B\x933\x0f\xff\xad5;\xfe\x8c\x04\a\xcd\xcd1\xe1\xff\xbc\xa8\xe2 ㋅" + - "\x05\xd3\xd9Xˮ\x19\x04Ʉ\xf9\x1b\xc4\aV\x0e\x82̈́\xbe9X\xc3w\x9eB]\xad\x99\xad\x17\xb9\xb7|\x85H\x902\x8f?v\xf70a@\x18\xd8ɋ\xc0\xfe@t\x8e\x87\xcf\xd9zS܈\x94\x17\x94j8IU\xb2\x92\xcb0\xde2\x1b\x00\xe7˂\xe6/^\xc4\xf07J>7\x87\x80\x13\xc9\x11\xafb\xde\x05\xaeN\x1e" + - "\x8d\xc5\fÀ\x80\xa8\x12\x18\xa6\xeb]\xe0\xb0D\xd3Ap!\x10e\x01\x15:\x05\xf4A\x89\xe7p\xbe\x01\xf3\x13Y\x90\x0f\xbc\xfc\xe5b\xc354D^\xe8\xden'Y\xa0\xa6\x05\xb1\x80O}'\x83\xe5\xb2\r:C\xc4Gg\xeb\x16\x17YzE\x89\b\xd0\xf1\xff\x02o\xabu^\xb8r\x06\xb2\xbd\xf7Yg\t\x02\x01ٿ9\xee\xcb" + - "rܼ\xd9 \xb8\xbc\xd7\xe0\xa9t\x15\x03\xe2\x91K\x13\xabS\xfb҉:\xb0,\"\x0e\x9aF\xc6㒄\xf7uܥ\xde܋\xdd\xdby\x10N\xc2i\xbf\x1f\xcd|\xf8ǫ\xa3r:\x9fQ9\xc2&\xfe\xf8:\x84b>'\x00\a\x85~\xdb*\x90\xe5\xdf\x19\xe8[ƔT\xe9{\xe20\x98Y\x00\xc3\xe7\xcc\x10ɝw\x86\f" + - "\x1c\xba\xcb\xd9W.\xba\x151!^=\bV\x13\xf9\xe3\xc0ҫ\xc1tt$\xd6b\"V\x1fQ\x93a\xe1\xa8AIx\xabm\x83|\x94%:Z\x17\xf8x\x0f\x95\xb1Y\x12N0Jx\xd7\xe0\xad\xc5nG$\x15a\xecGT\xdcpZ\xc19\xab\x0fz\xeb/pм\xb1 XL\xc4w\"\xc4Ɛi\x99\xf1\x16\x9cm\xb0=" + - ":*\xb9 \xbds'|*\xfc\fI\x03h\x83s\x9fw8\x19 A\x11\xda\xe4\xe6\xfeЎ\x9aЮ\x11Zj+\b\xd6\x13\xfe\xf5NX\xad-\xf4\xb0\r\x1a\xc0f%\xe5p`?\xabģ\xc4\xf0(\x16\xad\x02n)\xb3\x05D\x9d\x91\u007f\x83 \t\xbd\x00\xa0\xba\x99\x94\xb7\x87\x15n'\xe8\x8f\xfc*M\x97m@\xe9bO\x93\x19" + - "%\x97\xe9\x97zW\xb4_\x14\xa4\x1cj\xc5g<\xd0\xe7\x11\x93Q.\xb5%\xe4\x05\x8a\x9aPR\x98zsؤ\xf0\x93i1s\xc5Q\xa5\x04\xe9\x88:\xdf\xc4\xdb\xf9\x17\xf30\xdb۳\xb0-^\xff\nӓ\xb5\xd3w\x94\xbf@\x81\x03PN2I\x1fә\xffy\x9aMld\f\xb6o\xf3%`\xcfj=I\x89L)\xc6\n\x92" + - "\xba\xd3l\x06<.\x81?\x82}*\"\xe9\f94\xd8\xe4\xcf\r\x884x\b\\\x82\x12Y\x98\x87C\xbcn@\x0f}u\x8a\xa3\xa3\xcfR\xa1\x03p`\x9a\xa7\xc3\x19)\x1e\xf0\x17'\x9d\xb3\xd4'\xdf\u007f\xf7\xdd\xe3\xef\xdcڥ\x19\x02\xcb\xf8\xd3KHd\xc9\xf686\x12W\xd4菎\x87cΓn\xf1d<*\xda>>\xf4H" + - "\x16\xd3\u05fd\x9c_\x13\v\xe2̾\x98\xd4X\x91\x9f\x8c\xc3\x13T\x94y\x93\xa8\xd7\x05\xb7\xbc\xc9\xc4S\x1d\x85{bT\x03zAȈ\x92\xff42\xa2\xe4\xdeȰL\xc8(q\xf1o\xa0\xe2\xc9ף\"\xbf\xd8.\x971\xab\xa8\xec\xe4\x00\x02\x9bf\xe8\xe9\"\xe4i\x8dp\x91\x9be`~\xa5k'\x03u\xd1cӬ?\x9a\x05\f" + - "\x96\x8c\x87\xff\x04\x89\x14Vy\x881Tm\x8b\xa7\xae\\\xd9\x02\xac\xd3" + - "m\xaf\a\xa4\xe5%=@\x8dR\\\be\x1f\xf4兌\x1e\x1d\x89&W\x82\xc7\x10\xa9\x9f\x10\xa9T$\b>Ɂ\u007fRN\x01\xe3\xeaG\x83\xadf\x1f\x98\xdc~\x8a\xe4[\x9c\x16\x1a\x9cآS\xdf\xe7`nIw\"\x9f\x8a\x97I.Po\xd2\x05\xb8>\x94\x1bE\x81\xb6i$\xc4\a\xc2\xf6\xa1Z\x06w\xe6\xa5۔\xf7\xb0=" + - "܃\xf4J\x12\xebp\"t\xefG\x93\xc8\a5\x1b\x1d'aVS\x8b\xee\xc1\xe1\x9b\x02%ѓ\xc7\x14\a\xa0\xa1Nq\xea\x9e\xc6\xf7\xed\x14\xf0\xf1\x86'\xc1r\xe2\xd0}\x11\x12ѡ[\x0e\xa8\x0e\x92\xeb\x87\xd8c\x91\x85t]B \xba\f\x03m\xa2\xe6\xde\xd2Ee\x8e" + - "\xcf\xc59ث\xf3\x83\xc8\xf3R\xc38\xa3&\xa8a9\xec\x06n\xabh\xe9\x87\xe3\xe2$\x9e\xb0*TE\x1fwR8;\xf22B\x94\x1cZ\x84C\x83َ\x83\xec訣vE\x18\x14\xaa7\x02C\x8bA\xf2\xd4\xeaz)\r75jy \x9aJ\xa7z\x93\x8c\xb3I\x81\x1b<\x9d!m\xdd\x1b\x17\x10H8\x82\xba\xe0K\t7" + - "\xa4\xcd\x06E\r%Y0M\x94JTZ,ZÕU\x9e\xf1\xe6\xd1\x02KsV\xc7oR΅a0R\xd8\x16ڌeAiB\x8e\xb3\x13\\\x1e\xfd\xbe[\x00P\xa0Fy&\xdfQ @'\xca߆o\x1d\xed\x12\xfaDx\xc1\xf1y\x9b8\xe4h\xe6\x91\x04Ȳy\x05\xc1|ۦ\xb23\x04i%L\xbd&\xc3n\xd0\xc5\xdbm\xcdOR\xd9j\nD\x9f\u007f\x97\xa1\xb1" + - "m\xbd\n\xad\xdd#\xb4\xb7\xd8\x01r\x1b\x89\x1b\xfeI\xfaL\xdc(e\xd8?\xc0\xb8\xd9\xc2C\xd3`\xafm\x1e\x19;'\x15\x00O\x006\xac\xd6ң\xc8W\xb3\xe6\xd5M\\\xae2'\xbaʬ\"\"\xb6nE_\xe6q\x04\x87b\x9c\n\xee\xdd\xe4\xaeͤG\x1d-\xe3\x14\xfa\xa7\xaf\"\x10\xc1}\x88n\xcc\xdeH\x86\x18\xbc\x0enY" + - ">\x0f7̿\xb5\x8fl\xdf>\nכ1\xac\xa6'\xf8=.\xf0\xeb\t~]\xe1\u05ee݅\xaf\xbfnSz\xde\xc5\xe7\u007f\xb8~\xf4\xa71,\x97\xf1\xeb\xc16\xe1-\x05R\xbbw^\x0f\xf8\x13.'>\xaa\xae\xc8\xe1G\xcb\x15\x04\x86\xdd\x13\x9a\xbe*=\xf8\x9cF\x89c\xdb.\xaeD\xcf^ـ\xa7\xc4P\xd5Ѫ\xca\x02\xb2" + - "\xf2\x0ek\xbb\xbc6\xf2i:\xd73\xb5y!x,\xcb7\xf8\x85\x99U\b\x14Ol\xdb\a\xc0z\x05\xdepI9ϝ\x8fPô\xbb\xf3\x1a\x9e\xf3\xc8+Z\xa5\xfc\xfc\xc3]{\x1a\x16'\xe1\xb1\b\x93\x80\xfacS\xd4G\xe6N2\xb5\xbb\x9d\xf1h\xa0먺\x1a\x9f:\x9a\x15TٞR^\xb4\xcf\x14ႝ|.}\xaf" + - "\xf8\xaca\xc6O+a\xed\r\xff@\xa2\xfb\a~\x13\\\x95\xdc\x03\xcas\x86\xacf/h\xee-\x10\xbd\xdcs|\xbd0\xd8\x1b\xbd\xde۞m\xab\xa0\xc2I\x02:\"\x19\v2[٩\xb8}\x04(\nMcx\xe2\x1f?\xf9\xa33=\xcb\xcfNg\xbd\x89\xfbǓ\xe3\x95G\x9b{\x9b4\x16o\x83\xdakAP\xf0\xa6_}Á" + - "\xfc58v\x06\xee/\xc7ޏ\xc1-\x91z\x17\xa8\xe6\xec\f\xbe\xc0?\xf0-\x83o(}\xce\x12\xf8\x82\x82\xe9\xff\x83\xbf\x05>\xd8>\x1a>\xfa3\xfc\xe0\u007fŃ\x1fă\x1f\xec\xbd\xf7<8>;\xdbuwg\xd9\xee,ٝ\x15;^\x85\xff\xf9\xe1x5.\a\xda\x16\x83\x1b\x94\x86\x13\x9a!\x99\x017\xae\xee]\xe7+f\xea" + - "db\x8d\xedv\xbf\xbaB\x03\xf6ࡆ\xaa\xda\x1b\x89_\xed\xf1L_b\xbb\ab\x85\xf2\x10\x0f\xfbӧM/\xe8\xda\xe3D-\x10m\xe3\x97l\x1eo\xeb\xa5e\xe0T/\x90\x86U\x04\x8fU\xa5\xe7\x86mKD|\xefG\flr\xbd\f\x98\x1dԵ\xbb\xbd\xb3\xc4q>}*\x02`\x06\x19\xacx\x90帤&ݮ\xffI" + - "\x8c\x15_\xbb.\x14\xec\x02\x98\xccT\x91\xd5*ByQ|+\x8b\x8fa\x9e{\xdb\x1eL\xb7\x18!\x8e8\xed)WH\x01@\xa9\x82@\xf7\x80\xfb\boA#W\xa7\x8d\x1b\xf5\x0e\x88\xc1\xdd\xeev\xef\xdebSa\xcf\xde\xc3_t\x9c\xda8OЧ\a-\a\xdd.\xfc\xf9\\?\x85C\x18\xf7잽\xc1ۿ\xf5\xf5I\xd0@\x8d" + - "\xba\x9d\xdc\xed\x82\xea<\x16=\xc9ͣO\x1b|2.\xb2\x9b[\xee\xba)9\x8a\x060\x1a,0\xa9\x9fl/t\xf7s\xba\x8e\x1e&\x8c\xbb\xb8Ri@\x85^\xba'\xe3[\n)\x98\xdc\xcf\r\x17v)\"\x99\xc6\x15\x12(\xa9<\xd5s٢Rp`B\x9a\xf0 7W\x88\xb3\xbd9\x99\xf1\x17adTA\xf0\xa0\r\u007f\xeb\b" + - "\x96\xf3\x9b\xa9\x18gjTn\xa2W\xf1\xf9\x89\x10d\xa9\xceg\x97\x94Q\xd0\xf8\x01%h\xf5\xc0\x9f\f7\xf5s\x94\"\xf9E\xb4\xc45\x8f\xfe \xfc\xb3AJ&\xe9\xc2\xdfT\x85\vgn\f\x1d\xac:\xc3M\x1a\f7\v*\xfc\xb6\xf4;\x19ܱ\x02\x86\x0e\x1eb\x90\x00th\x93\x13\xb4wiU\xeev\vF\x97pf\xd3\xe1\xac" + - "ʡI>\xe1\x10\xf9\xae\x06\x00\x8f\xb4\x86\x83\xa1\xa6~\xc7\b\x04\xb4z/\xba\x9fU\rK\x1b\x85\x10\x92¯\xa25\xed\xddҜ\xf8\xcd\xe6\xb5\xc9#G8\xa9i<:\xb1\xad\xb0\xe8\x17\xe5\x90ˁ\xe3\xc9d\xe9\xc4\xdfÎ\xb8\xc6ֺ\x1c\rF\xc3\xc1#k'O\xf1}\xe7Yt\x8cO\xbc\u007f\x99n\x93\x05O\x1dg\xbdN" + - "\xe6\x03((.\x1fN\xb3ձ8l\xf7\xcd\xc3c\xed\xb8\x1d\x93[W\x18!\x13)G\x00\x9d\x95\x93i\x8a\xe9\x04\x9dLs\xea\xe5A\xa8~\b;͋\xa1\x00\x87\x01\xf4F6x\xe0\xcd\xd13\xb7\xc1X\x9b%\x9e\xeaB\xa8mo\x11l䩻\v\xf8Jg\xf2V\xf0\x85\x9f\xc9[\xc37y6\xee&\x98\x97\x87\xf2.\xe1G\xed" + - "P\xdey\xb0\x1c\xc0˵\xa7\x85\x002]\xef\x04\x0er=X&\x14v\x86ohK\xed*8\x9e\xf6\xfa\xb3\x893\xf1\xcf\x16\x0f\xcf\x06;\xf7lу\x1fS\xf6bF/\xe0\xe7\xce=\x962\xe6#\b\xc3\xd3\x1e\xc8\xe3g\xc1\xf1/(\x87\xb7/_\xbc|yv\xfdt8\xeb\xedj\xbf\x1f@\xb1\xb7P\f\x9b\xce\x1f:O\xa6gW" + - "g?\xcfz'\xee\xf4\x97\x93\xd9\xc3\xdd\x1f@\x8e_\xf5g\x0f]\xf7\xc1\xb1\xf7\x05\xca=qήz.\x14=;\x9e\x9c@\xa5'g\xc7g\xa3\x93\x1d\xbe~A\xbd\xcd<\xffv\u007f\x96\xcf\x1e\u0093S\x10\xf8\x13\xff\x97\x9d\xbf\xf3\\\xde\xc1\xd9\xd4E\xc0\x9e\xa2\xb8\xc6\x01\x80\x00:;>_&Y1\xdbm\xa7g\x8b\xb0\xbf|\xda\u007f" + - "9\xbb\xfdv\xefB\xb1\xcf\xc1\xb1=\xfd\x05\xcbdg\xc9졽\xc3\x1c\xbf;ʁH\x9e\xbb]\x9f\xa3\xa4\u05ca\x92\x15j\x06\xbf\xf4\xd7y\xff\xd8\xfb)8F\xb5\x04\xfa\xf8m\x06o\"\xef\x95y\x0e\n\x98\xc1\xbf\xe3=\xde\xe8\x82B\x97\xf4\xafZ9\xf7\xd6\t\xd5M[\x98S\x87%,\x03\x86\x8a\x99\x92\xc1\n\x03\x1aBJ\x84\a" + - "\xf2\xa67|\x18j\xb7\xf3\xa0o\xe5\x93\xe3z\xd7\xfc\x99\x83\xf6\xe2'}\xad7\x9b\x9f8\xa1\xb8\xfd\xbd\xf2ر\x9f\xbf{\x83)\xd7\xf1\x19t\xcf\x16\xb6\xf7\xab\xd7\x19\xa1;\xc5X\x9c`\xe4E\\\x1f\xda\\0\xbcҎ\n9v\xf3\x02\x19(\x8aM\xd5J\x89F\xd0\xd8AB\r\xae\xb5\x18\x83[\xbeh\xfd\xa5\xa7\xf9\xce\xfck\x8f." + - "]\xd1p\x9dH\xb5\v\x14\x14\n\xb0`\xae\xc6U\xc8\xe9\xc5/\xf4)\rs\xee\u05cd\x02\xb0\xa2\b\xcb\x00b\xf6\x14㣀E\x9fT\x1e\xb12.\x1c\x8f$\x89\xa3i\xc1\xe3ɔv\xef\x18\x85;\xce\xfc\xb7\xc0\x1a\xd9\x1c&\xd4\xebD\xbb]'\x9a\x8e0\x94_\xfau\xd05<\u08d98\xf0#s\xf9\xc5\xfc̥\x13\xaa\xbao" + - "\x10\xa5\x9cxG\xe7Р!ხ\xf8\x91\xafy|i\x02\x13\xbffيq.~\xcdo4z\xf5\xf1\xcdOT\xd3K\xd0\x1f*\xfdC\x93d\x90^\xc1\xd4ɳ\xcd\x00\x94\x1fR\xa4\x9d\xf7\x05\x94Ӽ\xe0\xbd\x1d\x1d]\x83)\xf3>\x06\xbe]\ue7e1\x95\x1cq\xcf\xd5u%\xe2\x10\xba\xc5\xc4u\x13\xf1š4v|Ta" + - "Q@%\x8f'\xb6\xd3f\x04Ւ\x14\xa8\xb8v\rN4}4s\xbd\xf4\xe8(\x15\xf9\x8c\xdeb:\x11\x1c{\n\xb6=\xc8J*\xa0\\}\x12Iԕ\x88\xf0\x1d\x91\x94\xc1\xe3\x14*&Y\xe2\x17\x13C\x83ND?\xf9q\xb64\v\x18\x97JJ\x03R\x98r*\xd5d\xa3\xbcx\xb53\u05ef\xe0\x03C'\xc4RēTL\xf5" + - "\xd5\x11\xf6\u007f\xb5\u007f\xf5իt\xc8\xe47\\\xd8\xeb\xf0\v\x131L\xbcGXⲚo۞\bd\x06\t\xcb#\xaf\r\xd2uUJz\xa8\fx\xf7u\x16T\xb1\xa0\x19ͤ\x8c\xe2\x06Ukx\xc2\x1fM\xb5\xb1\xf7،\xa6x\xcaf \xde@~\x01/\x9a\u007f\xa94\xca\x15\x11\x9d:+T\x8eG\xfaJ\xad\t\x13G\b\xd7" + - "c\x19\xba\xa3P/\u007f\xe0\x0e\x18z\t|#\x9f\xbd\xe6\x1e\x04\xaa\xcf\xc8{D\xd3`\x1a\xa9`\x96\xc8j\xd6\x11]R\xbcH\x13\x86\x8b\x97+)$\x88۔\x145\\geޛ\x86\x9e)\x80\xbc\xad\x01\xf6\xab\x83\xa7\xa50\xbe\xee@\x11\xe070\xda_\r8\xd5\xe6\xc1K\x020\x8d\x1c\x9a\"\u007fXYd\x1a\x9c\xc9I0<:" + - "*N\x92\t\xcd!(\x833\x9f\xfc\xdd\xebpcBO\xad\xfa5?3\x8d\x83\xd4\xecĦ\xe1\xe0\x91\xcf\x0e\x87\x0f*b+\xf6\xd4L\xefvMև\xb9*8A\xf9\x17\x1e\xaa\xec\x00'm\xe5z\\o\xa6\x9f\xf4m\xef)\xbdF\x93\x18\xf8\f^\x88-_*Q\xdf\xfe\x95a*\xa4\xe7y\xa9\x17\xa2\"\xa7\x82\f\x8734\x00A" + - "\x8f\x1by\xcd\x03ɠ͉\x1d!\xfb\x9c{JK\x81\x82\xa7\xfd\xe7A^il$\x1b{\x04F\x80\xd8c*+\xecv\x15\xc6A^\xeb\x1c\xa3\x8c\xa0\xe7 \xc0x\x94\x9c/\x86~?v\xc7ۓx\x1c\x8bPQ\n\xebD\x0e\xaaz\x8ag\x1a\x87N]\x16 +\xf6\xb2 \xc5?9\x9a\x19\b\xde\xd1\x11\xfe\xa93\xf7\f;F\xc1" + - "+\xb732\xd7uAJ\xc1\xffa\xb8\xa8\xf3r\x81 \xc3('8\v\xae\xaf\x9e\xebm\xd1[\x182v\x1f\xc8yp\xe6\x1eʼn\xfb\x92\a\xd2۬\xdc\xfe\xce\xf7jΜ[v\xbdA?\xa8os=\x1a,\xcde\xaf\xe2\x1e-]\x10\xc7g\xcfA#\xb3\xc1D/\xbdĦ\xa3V\xa0\x88\x03F\xaf14\x1e\xbema\x95\xa3$" + - "\xe7\xed\xab\x17\xe2g\f\x1cw\xefE9]\xa0\xe8\xc3\xf8\x89S\xfc\x1c\x82\xc61\xf2.\xd2x\xf1\xa1\xc1T\xd8D\xf0\x13,\xd5\xeb\xf9R\x15\xa33\x91M\x1e\x84\x87\xa3\xc8\x01?\xe9\xf4\xfbZM\xbf\x83ؤ\xe6yPg88O\x17*~X\x8bX\x12\x95ܱ\xaa\x80\xf6\x15\xc3X1X\xe7\x95FO\x868\xb9\xe8\xdbL\xe3K\xf6" + - "3:9Boz=s\xf9\xf2\x01\xadh\xb5b@\x15\xd7N\xe8\xca_\x8eM\xd5mw\x90.\x97\xea\a\x86\x11\x95\xe4j`\x1b\xfa\xf6\a\xcc=\x92\xb9\x83[R\x82r\xfcJV\x0fms\xaal\x80\xf2(4j\xffL\x16`\x9b\xc0\xea \x192\xd4\u05f8\xa5\x885\xdeªȢ\xb9\xa1Js\x83\x85\xb9\xa0\xef\xa8M\x18\xec\x11\xbb" + - ">$\x1eY϶\xfd\xc6rF\x1d\xbd\xb9\xff\xc3&\xf3\xe9\x8d86\xe5\xceʝf_\xbeGp\xb5\x05\xd4\xe0\xf6\t\xd7g\xf5=\xea\x12;\xbb]\xa9\xb1pn\xc2q\xe50mC\x11]IHr:\xa3=:\xea\\\xca\xc3\\\xb6\xf6\xdcv\xb57z\x05\xcdܷ\x01`\xf9\xe3\xdd\xd2.{\x12\x8e(uH\a\x9e@\xbf\xd7\x03q" + - "\xbd-\xaa\x9e?\x81\xc8#>\x85\xaa\xac\xa5\xb4t\x05K\u0083T\xc4۱\x1eE\xb1\xdbi\xa5\x10k\xb4Oۂ\xb5\x82\x9a)\xf4N*[\xab\fÿ*\xb5\xb8\uf307\x85!\x11(5\xba\xa2kx|7\x98\xe6CX\x14e\x82\x18W\xa3\x93qS@\x14\x14\xf8!N\xe5\xc0\xbf0\xa2P\xec\"|Q\xb6C\x14t@c/" + - "\x0f\xe5d \xb1\xc5}*BSv2T\xd1g\x18\\x=8\xdfF\xf1\xe2e\x16\xae\xe8\r(c\x00b\x04\xad\xe0z\x8e\\a\xb5\x91qȵ\xb0\xe9\fC\xb41\xdf\x1b\xaa֤\xa9\xd0@\xf1.T\xdf\xe8\x12\xc47\xc8,\xcb\xdbR'\xfa\x0f:\xbb'\xb6\x00'\x89\xdf0\xb3xڎk\xf2QP\x98\xcd\xd1\xd1\vni\x94" + - "\xde秞\xfd\xbf쒩\u007f\xf6\xec\x99\xf6\xf3\x14\xf9;\xc8#%'\xa5\xab\xd4\xee%.h\xa7@`\xac\x1a\xccG\x83\xa1פ\x04\x12\x9c\xff\xd4'2\x91A\xfc\x11-\xae\xc40\x99Ie2\xc9\x1b;\x00\xeb\xf8=\xb6\x05\xf63?W\xa0\x1e\x80\xa0\x8d8>^\x82B)\xa3\x00<~\x17\xcd\xf5:\xb6]\x9e\xed\x03#\xf1\xe6\x98" + - "=\xea\x9fB\\\xdao\xa2y\x96\xe6\xe9\xb2\x18\x00\x84\xd0\x1e\x88\xb2l\x10\xe67\xc9<\xb0\xc9/\x81\x8ej4\x91\xe15\xed\x05+go\x16\x14*\xea\x01\xe4z\xdd\x13\x05\xeb8\xd3\xec\xab\xfcǛ\x8f!%|wl\x024#\xa4ٮ\xf2>6Ј(\xe3X\xcc\xf6 _Ӎ\xaeс\rAq8/\xa0lE\xe2\x16\xa8\x13" + - "\xd0l\xf3\xa3hD٧t?\x9f\xc6\xf2\vL\xb4\x83\xfb\x16\xe5\x01Խ\xeb\xe0l\xcd\x01\xc4\x18\x1d%&\x0e̴\xcd\a{\x9d\xf752\xf9\xc9{\xe5\"\x98\vF\u05fc\x18\r\x04\xce,\xf1=R\xb4\xfc\x0e\x96\xceO\xe9\x95\xf4\xceP\x80\u007f\xe5\x89\xc1\xe4\xf0J\n\n\x86\xdcC\xc8\xf5\xc30x#\xccv\xce(B\xbe\xbb)\xe2\xcc\xeb\x9e5\xda\xfb\xe2\bƊ\x91\x87\u007f\xee\xd7\xdf\xe1Zڶ7N\xb5\u007f\x0e\xd4v\xce\xeb\xd8g\xdb%[.϶\xc3a8\xb4\xdd\xc9\x019\nR\xf4\\\x8a\xc6\xfd!\x81\x8b;\xba(t\xcb\xd9~\x86L\x01\xcd\x17a\x18\xfb\x067.2\xd8j" + - "f\x1aR\x15\x9c7\x8e\xd2U݉d\x8c\xb0X\x1b\x1e\xa2\t\x9e\x80\x00\x1b\xfeB\x06$`:\xa1\x04DO\xd2\xecSQĘv\\p\xeeג\x85\xac\xa5y\xa4\xe4\x9b\x16\x9f\x9b\xe0\te0̴\xa0\x83\xac\x87L\xd5\xc7@\xddd\x9c\b\x95\x9f\u00a0\xc0\x86CG>\x1e\xbfWa\r\"Vz\x04\xd8\xc0\x91T\xdcb\xe5a~" + - "\xd1[T\x92*\x9ek\xd0N\xc1\x05\xe5)8\xa2\xa2\xec$\x1d\xa7\x14\xf1\x10\xd1i\xa9i:\xe3\x89î@z\x00\xbe\xe07*\xf3\xda{\xf8\xa3\xe8BzH\"\xcc̰\x82Yk]> \x91Rږdz\x98\x14\x18\x1e\x1d̹\xc1a\xc8\xe0\x17L\x17t\xe9\xa50\x03ܚ\x11\xe7L\xf1\xa9[\x9e\xe2\xaaY\xb4w.U0" + - "׀Fh\xf5T\x16\x0f̐$\u007f\x94Z\xfc\x1c\x1dY.\xd2\x16D\x03f\\_=\xf7\xac&\xc0\x957]\x03\x0e\xc8+\xb3\x8d\x16`c\x80\xa6u}c\x9aF\xb4VEU\xa3\x9cMi\xd7\a(\x8ay,HQ\xe8W\xddR@v+\xc3Y\xb2Ȱ1$/\xfbN\xb8\x8d^\x9e\xeb\xaa7@\a,\xa2\x01\x82\x0e\xa8\xd5\xfe" + - "\xa0@\xc1\xbf\xbd\x1e&\r)\xf6^8\xc7\x1c\xdc5\xaf\xad4\xc0\xe5Y\x8f!\xed\x9a(c[d0\x18ka\x9b\xa5q\x00\xf6\xe3m\x8a1\x8d\x88\xff\x18\xf1\x9f\xb9\xd7\x03\xde\r\xb5\x1e{\x19\xd8\xc5\x1eXF\u0603ⓑ0B\xb1n\x15G\x11\xb7\xc0\xc1l\xf3\xe68i`\x00K\xf9\x14\xc9\xd3\x1a \xc8\xe7\x14\xc1S'2\xb5" + - "WJ5\xae\x91\xb6\xf0\xfc\x16\xfe늳\x9e܀\x87\x1a\bV\xe6\xe5\x93ȗ\xe9'\xf0I\xec\xc9W\xdai\xb9\x14\xec\xe9\xf9D\xc2\xe1\xfa\xdb\t\x16\x1ab!?D\x81w\xd5t\xb48\xf2Ȍ\x8b\x1a\x00\x1a\x8d(\xc5\xf2\xab\xc6\xd2\xd0\xdc\xe6\xb0\x1e\xc4iݔG\\\x86\xb0\xb0\xd0=\x89\x17\xec\xe1\xca+\xbf\x06\x052\x03\xfd\b" + - "Q\x86\x9c\xd6\xd5kk\xa5\xb1\xa1r\x81\xee\xd5N\x85t\xbe\x05\xb5`\xf1\x0e\x85F\xa2\xd2\xf8\x1c\xcf|el\x01\nl\xfb\xf6\x87\xc9,V\"\xb1\xb1\xf5\xe16\x1f\x1d\xda\xf6h\x96\xd5\xf6<\xa8\x1b\xdc^)\xee\xb3\xedQ+%\xb7=\x84\x05 \xec4\x99\xb4\x83\r\x96\x19\xa8&J\x97kl4\n=0\x02MLh\u007f\xa0c\xa5q" + - "|t$\xb1i\xa5\xe2h\xa8\xe6T\xa0.TY\x18\f[\x16\xb6\xd4)K\xb9\xab\xa14\xf5\xbe\x1b\xba\xfb\xca\xfe\xd2~\x0f\xff\xa9\xf8;\xe9AE\xddM8`m\x11E(\xe2\xc9E\x00\xba\nd\u0867D\x9f\"\xe8E\x1c\t\xe5֗-\xaeL\xb7-[\v\x88\"\xb1>\x9fj1\xa0\x05F\x9e\xcd\x1a\xca\x1aP\xa1\xec\xe7M\xe9" + - "1e\xa5\xb8U\xc6\xf3X\xf9\x825\xb3\x19\x93\x90\x8dh\xf7G\xda\xd5 s'\x9d\xa1_\xfa&\x12\xdd\xd0\xef\xf0̄Cn\xa16\x84)J\xec\x13t\xbd\xf6G\\@\xec\xc1jóx-\xdbΜ\x1b\x02'\xd8zso\xe3-\xbd\x85w᭼\xb5w\xe3]z灝G\xbf\xfd\x163\xbb\xd7Wg\f\xaf\xf4\x1d\xe9\x8f\xc0" + - "@\x9f\xc1\u007fo\x030\xb0\\\xef\v\xff\xf3\x82\xff9Eg\xdeS\xf3\x16%\xa3\x93\xed\xce)\xb2ġ\xebc\x80f\xb9\x03\xfe<\x18=y\xf2x\xe4\xfd\x04\x1c\xa2\xbe\xff\xfc\n\x05\xf8\xaf\xc1+\x8c\xb7\xf6>\xe1_\xdc\xcb~#\xbf\xbc\x83/|S\xfb%|\x13\x9b\xdaU\xd7\x0f\x9f <\ueb79\xb5\xf9\xe9\xf8\xe4\xa4\x18\x17\"E(" + - "\xed?TT\x9fB;`\xfec`\xcf/\xd8\xfc\v[\xec\xf8\xc6\b|!+j\x17n\x8bt\t\xf8\xc9\xe9\x1bh\x8f7;y\x97\xf4\x8eΔ\xee\x16Q\x8eA,\x8b\x1d\xbf%|\x17\xe5\xa0C\xecb0xvt\xa8\x00\xd8\xce\x0eF\x9b\xec\x90\xfea\xe1\xde\xc0\x97_\xb7Q\x86}\xcd\xe1\x05,\xe3\xf7\x81==;\xbb~4<;" + - "+po\xf9,9;[\xcel\xefC`\xe3~2|\x06;(p՟\xed\xa6\xbf@\xc1\xe1\xb0\x0f\xff\x86Ù۳\xbd\x9f\x83\x0fJ\xaf\xb5\xaflϾ\xfa\x03P\xfe\x83\xc0>;\x9bڽ\xf7=\xfb\xa1c\xf7>`\xa4$\xff1\xf1\x9d\xe9\xc3_\x1e\xec:\xff\x9aM\x02\xfda\xf7̞\xb9N\xd9\xe1/\xf8w\xe6>\x9c\xb8g" + - "g\x8fw\xd0\xc8\xcf\xd0\xc8\x0e\xfe\xc7\xeb\xc0;\xdb{\x1d`\xb4$5O\x15\x1d\xe7\xcevj/\x1c\x17F6\x9b\xed\xec\xde\x035\x8c\xc7ޟ1\x18衻\x1b<\x84Jإ\xf7[ cB\u007f\xa1\xfe{\xd4\xd2/\xaay\xd9,\xd4\xe2\xefe\xd4\xda?k\x15\x1fz\xfc\x0f\xbc\xfa{\xfd\x953=\xe9\xfd\vay\xaf\xf0\x05\xc5\xfe" + - "!\x8b\xe1\xef)\x14\x80g\xff[U\rdU\x00d\x86c\u007f\xa8#\x88@\xf8\xab,\xfc\xda\xf5\xfe\xa2\xf7\t\x18}\x00\xef\xff\x16ܾ~\xee\xab\xe7\u007f\x90\x13\xe6z\xcf~zzzZ\xbe\x81\xf1\x95\xef>>\xfdK\xf9\x06\x1f\xd7\xc8\xe0!\x8f\x8fu\xbd\xa7\x1f?~\xf0\xb5^\x1f\xb8\xde\xfb\xd3\x17\u007f\u007f\xfeN\u007f\b\xa0={\xf5\xfa" + - "'\r\f\xdf!j\xa5\xad\xa8\x1dn6\xed\x120\xf4\xe1\xbf>\xfep\xfb\x0e9\x82v鲏K]̿@\x06\x039\xb5K\x17\v\x98$\x8c~ع\xce\xd9\xd9⡛\xect\x82\xa3\x17\xe27\xbc\xee\xc1<+\xd4ќ\xdb\x11@\x8f\x8e0m\x9c\x13\xdf\xee\xfd\b\xe3z ^'\x8c-\xf2g|\u007fϯM'\x9fM\xbf\x84" + - "\x86\xfd\xba[\xc1X\xf8HʁUa\x87\x1f\xb0\xbc\x16\xee\x84@\xd6\x00r&\xc1\xf4\x17\x80\xf9\x81\x00m\xef\xfd\x17\x86\x98\xfcr;\xeb\x9d\xddR0I\xc2s{\x9f]\x1d{\xff̓XD\xc0\n\x8c\x8d\x02Uv0\x81\xe2\x01\x86\xa8\xb0\x82\x97\x8a\x92Ͷ\x10\xacg\x87#\t\x81Y\xecηE\x91&P.\xf2\n,xq\xb6" + - "\xc0\xef\t|\xef\xee\xceΎW^V(j\xa2\xb5\x04K\tCVf\xb7#\xef\xfb=A>\xd9\xf1a\xc1R\"\xa8)\x8e\xb3hh\x9f\\\x8b\xb0\x87\xd7 \x18\xfb\x987\xf0{\xe5ADsi\xb7Kp\u007f\xf0$\x9bpa\f\xeaE\xba~v\x11f\xcf@\xca9Y\x8fj\xb8\xbe\xe9\xe5w\xdf=\xfa\xe1\xfb]vr2\x1az\xdf" + - "}\xff\xf8\xd1p7\x1a>z|\x84y\x90P\x9dx#\x94\xc0W\xc1;\x11\xaf\xa5\xfb\x17\xbd\xea\xafWS\xfd\xb7\xb4\x88\x94\xa8\x95\xce-\x90Ko\x82[j\xd7\u007f%\xf3uU\xe5\xd6'\xa5{\xbeS\a\xe1\xf6F/\x80\x12\xfd\x98\xe7\x86\x1b\xaf`&\xa1\xcdZL3\xf8\x03j\x9c\xb4VQ\x94\xec\xf7J\u007f\b\v\xa1%\x8bl\x88\xba" + - "l^\x90L\xbeF\xcb\xc4\xc1\x1c\x89\xb5\xb0\x8a¿r\x01\xefˣ\xa3\r@Ɲ\xbdK\xb4 PQ\xf6\xeep\x1fc\xa3x\xaeljA\xbbQG{\x8e\x8e~\x80g\xb1(ō\xd6\v<1\xc2\x03$\x82\xff\x96>dJ\x01\x1e\xa42l\xe4\a\xdcK\xe4\xce(<=W\x8d\xb8\x809鄻]'\xd4\x03.t8\xc2A" + - "\xb4\xa0\x1c\xe2\xa5\u0087Vw\x88\x8e\x10\xa9e\xd7F\x8f\xe1\xb8A\xedY\xb3_\x18ϥSxt\xdc\xed\x8e>h|Z\xe4\xc7\x1b\x15\xd2^\x98=\x9c䧡\xa9A<<ƀ\x96\x9a/\xf4\x19p\x8d\x9c;\x02\x8b\x967w\xf6\xa6J\xe2h\x00T\xf4\x9c\r~\xcdC\x18\u007fg\x058]q?7\x9ej#wP\xb0\bν" + - "\x9b\xa0\xf0\xae\x83\x1f\xf8\xfe.\xf3F\xfc\x8b\xb6\xb7S\xb4\xf8%1\xad\xf4\x1a[\xf3\x9c\x05\x9fǧ\x85\xb8K\xc0\xb1\xa3\x85\xed\xba\x13\xe8AI\x10P\x06\x81\xa3<8\xb2\xc1\xf6\x1e\xe4\xf5\xc2\xde\xda\xf5֠\xb3\xe0%\xcevoݳ\xbb3\xcb\x06\xd3{.\xd5/\xbeN\xb6\xfd\xbe;\xc7\x13/\xeb\xdeM\xe1\xcc\xe9\\\xf0M\xf0\x0f9" + - ".:v\xad\xc8\x06\x88\x1eF6\x17\x81\xe7\x1epW\xdc\xfcq\xc9\xe4\xa8c\xf2f@\x91P\xa7\"\x86\xe5)\x1āC\xce\x00>\x82U\xb3\x8c\x12X\xd67\xb7\vhW\xecc\xd4\x06\xbcW\xa7\xfe\xbe`\x90\x96\x1c\xf9o\x9e\xfd`\x04L\x92/\xdcr5\xa3\x0e\\\xe6\xabV\x8f\v:\xd4_\xfa=\xf8\xf9\xc9^\x80\xe6\xc7\t\x1em" + - "\x06\xbd\xf2'B\xcaё\b\xd0-\xa6`\xddbD\xaf\xe3\xe2\xd9\xc5\x04\x938J\x9d\xb4\xec/.t\xc7\xf5\xf4|F[\xb4\xe5\xfbmQj\xbf\xcb\xda\x16\x8f\xbd\x88.mw\\\xe2\xae\xd3!\v\x8b\xa3'\xd16\xd8$\x9a\xf4\x99\xa8\u038b@\x1e]\xf2\xc3y\x11\x9a\x98\x1a\x9b\x9b\x17Uv)̯\x1dnE\x94^9N\x11\x98\xe9" + - "!\xa5\xb0\xaeWa\xb2\x00\xfb\x1e\x0fn\x03'-[\xdbTZ\xc3}vL\x18qtT7\xaaFA\xa0q7X3\xff\x92\xc7})\xe5\xd4n\xf7\x1c\x14\x94\u007f\xb1\xfa3\x9e\xbeK\x8a6\xeeh\x17\x1eI<\a\t\x92\xf74:\xc7$&n\xed\xd4v_\xe5\xea`\x93\x91\x0f\x8c^A\xbc\xd4'\xaa~\x02'i]\x90\xd2\x13G\xa2" + - "\x9f\xecB\xc4;\x05\xa1\xc0H5\xfc.\xfe\xad\xf6\x1d\xad\x03\x90\x1a\\\xa5\xa0_nK\u007f\x17z\u007f\xb1\x96bG\x8bH\rz\x85\x17W\x12\xbf\x96\x9e\xa0\x80\xb6\t\x95˸\xc0\xf3\x0fi\x95\fB \x83d\x1a\x01s\rg3:\xbe\x1f\x01y\xf3\xf3\xd0\x14\xec\xe7R\x9e\xbc<\b\v0\xae\xff\xf9槠i\xf11\xda\x1d\xaa\xc9M" + - "\xe6\xd6\x1d\x1d*\xa2ib\xe3nl\x95E\xfa\xb0\x020EX!\xf7\x98y\xb0uH,O\xb6\xda\xe8;\xc1=\xfcF\xcf\xfe\x15e\xc5\x11Gv\xfe\x11\xb1+\xb5u\xc0%\xf9\x0f\x81~\xd4\x16\xc3*k\xa0N\x9ce\x90x\x8b\xa0\xf1»\b:t\xbe+B\xb7\xb5\xe6\b\x82\x9f\x18Ո\xb7\xf9\xd4ޠ\x8b蜁\x15̶\xc2" + - "U\xa4y\xf96\x0ee\xa2\xa4uH\f1\x0f\xf4TJ\xfa~\xd9\\\n\xa9\x00\x14^PB\x01\xa8\xab0\xdc\x15\xfeõ\xec\xe0\xbfd\x18I]\x95D\xd3©-\xcd*\xd3\xe0v\xfaɓt\xc35C\xe11\f\xba\xc8*\xf8C\xf8\"J!\xdbhh\xab\xf6TV\x9ai!\x14+\x8eB\xcdq7\xf1\x89zv\xdc\xe5\x81" + - "g\x1b\rm\xf9\xc2uih\xa9|\x85Q\xa1\xd51\xf1\xb5\x90\xd4UG\xae.\x80\xf2XS\xfbq\x1a@-\xe7NN\x82DgS\x85[/nS\\\xa5q\xec\xc5/\x80\xaar\xe0GG\x12\\\xf4K\xce\x025\xf6nwwf\x9f\xb5\x8f\x9b%\xe4x5\x8d[\xbe\xf2l_\xfag[Zy\xe8\xf9\xd7\xf0J\xd6\xf4\x06\x0f}\x9b\xf6" + - "݀N\xe8\x16J\x96\xcb\xf2\x92fn\xc0P\xbab\xe7_\xa2\xe2M\xb5\xc0n\xb7\x18\xac\xd3\xdf\fOSSɼ\xf6\x10)\xaf.\x13\x06\x00\xfe<\x05\xe2Cb\xa1\xf2\xc1\x8d\x8a\xbc#5\xdf+\u007fO\xf3\x0eb\x96\x06\xb4\x16\x03\xea\x04\xb6\xf7\x1a\xa7\u007f\x15\xac\x14\u0085\xd3hU\x1e\xf3E\x83n]\u007f\xbf\xd6\xdf_\xca\xe1/T\xde" + - "'\x17\x87A\xa9\xb93&U\xa1\xf7i\x1e!\xf4\x13\x933凊\x16?auM\xc7Gm\xbf\xa8\x1a cm\x8f\x01\xf0\xd6q:\x19\xcf[\x92i\xb1\x8b\x1d'QPM\x12-1\x95\xeb\xb36\b\xc1\x88\xf8\xfe\xa8\xf5-E1\xd7Y'\x05gpF\x88I\x964\xa7\a\xbe\xd1v\x17\xd4\xed>\xa8a>\r\xee\x8b%\x11ګ" + - "\x8e\xdc\xf2\r\x15\x91&\xb5h\x1fȁ1\xb6\x0f\xb0\x14|\xd1dt\x84\x87\x8e2\n\x95\u007fN\a\xac\xf0n\x8e\xd6\x1e\x814)\xfb*\xe3fťs\x85)?\xfb#\xbf(\x1f\x14.\x18J\xf3\xc9KN\x9ds(\xd0W\xdf\v\xd7\x1f\xfa\xdf\x1eEXe\xd4>C\xf4\xda$\xbe\xcah\x8cr\n\xbc\xb02#\x18\x99\xc1f^\x1c`" + - "\xf2\x83\x16\xbc\xe2\xf6f\x8a\xee+W\xa3\xb1D\x8d\x03\xe0O\xf1Gxx c\xf2\x9f\x05\x81jEذc0\u007f\xa5\xdd\vĪ\x11K>\x10\xa7\x87)\xe3\\P\x98K\xc5z)^\x82\x02߃ F\x1b\t\xa4p9\u007f\xd0%E\xec\xd3\x1b_\x14\xbbB\xe0c\xf9}\x84\xdbr\x89\xeb/\xf7\x1e\x188\x82\xb5\x99\xb7\xf3\xc8sI" + - "\xa7\xd3d\x82I\xad\x8a\xe2\x86\r\xd25\xd9cҋ\xc9ȋ\xa9\x14\xaf\xff\xed\xd9A\xf7\xc1\b\xa5\x80\x87+\xba\xde8L\n\xb0\xf3\xf5\xd1њ\xf3\x9c\x02X\xcd\n\x05\x85\xf8\xe5\x92c\x883\x95\x9b2\b\x90\fz\xccE\xda\xe0\x9a\x18\xea\xbcP\x1e\xc6\x11\xf2\x8f\xf2A\xe9%UaQ\xda\xfe\xb8\xc2I\xe1-9B07\xbd<\xc8" + - "7$ܨ\xbb\xaaL\xf8\xbc\x03/\x97<~\x11\x9bA\x8b,\xa8jA\x87+\v\xd6P\xf5\xa9T\x1d\x01\x98\xa5\x1f\fǟ8\x96\xf4\x92^\xad\xa4;\x89(\xf0\xa5s\x01*\x93J\x00B[\xbb\xba\xb1\x88s3\xa9\xe9\xe3x[B\x18\x18\xf4\xe1\xc4%\x0fm\xbea\xf3h\x19\xb1\xc5$\x1c\x88\xfbe\x00\x91\x18\x81\x02\xa3\xa6\xc0Ѡ" + - "-\x9a\xda>\xbd\x01\xdc^[Tʳ\xb6I\xc6\xe6\xe9*\x89~c\v\xbcT3cy\x8e\xe7\t,\xbb\xc78\x12y֑\xd34k\x9a\ue157\x94j/-\\\xe0\x04\x99\xb8\f\xef\xf9\x16\x0f\x06\x81.\x94\xe39\x1d\xce\vO\v\xd4\x1d\x90\x8b\x8aK|P\x89\xa0ԐO]\xefT*\xc5x^\x1e\xe3\xd7\\\x12\x01\xd3\x14}\x1a" + - "\xe8\f \t\x9c\xbar\xf5F\xfd\xbe\xcb\xc4\xf1#\xf2yx#\x15\t\xc1\x00tt<`\xc0\r\x1e[3An\xdbt\xdbQ\xa4\x89P:\xe1I\x8b\x0f\xf5q\xe0\xe1?\xf0?#\xfa\xc9\xf3\xd47\x02\x13\a\xb8\xc3$\"V\x14\xe7\xd3\x1f\xd2\xf69\vt{w\xcc\xc6\xf8@\xf7\x90%\xbd \xc4\xd0K\xe9\xc7\u007f̻\xfe\x96z\xae\x84" + - "\xcc\xfe\x83\xaeqR\xc1nc\xc4W6\xa3\x1b\x03\xa8\x91R\x12%`+p\xff\v\xe7\x03yp\xab\xb9P\xfd\xef\x86\x1eWW\xdf\xe7l\xbbH\xfd\xb8\xf0\x88q\xf8\u007f\xf3J\xb2\xc6\xf3Chn\xe0ߌŴ%\xe7\xdfb\x8e\xa3\xdbE\x94\xf9v\xc9bmq\xce\x0eC\xfam\xcb\xf0~\x8f\t9\xe4\xe3\x8c]F\xe96\x17ï\xd4" + - "\xfdW[!0\x81\xe1\xd1K2F\xfd[ڈ5\x19\xb7S\xba\x91j4\xab\x19\xa6\x1e\x9b>\x9e\x05\x0e\x9b~;\x83e?\xfd\x0e\x0f\x80hQ\xac\xa2\x90\xfd\xaf\x80L\xb4\xe9#\xa4;\xaab\xe3j\x80/=\x8a\x82Q\xc4\xeb}\v+\x84\xef\xf2\x1e\x84\xa2\xc2\x15<;).x\a\xf0J\xb6\xf4\x18\xef|\x84\x1ev;\xb9\x80)\xac" + - "\fA\xfev\x16\xf4\b\xe6\t\x82\x8c_\xbf\xc7\xcc\xfb\xae\xff\xe8\xa1c\xe3V,o\xec1\x1dgY,\xe4/\x17\xeb~\xc7\xeb\xfei\x06\xe0\xff\xb9Q\xc0\xc7?\xc0Nj=\xee\xe5vvÀ\xc7$\xcb\xd8(,`\xc0\x8e$\xb2\xbf\r\b\ab\x1f\x02ۘ\x107rx\xf3\bz\x87nj\x80:\x01\xfe\U000b38e3\xbf\xf2\xe2\x98" + - "\xc0\x17\x8c\xe05|\xa3\x83\xcf\xf4+SW3`>*\x99\x91\xa3\x9f\xb8}\xf9\x9db\xd9\xe9\x040\xfc\xa3\x90\x88y\x16\xb1\x8fL{\xa2O\xd7c:4\xb5\x14ԃ\xfb\xfdw;3\xcc^fn\xc4O\x1a\xa1~@\xbd\xe6@\xf9\xfbE\xba\x03tQ\x9el\xe7P\x9a2\x1f(93 \xf8\xe8\x94;\xdeo\xca2c\n\x18\xa1\xae\x97\x10\xe1A/" + - "ı\x11W\xa6\xd2\xdd\x16$\xdb\xc9*\xed\xac\xee\xdfNq\xd2\xebe\xe6f(bA\x929\xd8,\x81F\xf4\xbf\xaa\xd4\x12\xb7Y\xb8\x88R\xb0|8\xbb9O\xaf\xf1;\x98\xe9\f\xff\xe2\xadmWi\xb6\xc0\xef\xd1:\\\xe1ý[" + - "ji\x98I\x133\xa2\x95\xcd\xe5\xdb\xf35\xa6o\x19z\x19\x03\x8d\xaaY~\xc1\xcb\xcb\b\xad\x15\x86\"\xeeWz\xde\"\x19\xf0\x90\x97\x10W\xd43\xca\x1d\xb0*\xca6\xd6E\xfd\xe8\x90\nN\x0e\xbeH\xd3\x1douP\xc7e&C\u007f\xae\xbc\xa0c\xd0lpoe\x06VB:P..\xa9帷\x94\x16\xc1ɂ\u007f\xf2\xb0b<" + - "\xe8\t+\x83β\x06\xb9h\x063\x95J\x03u\xb7ˁ\x18\xf8\x94\xe0\xa9^\f\xe7\xc4\x03G\xd0\xc4\xdfU\x13\xc2\xd9\"\x82'\xe5U\xb1\xea\xc2rJ\xbcB\x8dj\n\x9cE{\xdfe\xa7\xca$\xe6\x13\x10R\xc2#\x81=\xb7\x03\xdd\xfd\r\xd4J\xd5\xe3n\xb7\x85\x9fx\xcbF\x16\xe07\x87_W{'\x14\xa1'64\xfc\xac\xadw" + - "~T\x91\xdb3\n\xc72\xa8\xdd\xcf'\xa5\x97\xcb\xf5\xbf\xc0d\xc5\xea\"y-*\xf5\xa6\xa8\x9e\x81Ң\xd5m\xbbz\n*\xebѥ\xf7\xdc\xfd^\x06i\xa8\xa6.\x8b\xea\xaa)@\xb6\xe2\xc5#\x98tVs\x89\xa2\x91\x02\x8a\xee\xb3r\xf7\xa9\xe0biR1\xb9\xa3\xd27N\xf7\xf2\b\x1b\xafЄQ\xaa'\x16\xa6`۪\xd5." + - "O\xf5\xf2\xc3l\xc1G\xa4\xc9\x1e\xdd \x9f7\x1b7\xb4\x0eBW\xb4\xa36e\xf7\x9a\tx\b0\xbaΤfTz\x0e\x1aęfXn\xf8\xaeWL֥\x1b\xf0;\x11b\xdd\xfd\x1ds\x89.\xadU\xde@0\xdd\xc0\xb2!g\xab\x80o\xb7\x8b\xf8\x03,]\x02[\xce\xcdy%\x18\xb8\xb4\xc7*\xf8R\uea1á\xdb\x0e\x94" + - "t\x06\xb3+\xf2\x82\x06\xc9\xef\xa3g\xb2\xec\xf1\xbahxq\xe8\xb6g\xa0\xe5!e\xa9\x15t\xb6\x15\x97\xc4\xf2=\x83q|\x92\x8fs 6:L\xcem\x1c\xca]\xe9\xa4\xd4\x10\xfe\x0e\xe5\xb6\bf\xde\x16\x17o奍\x15\x960\\i0h\xb6\x10f\x1fBK\f\xf9Ip\x85.Y\x8a\x8c\xecD\xfcY\x84ϰ\xbc[\tQ\x15" + - "\xa7/*\x9e\xa0\x80\\\x1b\xf0\xcfE \xef\xa8F\xc7\xd0n\xf7\xb6p\xf08\xe6C\xdb\xcb\xcbh\x05\x18\x8f\x9f\x93Y\xb7\x0e\xf0\bF'ų\x9d+\x1fP\xb5\xf2\x96`\x15c\xf3\xdeM\x90L\"\xbcGp\xc2\xfc\vL\xd49\x99\xce\xfc\xd0_\xd3\xd6$\xe8\xe5\x0e\x1e\xfc\xa0\x920_\xdb\x00*\xdfx\v\xf8\xe1l\xf1\x16\x19z1\x0f" + - "\xb6\xd5\x19\xc4\xdbj\x9c\r\x90ٜ0z3]\xc074\x1c\xd7\xe2\xdbƥp\xf9\x94'%\xc5-\xc2[\xbe1\xb4\xc5\xd1̓\x1bc{7\xbc\xbd-\x9f\x835\xfc\x82\x86\xc6\x11\xbf:\xf3\x86\x98;\x80\xb3\xbf\xa3:Pu$7\xc7So\x03&,>\a\x83\x0f\xcf\xc8c\xf4\u007f\xc7\t\xf1\x0f\xc2\xc8W\xc2\r\x8d\x1aw\xcc'7" + - "r;\xec\u0093\x9d\xb8\xfe\r\xcc\xe7D\x80\x11\x02\xb6bח\xb1\xff\xf0\x13\xfd\xb3\x8aD>\x16\xda\x06\x19%^\xd6\x124\xa4\x03\xb9\xfd3%\xb7;rf$\xe0\x10\xdd$\xea\x15J:\xa0h\xdc\xe4\a\x81\x1e\\\x9a\xa3F\xb9\xb2H\u05ca\x03/2\x17z\xa9\x12u\x90\xbd+J\x03\x95U\x93\x16(\x8d\x1a\x8fz\xe0Ѫ\x0e^\xa1" + - "\x04$\x83w{\xb8%\xbd\xcdEq\u007f#\xbe\xb8{~\x99\xdd8\xd2r\xf9UG\x19\x8bQ\xba\xd0+\x00\t|c\x89\x19\x04\xb8\xef\xebV\x94\xe7\xc2N+\xad_\x99JO\x85\xf0\xc2[\xab\xcfg\xdc\xfcȂ^/\x86\x9e\xf9EߔSU\xeb7\x93\xfdV\xdcZ\xb0\x10\xe3\x13\xa0\x03\x0e\x06}E\x81\xa5\x9c\xc0q\u007f\xa4n\x16\x17" + - "\xf2\x13f\x83\xb6{\xe2\xfe#\xde\xe4\x04V\xa1o\xdb{-m\x9f<\xa2\x0189\x89\x8f\x8e>\x96M⍯@<'\x19\u007f\xaa\xfc\xca\xea)\xc9K\xa0\x1fu#\xbf\x80\x94 ,\xc9\xeaY\xe5\x14\xc2P\xbb\x10\xf1D\xcf5\x02?\xb4\x1d\u007fT\x9f\x90\xad,x=q\xf0\x1a\x97\xd1%4q\x1e\xd8CۻF\xff1<\xb9\x12l" + - "s\xe1=\v\xb6x\xdez\xb7\v1o\xad\x8c\x0eŰKoqt\x14WN\xc8\xc4x&\xfbcO\x1c\xf2\u007f\x06\x14[Il\xb8\xdb\r\xb8\xce}E\xab2\xe6a\x02t[\xab;\x16I\x1f/\x82\xb78\xa5\xe3s\x98D:\xd4E\x01\xbe+u\xb6m\r\xb8_\xe1V6\xba\xb0aU\u0090\\\xf7\x96\xe7\x18w.\\\xe1\u007f\xc5\x0e" + - ">\x06_\xa0\xe5^\x0f\x91\x88.ϋ\xa0\xb3\xc6Ǝ\x8e.\xfb}/\xc7Ci\x87\xccA\x85ۖZ\xfeۚN\x87\xc1\x03E匼" + - "\\\xd0\xdc%\b\xeb\xd8K\xb4\xcdx\xd5З\xdaYF\x94\xa5R\x88\xd20hd\x11wi-%'\xbf\xa5\xa3\x84KԖ\x96ھ'(\xc4r\x06\x1e\x81r\xf9\xfa9.y X̞\xea\n#Z\x05\xae\xf3\x83\x13\xfaQ\x9f\v\\(\x8a\xf7\xe4\xb4aM\xbc\x87\xc2\xf3\x822\xd0\xdd\xd9JF\xa6\xdb\x04b\xd7\x1c#\x8a@\x96" + - "c*\x94Ny\xdf\xe2\xb8\xe4\x19\xb9\xd4\xf0\xb9\xc6,Ǵ\x0f\x83\xbf\r\xf4C\xc7\xf28\x1b\xd8GyӃ}Kj_\x0e\xa6\x83\xa7\x01\x8d\x12^痨Fn\x02\x0e\xb8\x90\xaaQ\xb09\b\xbf8F\x97K\xc1\xd6\tg\x88~6\x9e\x06\t-tV\x06\xdd?` wxb{\xf6\x1f\xb8cG;\xf7Q\xf5\xe8`y40w;\xcc\xc6G\xfe%\xf2w^\xb0huQ" + - "쮢Eqa{f\xf9Ow<\xd7\xe3\xa8<[\xee|\xd6\x1c\xcc\xc0\xec\x1fՏ\xed4ÅM\xa3\"\x1f\xd6q\xfd\xfcJ5\\\x9bH\x9c\x87l\xdbw\f\x99\x17Uc\x165ۆ\bZ4\xf7\xa1u\xda}h\x84\x06yp\x8aB\x85ڦKf\xb7\xa9BTFx\v\xa0~l\x80C\x86\xd1Xû\x13\xb5F\xabE" + - "Z\xb4Z$\xa2\xd5\x18ϛ\xd6\x19Nj\xd3Bql\x94\x94\b\xd7.\xc8\x04\xcaD\xbc\xc9*AL\xe2\xd9\x14\x14\x19\x9e\xd5x\x93)/͵\x90?AE\x12\xc1c\x9eo^E\x84Q\xaa)L\xf2\x98\xceձ8x\xa6\x02\x0f\xb5 Ľ\f\f|G9\x99$\x0f\u007fY\xba\n\xde\xe1~dy\xf1\xbfH\xbc\xc38\xbbq>" + - "\x12k\xf4\xaa\xdbutP\x15=S^\xb1\xbf\x1e<\x03\xa9{\x1eο\xe4\x95@5\x16\x18\xb2ལ}I\xec֮ܿ\xd5\x15 V\xd2\xd6p\u007fR\x87ѕ\xe9\xa4'\xcd+ٝ\xb8\x1e\n`\xb2u\x9a\xdd\x00\xc3\xc3|\xa7\xa8\x90\x81\xfa4$\xcb4\r\xe22UOg8\x06\xf50=\t\xc7!WYct툔" + - "\xeb\xc8\xf8\vi\xb7\x8f(¯H7\uf497\x985\x13\xd3c\x82q\xcc9 \xf9\xa10\x9d\xf6v\xb2U\xbcs\x0e\xccY\xc8\a\xd7\a\xad\x00@\xf77r7\x82.\xd1\xd8\x04\xb7ᢒ\xc6\x1c!\x903 \xc1\x1c+2\xb7\"\x1c\xa2LB_˔\xceŷ\xc8=\x04\x12\xba\x92+9\x9b0A:GG\x1b~\x1f%\xcc`" + - ",u\\\x9f\xb6\x83$\xe0e\xe2\x00ʂ\x87:0\xe6\xceԯ\x95\x9f\x94X\xf4\xb9Ǯ\xf0掦b\xf0$\xf7\xfc`\xb0!O{\x8c\xba\x1f\r\xa3L\x14g\x88\xe1\x96\xdbb8.\x91\x13\x11\x06K*<\x98On,\xe5V\x86r\x8b\x12ԝ \xc8)h\x97!}C\xf9\xba\x97)\xf7q\x03\xd4\xc4\n'e\xe3\xe8C\xc3" + - " \x97\x8eӉ\xc1|\x8f\x95H\xaf︔#\x91\xf9\x05y\x1fbz\x8d\x05\xb7A\xa6\xae\x92lnY)\x9b/\xde{q\xaa\xdft\xa0\x9a\xd8Bu`\x97\x1a\x11\x89ְ\xbc\xb1\xad-\xed\x16PRnc\xc2R\x1c%:F\xb6\xa4mR:K\xaf\xc0\r\xfc\x82\xab8\x93B]x]\x80\xde7\xd9\xca;\u007f\xfd9nߊ\xee" + - "\xb1\v\x03\xb8\x9b\x81\xec\xbb~}\x81V\xcf\x04u'\xda+Ƴ\xd1\x13\xb7\xcbtm\x86\x1d\x9f\xe9\xd4\x16\x19\xc8AF\xe1U\v`I\x95<\b\x0f\xbbΙŹ\x02J0Qv\x01\x86=V\xa4\xdc\b\x9e\xbd\f\xa3\xf8\xaez\x9fi\x1f\x8e\xea%i\x11-o\xf0J\xb0,]a\x94q\xad\xae\xac6\xc3\xd0\x01\x1b\x8fBQ\xc0P" + - "\x16\xdcR\xf26\x03ʒ\xbd\x17\xc6W\xe1Mnx\x17\xf1\x1b$J,\x0e\x10\\\xa7\x81\xd5\xe2\x82U\xae\xca\xe2\x19\tT\xb1\x92\xa3\xab\xe4w\xe5!m3wI\x85F\x1f\xa4\xc8\x12\xf3\xa0\x9a\xf6qZ\xa06\xca\xe8\x10\xc5\x14\x93\x82̜F\uf807\xe4\xe6\x9b,\xc6\"\xc5\u007fٞL\xf8\xe6NX\xfd\xf6\f\x95e^\x8c\x1d\u007f" + - "\xe3|\xb8\x039\x03\x0e\x1e8\xc4Y\x01\x9e6\r{6R\x9f=\xa3N\x89\r\x96\xe9\xe4\xf8\x052^N9XKx\x90Ձ\n\xccevY\x18\x83t\xe9\xeb\x81$\xf1\x13E\xa8\f}2\x18V\x12i\"\x14\x04z\xb4aA6\xc0\t\xf2\x9axf:\x9e\x1f!\x9e1\xb3\xc88\xe38\r(\xad \x1a\xcd\xf4EGq\x12\xe0\xac" + - "OG\xbf\xb0\x19ԓ\xcc\x01\x9e<\xa2\xdf\xc8\x1c\\\x0f\xa7f83]\xd1\xc6\xdf\xd4Q\x15M2\u07fcj\xab\xe5\x01.\xb9\xcaI\xf5\x94\x18\x8b\xe8\x96EqoGD)\xc3\xf7\xdeU\x854+\xdb\x12\x8d\xb4\x9f^%\xa9\xec\x88\xe7\x18:@,\x99\x8f\xb2}\xc4\x0f\x1d\xf9\x95Ԏa[*M=N\xb3@\x85\x87\xdfL\x88\xdf\xea" + - "\x17s\x9c\x8c&\r\x10\xfd\x8cb:\xf2I*\x88\x8e\xf3:\xe9r\x81\xd2\x05\xde$\x12t" + - "ڠ\xa5\xd7\xea\x1c.\x94\xbf(\xd6\xf1)ˢ0\x8e~cA\xa7\xb5\"N\xb6^\x8fF\x1a\x1c\xc3\b\x8fE\xbc}\xcd֣\x02\x88\xba\x82\x02\x8bަٚ\xfaX\x04\xf6qHʰ\xd1B\x87\xe2\x02E\xc1\xf1/\xc3\xc1w\xaau\x8eZ\xf1\x0e\x8b\x01\x96\xe9b\x0f\x00ZC<=·Hh\xef0\xbdt\xca-Cj\xb88" + - "\x95\x01<[\x15\xcb\x03/\x18,\x1b$\xcfN\xa7A\x02\xc0\x1a\xd60nQB \xec\xbbg1,j\xb0\xd8\xfd$\xbc\x04ҧ?8s\x8d\xea\xf0\x02jϱ8٭\x9d\xa1;Ha\xb8\xb4\x8a<\x8c\xc4\x03IJ\x1fQ8\xbcEW\xd5O\xe1\r\xbcF;\x06P|\x01\xfa\xff\x97\x9f\xb3pC\xefs\xfet\x13]\xb3X\xbaQ" + - "\xf8#\x9eU\xe1\x05\xbfN\x87.\xe0\xc4\xcbԱOJ1\u009fd,\xa6;\\\xdf\x00㌒\x0f\xe8\xf5\xe0/`5\x9eF\xbf\x01\x85}\x10%\xf0q*ê*\xcd=\x13\xcf\xd2ڈDY//\xa3\xbc\xa8\x1a \xfc\xb9z\xb0U/)ߑH\x05\xb1\xa0\xf9\x15\xa7\xf8.\x80\xff\xd7G3ڧM\xb4\x8aE\xc7#'\xcc" + - "\xde\x11\xc4-\x14\n\xc8K\x92\x9a]#\x9e\xa0\r\\w\x8d\xb6\xc49z\n!\xa1\xf6\xe8\xdb?dyj\x95SV\xbd\xa6<\xcb\xcf\xd9f\xfdmRr\xd4X\x8dL\xfa\xc7\xd4\x15\x1f\x18c\xa1\xf3\xa6\xd4\xe5\x17\xb7\xd2\x035\v\x02\xef\x82\xdc9U\xc6\xf5ɩ\xfcR\xe1\xe4\xaa\U000a26a8\xc6Y\xd4\xd3\xd3\xcc\xc1\xf4\xf8R\xc9KS" + - "\xa7\xaf\xd1\x1e\xa5C\xbd[\xa8\xe5\x88\xe0\x8de5z\x86\xe7K\xa6X\x1c\fE\x8c\x12\x8a\xa4\xa9ɟ9\x06\xce۽%GU1]\xf6\xec\x1f\xb7\xe7@?9\xa8;sʲ\x8b\xa7\xdaK'\xdbt\x8e\xe1 \x9cl\xd0U0^\b\xb6\x80v\xc0*Ûb\x9f\xc5\xd1&\xb0\xe7<\x12\xb6\x0f\x94o7\xe06WAf=\aN" + - "\x9cѰO\x89\xf9U\xda!\x96l\xaa\xab\xc6o];\xf5hruU\x0en9\xe1&\x90w]Wڅ\b\a\xbb\x05\xd4MX\xa4\xfep\xbc\xa6\x15\f_\xce\xd3\f\x83\xfa\x86cXX\x98\xf0\xd6?G>\x01\x8f\xaf\xfb9\xadh_\x83p\xdc_\xa7\xbf\xf5\xdb\xde\xf1,\tm\xafm\xa2T\xb3`\xe0\x02\x05\xc4\x1f\xbap\x9c\xa4E" + - "\xbf\xf0\x92\xbalT\xc0\x93\xeb\x15\xferO,|\xd9\b\xe6\xe6\x87\xe7\xa0\xf8\xc0̎Q\x8e\x0e\xc7(?\xfd\xfe\x0f\xf0\x01\x91ʑ\xd0\x17\x12֮\xad\x96ĭ\xfc\\Ԕ\x17\xa9\xb3\x14\x19\xfc\xb7@\xddeA_\n\xfe\xed\x18\x9f\v}\xc6> \xfa\vLU\x91\xd2~Iul\xf7\x99\xab\x84\x8c\xe3M\x80q\xc8\xd4F\xba\\\x02" + - "\xfd\xbf\",譊\nH\x83)\x1d\xec\xab>\xe5\xed\x94\xfc\xfd\x15\xe5\xfdxG\x8d\xe5\xc1\x86\x1f\xc4ivP\xc1\a\xae\x82\xc6\xf4(J\xe0\xa0\x1biH\u007f\xd5$!\xed\xad\xc4\bjC\x02\x15\xf8\xb5J\xb8\x9c\x12\xbe\xad\xcd\xee\x1f[\b\x02^\xa0\xa1\x8f\xd9\xee\x9dX\\\xc1\x10\x8ba\xfc\x96\xa6\xeb\xc9-\xfe\x8bi\t\xf0\x98\xa9\xce" + - "\xbc\x94\xc4\v\xbe\xa5e\xcb\x11\xf33\xf6\x8eV'\xce\xf6\xb3t\r\u0083-h\xa5\xe3e\x9e5\xb9k\x8f\xfe\x88\v\xd6i\x16v\x16\x04\x8bK\xd7\xcbc\xc2/\xa3\x88\xb5a\x94\xb4\x99v\xb0\x01\x8e\x10*\vm\xd1/R\x89\x0f*\xad|#\xa5\xa1\x8c\xd6g8W%֚F \x9fQ_\xb4\x11\xbe\xa8>\xa1\xc5֢Mh\x97\xad" + - "\x99ƕ\xe9\x88\xd1:E\x1d\x91\xfb\xa0\x17\xda\xf4a\xbe4\x92F\a\xe94\xef\xd9\x1cIHM:\x91I\xca\xe2\n֘\x93\x82ݮq=\xaeS\x82\xeaJ\xad4\"R\xbb\xc6I(\x0f\x99H;V\xd1\xc9+X\xfb\x8ec\xad\xa1\xd1=\xee\xd4{m\x03\x10P\xa1\x13w0¨\xa9J\xcaG\xbc\x87$\x00\xad \xe0w\v\xa0\x03" + - "%\t\xf2\x80;<Ӏ'\x88\xf8f\xef\x00\xf6ɡ\xff#ݱ}v\x8b\xf7z\x9f\xce\x1e\x9e\xedwgS\xf9}\x869\x8f\xdfC\x81\xe9\xd3\xfe\u007f\xe3\x9d\xd7\xe5\xe6\xc4\ay\xa1\a\xb9\xc9\xf9=\x1c\xa0\xe6\x85\x05\x1e1\xff\xff\x99{\xd7\xf5\xb6\x8ddm\xf4\u007f\xaeB\xc2xɀ٤(\xdb\xc9$\xa0!.\xc7\xcei&q\x9c" + - "ؙ$C\xd1^\x10\tR\xb0)\x80\x06@K\x8e\xc8}\xed\xbbު\xeeF\x03\x84\x9c\xcc\xfa\xf6~\x9eo2\x16\x81F\x9f\x8fU\xd5Uo9\xf8\xb9r}\x82Ø\xb5\xd0,\x8b\xb2\x89V\xe3k\x81\xdb\f\x135\xa37蟅\xf8st\xc4\x06y3\xe8\xed\xcdXC\fZ\x9dt\xaa\xcf)w\x9a7\xecU\xf2c>\xbcf\xdb" + - "\xador\x84\xbbu\xd8\xdc\xd4\xfeI\u0092X>ʎ\"\xe1\x87\xe2\xdd\xd0\xdeP\xe5\xecF\xecz\x00\xcfWP\x1e\xdcs\xf8\x97u:\xfc\xcb\xf8\xeew\xcc9Y\x89\x13\xde w\xb0\xb5n~\xe2 6\x1d\x8eYGLA\xff,\xe6P\xfb\xc0\x1a\x8cq$/\xb4\x8c\xb5\x13\x93x\x82N\xd3.\xb3h\xac\xe1^fߕQ6f\x9b" + - "%8\x87\xe1\v\xb8\x9cݟ\xec\xa5\r\x82\x90BU\xee(.\xfe\xeax\xbd\xeb\x1cT\xbe\xfdq\a2\x8erg KzK&v̧\xa1}dta\xa8\x18\xf2\xad?\xeb\x02fc\x04\x84\xf8#̈́\xc0\xd3\xf8\x1d\xad\x82q\xc5\x10:\xacm\xa4]\xd2*\xa7\x05T{v\xf8WP\xbcI5\r}8\x1f\xae\xdb'0\xcc\x12\x01" + - "\x9f+\xc7\xcfD\xe0\xaaU\xd4J\x97\x9a\x17)&\xd5$\x9d\xb2\xeeG6>\xfc\x0e\x98D\xecT\xc3q@\xe8[\x95\xcc\x1d\xf0K\f\xa0\x9dm\x89\xfaN\xda\xca\n\x94\xdc?p\x90\xc1\x1d\t\x90\x1b\"0\xc3\xdaOb\x83\xd3\xd9n\xe3C\x1au\xf1m9v\xf2\xe5n\xd2Kz\xb7\xab\xa5\xf0\xd2\xf37p\r\x83\xfcC\xc6\xd1f\xa5t" + - "\x95\\\x9e'\xac\xd6.S9\xf4f\xab2\x9d\x87O\xef\xff\xfd\xc9\xd3/?\xfb\xaa\xff\xf8\xabϞ\xf6ONf\x8b\xfe\x17\x9f}\xf9y\xff\xe1Ç\x9f~\xfa\xe0ӇC\xfa\x9f\xc7\x174\x9ca\xa7v\x9d\x03\n\xa5\a\u007f\xe2\x0e;\x16r\xfd\xa6\x0e\x0fa\xf3\xfa\x1d\x9b\xa0̛y6$\x80?\xebwsW\xf5\xb4\x1d\xd7\xc6\xfcU" + - "c\xb0\xbc\xfe\v\xd9)\xf6\xcb\xfa\xfa/e)q\xeby\xbf\xe7\xc8Յ\xb4=lB\xdc~q\xd8m\xac\xd36\x82\x81\xd4P\x06kr\xdb\r\xbb\xb1\xc2?\x84\x9d\x9ev\xf3\xdai\x02\xef\xc0**\xc7\xfb\xb1\u007f\xd3\xee\x17ש\x94\x1c\x02q\x84+X\xed\xe9\xbcF\\\xba\xd1\xde7\xec\x05$\xed\x1c\xd7<\xa9\xa1|\x02\x89n鴙" + - "\x16\xc6k\xf9\xa6\xc4\xcf\xe0\x1c5,\xe1\xc1Q\xdf\xfe\x96\x0ek6\xb2\xa6\xa9\xfa\x8a7*p\xc3\vVX5\x8d\xe7=d\xda\xf7D\xb1\xc6]\xd6\xc6\xc0\xfdSZ\xc4w\xa8Tj\x0e\x03Ўn\xa9\b\x0f\xa8մ\xd2VB{\xbe\\\xc5\x05:\xdf\x018$\xa2n\xb68\x18\x87\xb1g\x87\x18\xfa\xcf\x13\x8aYk9Fm\x13e\xba" + - "\x12\xce\xe5D\x17\xa1{\xae\xb7܃\xef\x15P'\xaa\xeb\xb7s\xbd\xe1\xdc1\xaa\x14\xec\xe1\x8fO\x8f&&\xb3\xd1>\xd7]ݫ\x1dt>W^\x1f\n\x9b-k-Ψ5\vӎӧЎ\x87\"\xaf*6b\x80\xc0\x1euĿ\xa5\xbc\x9e\x84\x1e\x1a/o\f\xe6\xd1+z\x9e\xbc\xf6\x8a\xf0K\x03\xdeA\xbb\x8buX\xea\xf3" + - "5\x8eu\x88\xb9\xd3])\xcd\x14Me\xd7If}\xa8}\xd7\xe9&\x16:\\\xdcvO艽=\x9e\xef\xd2\xd8`\x8ci\x03\x8e֡\x88_o\xc5\xef6\xc9&\t?\xaaʒ\xc0$\xdbgR\xe2\x1a\xee>8\x89\xa70\xc7_\x9b\xd6\x04P\xbb\xf4\x0fS\xf1\xf0k.\x1eƍ8\xf0\xf0j\x9c!\xe202Z\x86\xac8ˊ" + - "r\x00ќ'{U\x82\xcbN\xa6\x9e\xa8|Q\xe8\xa0l9\x96\x98u7\xeey2k4\x83=\xe05G\xfb6\xcfߖ\xc6\x04\xbc9\xe7\x93:\x9f\xdd\b\xc29s\x11\x1b\t\x11\xeff\bdqX\x01\xf8\xa8\x88L\xcf\xcc⧹i\x89g7h\xb1P\xf8Pƃ\x1a\x11\x970\x198\x84\x86\x01\x14\fY%\x80o\xbfp?" + - "\xe8Ե\xdbW\xa4\xeez\x8e\xe1շ\xb0\xf5 \xa0\xf7\xeb\xee\xbe\x11\x8d\x83\xdb/\xa3\xdb׀\x94\xd8Y\xa2T\xb2\x19k\xec\xd3\xcdO\xa2ѱ\xb7\x83\xef\xcf&\xa3Vr\xdfX;\xee\xf9\x94`\xd1\v\xdc\x01\xa2W\xa5\x8f\x8b\xd3\xf6\xae56\x03\xae\xf7~\xda;B\x86N\xe7\xcd,\xec\xdcp\xe4\fs\x13\x8aw\xcb\xe6\xac\xd0;\x91" + - "\xd2cJ\xd5qG\x12뇊\xc3\xf1g\xa6J\xbduu\xcc\xd5?\xdb\x02;3Y\xed9\a\xb54\v\xf5\xee\xf5\x18\u007f\xa0/F\x1c\x15\xeb9\x81h\xb5\v\x82\xefTM\x1b;5z\x1cWi0\x1b\x18e<)\xddu\xc0\xe2A\x13\xa7\xc0\xb0\xee\x14\x87\xfd\xf4\xd1\xe6饣\xebA\xeb\xb7\xeb\x8e\xdbuny\xc2k\xb2q\xaf*" + - "W\xe8\xae_-\u2e5c\xaau\\\x83ƊA\x19F\x1f\x99J\x15\xdb\xee\xeb\x1d\xa3FE(\xecv\x04\xc2T%\x8d\x05\xc5[X!k\x12\v\xbf\xd7S\xfa\x8d\xd7ɪ6\x1fZ\xf9\xeeEf\xc6g\x18\x9a\xf8\x87\xfaM\xfd\x12\x1dOΪ\xb3\xe2,;[L\x8f\x97\xea_\xd1\xf1YA\xbf\xbf\xff\xb9\x13\x9e\xad\x1c\xf1\xec\x8b\xe7\x1f" + - "\x12=\xde\xe2;\x87|#!m\x17b\xfc\xed\xa7\xa8\xa6\xcc[\xf7r\xea\x9f\xce7.}\xd4X\xb1 t\xba'\x9f\xf5S\xc9Ct\xcd$\x91\x02\xb9\xb9OQX\xe2\xf7q3\xb7\xbfF\x10 \x91\xbb \xa8c\xd7\u007f\xadJ\x88\xf9gUz\xdḙ\xb1\xb6\x90\xfe\xeb\xf4Z\x16\x95\xea\xac$\xa8\x02\xdesp\xb7o\xb6u\x1dP\xfb\xba" + - "\xe0\x15C\xb3\x84\x11\xa1\xf7\xf5\x13j7\xa2\x96~\xad'\xfb\xbe:#\xd1\xcd#\xe6e\x1b\xbeQ\x83\xdb\xfb\x12:}\xdc'\xbc\xa5s%|\xad8\xc1=%:c\xf5\xd5,\x94\x95G\xac)ȴE\xa4\x111\x1a\xaa\x99\xa3\xb2\xd6i\x14\xbfw\xd0//\xa26&7@qM\xbe\x02\xfa\xe4\x04\b\xfc\x93\xa1\xd1~aKِ\xb9\xd9" + - "\x9b\xdc\x1ag\xa4p\xd6\t\xe3\x8c\xe1\xa9\x03rfѣ\xc0v\xf7\"y\x1e9y\x1b\x8f\xedE\xa7\xca\xe0\xfff$@ηgR-\xb3\xf9\xfff|\x9c\xda\xfd\xdf\xd4\xd8\x1eT\xb6\xd0\xe4\x06?\xc3\x05\xc1\xe1g7gԜ+\xec \a\xb6\x95\xe6\xa4\xe7\x1dmO\xf8\xd9\xf2\x8eS8\x1c\f\xfa-S\xb7w\xdc?\x8f\x8e~\xdan\x0f\xbf\xb1\x010\xa7\xa7#\x99\xef3\xeaz\xa1\xfb\x8fWO\xccZ襖\xdb\xdau\x01tT?\xdb\x1b\xcd\\\x87\x98\x95\xa1oT\xdb\x135" + - "혨\xa9\x18\x13\x16a\xf7\"I\x1b\x8bD\"KS\xcd\xe0i\x18\xbd\xbfx\x1cQt\xa6\x94\xea\x13\xa9\x1a\xb3\b\xfc\xbb\f2\xa7\x93a\x10\xfe\xbe\a\xbe\xb6\xdd\xfec/\f7FP\xa6\x1d\x0fC\xf6s\xbb\x83k\xed\xbdI\xe4:n\x12\xc2ro\xe9\x85\xfb\x13\xbe9I\x0e\u007fb\xf0\x80F\x87g\xc1\x9f-\a6OT\xd9ng" + - "\xac/\xf6W\x9c8\x83\xd4+\xf9\xf8\xec\xaaw\xbc\fT\x97DT'u\x9d*0\xa1b{v\xd4\x15#\xdakXcrZ4䮴8x`\x96ڙoE3\xa7\xd0yt\x1a\xa0:\x86\x9c\xfb\xa9i-\xec\xf6\x96\x89k\x82\xfc\x91~\xed6w\xa5\xa1\x97\xa6\xfa\xce\xf9\xa0\xd7r{F\xb8\xa5un\x1cc\xbfi\xfc\x1be\xf0" + - "\xaa\xf2\xc7\xd1\xd1\x1fz\xe9\xf0u\f\x15\x89\xf2\xfe\xe8\xce\xdf\xe0\x1e\xed\x19\xf4\xd6\xe8n@\xc5iL3\xfeδ@\xc3Ӱ\xa8=Փ\x91o@\xcc>%\xf8\xddB\xe1\tZ/\xc3~6i\x9e\x82\xc6(\xacd\x1e6G\x03\xae\xfc\xf6\x033\x11\x98\xb4\x83gy^\xcc\x1b\x0eE\xfecKf\xcfc\xf7\x90\\_k\xca,\x97\x84" + - "5\xd1=\x10\tg\xd4\xdaN\xea\xc5Й\xfb\xa8\x06c*\x1c{\xe9B\x17R\t\x01\xc6C\xb8S\xee,\xd1\n\xa0\xc9<\x15\xb0\x80\xce\x1d\xc4\f\xbd'`\xe4t\xcci\xfb\x1a\xbd\xb4'\x9e\xb6\xac\xf7D\xbd\xd3k[+7閽B\xec\x94\xd4W\x84\xfb\xa4\x83\x17o\xaa\\\x88\a\x1cM\x81c\x0f\xd32<\xc0\xbe\xa0+Ŷ\x06" + - "\xc4v\x14\xb3f\x85خ\xb7>.\xaai\xbb\xb3ossX\xc1cC\xc3\x18\xc7ؤ4V\x9eXMܞgC\xb9m\xbb\xad\xba\xa8\xe3\xeeȸ\xd8\xf2\x9a\x15p\xcc\x1d\xb8\x1a\xb6]5q|\xcbɔtx\xf5\xaaX\v\xb2\xc9\xe1|\xc4\x19q#\xa2P\x8b\x9ai\x93\x110\x87#4\xec\x93x\xfe# ҕw\x19_\x8b" + - "\x03\x11\x10\x12\xc9j\xf5\x02\xe6\x1e0\xd6\xe4\xb7\xe7\xa2߇$\xf9\x15}\xca\x10\x9e\xaf\xf4ӦL~\x88\xd70\x1f-h\x9d~\xc9J\xa6\x1c\x81\xa7\xf1Wz\x1a\xbb\xe3m\x06\x1b\x87\x970\xdb\rV\x96\xa5\x04\x8d\x1e\xd5V \xb67)\xa1\xb5\x1d\xf1\xe8!\xe7\xea9\xad\x14bLy\xc6\xec\xa9]z\x83\xa9ߟ\xfd\x99\xb3!\x1b\xb9" + - "\x02\x9f\xc2\xc68\xc3en\x12\xc3\xdcd`n\xf4\xbefj\xae\xcda\xb8\xe6\xcdB1\x8f\xa3[\xa5\x13{\x10\x0e\x9ai\x1eC7?\xd4d!n1\xf9\xee\xe6\xdf\x1f\xb9\x9f\xe1;\x16*\xea\xf8\xd5\xdb\xe4ñ\xaa*\x89{\x99Ӹmg\x82\xd0B\xfb\xfa&ز\xe5\xc0\xb1\xcat\fm\"\xc0?[\xfe\x9bo\xaa\xf3զ\x80\x8e" + - "b\xc1\x91&\xaf\x06\xd3{\x01\xb4\x19\a\xfe\xa0\x17l\xe9K\xad\x0f\x91V\xae\x13\r\x1b\x9c;\xc1\x8e\x93\xe8\xb8\xd2\xf7\x15\x86\xdal\xe2)\xebۊ\x04\xb7\x154\xcal\xfep\xb3\\\xe5\xe7\xf1\n\xaaX\r\x1c\x01ѓ\xa4C]\x96U\xc3\fOi\xd0)\xf5\xbe\xbe\xdcg\x86\xe5=\\\t^\xf0\xc1\x02\xf1\xc9,*\x88S\x9b\x99\x10\"" + - ">f\x16\xad\x82\x9d\xc6nR,ny\x88\x8c\xa6c\xa0\xfcU\xf4^\xaa\a\xd0B\xe7M\x00\x12\x17\xf4.Y\x06\f\xa9o\u07ba&\x82\xe6V\xafE\xe2\xc92M\xce\n\xe2\xe7\xe52)\x18\rYD\x1btș\x8fКezN̍\x17\x03\xaa\xf4\xa5cźS\x12\x14%PSeň\xa6`\xde\xf3\x001\x91\xed;\xaa/" + - "#\xacD\xc0~fpT\xcfv\x82\xcb\xe8C\x04|!u\x19\xf9\xe5\xe4\xbev\xbf\xa3\xf5\xfe\x06\x06\xdd&PK\xea\xd2ud\xeaȧa\xbcb\xbf\x024xKb|\xc7k\xd6\xca[\x12e\x01n$\\\x0f@\x943\xe3\xb8\xdd.խi絢\xa70mK\x95S\xf7p\x1e\x1fD\xf5-Wz\x10\xc3Ba\x98B\x194e" + - "\x863\x8c\x95\x8bV\x14\xc6\xdc\xd35a\xbc\x0fe\x14S\xd7\xd1V\xc7F\x81\xa1q\x01I\xadݩ\x19\x8d\xf1E\x84\xdaa|\xe5\x89\xe1\x13m\xeb\x9e\xe4\x9b\f&\xbfk\x9c\xa7\x1b\xb8W\x90\a\x8b\xe2O\xb3s\x01>\xe8\xf0\x84\xa5\"4\xb3\xd9\xd8\xe7\xfb\xb4\xa4V&@\xb2h\a1\xb8\"<\x8d$M\x8b\xa2\xa4mP\xe4\xf5(f" + - "@'\xf5\x1ay`H\xf0kJfc\r\xddUf~7\x03\"\xf9\x81\x1a\xed\xf8\xc2\xe2\x126\x9b\xd6\xeb\xa9!e\x15^\x88\xc4iΛ2\x8f\x9c\xacVt\bD?\xda\xc6|\x1f$c\x1fTSu\xac`\x1av\xad.\xe9\x83\xf1j\xae\xe5K^\xc0\x97f\x1dB\x01\x87\xd1*\xbb&z\xb5?\xd1\x19\x93\xcb\xcc\xf5\xca\xce\xf5y\xb4" + - "\x94\xb9~\xf1\xf1\xb9>\x87#\x93\xf6t\x9d\x9b\xe9\xea\x17\x1f\x9d\xeas\xb5\x88f\x1c\x9b\xe5\x93%\xbb\xacr|\x02\x9d\x9d\r\x02\xafw\xa1\xe7\x1c\xbd\xd1\xe6;\xb8G\xbf\xdb\x00\xdaM>\x9e\xe0%H\xad\xa2\xdc\u008c\xe9\xb6\xe5Զ8ZL\xa0\x1f\x9a\x1e\x1d-\xd9nҬ\x16\"ԡ\x10\x84\xf1\xe5p\x99\x00%\xd0\xe1\xf4\xa4\x1f\xd8" + - "9\x0f\x95p\xa2j9\x9eYE\xb8\x99\xb8w\xcf\x13;\xf5\xc3:\x9c\xf793Wr\x00\x95\xb8i\x16\xcd\xc9\xd3\xef\xd3Ԕ\t\x81\x85!OV\xfd(\b`\xeat\xb8\xa8\x15%\xd7T\xb5\xb8\x98\x13\u007f\x82\xe8\xe6\xd9$\xb8P\x97f\xb3\xd5\xeb\xc9pڲ\"h\xca\xd71\xcc\xed8:?\xa8=\xb1͡\xba6\v\xccpJr\xa4" + - "\xecab\xf0D\xc5lnk\xb2\xcd \xe3\xd49\x9a\"\xf6Ԑ<\x99\x9f\x1e\xfb\xb0қz\xbd\x0e,\xa8k\xc7\x19\x16M\xe8D\x88\xb1\xfd\xbe\x97\xc6\x1aT,f~1\xa92Z\"\xf57;r\x1c\xc1\xbe9\x937\x9c\xb0F\xea&ZD)\x8e\x9bX=`Ψ\xbe\xab\xf9\xbc\xf5~\x98\xe9\xddp\xd9\xdb;\x98\xd0\xfae}\xcf" + - ":\xe0\x1bV\n\xbb\x8c\x96N\x99T\xfdK\xab\x9ev\xa9\x97O\xc0Bx'q\x88Kt\xbdyeQ\xe6h9\x13\x13\t\xd0\xee\xeb\x81\f\xe7R\xed[\x10Д\x86\t\\Z\xbe\x94\xaaE\xf9\xf8~\xf8@9}\x109\xfb\xb7\x1bNC\x159\xaf\xe3\xbd5x\xf9\xa7k0\x14\a\xa1P\xff!\xd6=\xaa\xe0M\x92}V@\x94\xac\x1f" + - "\xa3\x945\x00\x99\xe6+\xd8+|C\xcfP\xb1\xe4\xec\xd6\xd3\x0f\xaeYצہ\x8c\xa3\x1f\xf5\xe1\x0f\xd4C\x9e\xf9r9\x008\xdeC\xf8\xe3\x11sN\xd6%N\xcb_Y\xf1\xddO\xb5\xfe\xf0,jnO8}\xcdH\xcfzK,\xe7M\xb4q\xbdt\x8c6\xa3V\x88\xde\xfb7\x80v\u074c\xe0\xb5\xc7O\xdb>:c\x1aU\x1do" + - "a\xa5\x1bir\x05W\x19\x92\x95T\fP\xbd\xbb\xb9\xbḑ\xc2/&s\b\x901\x03\xa9\xfaА\x89\x97\xec\xe1\xe3E\x95\xaf\xd7\xd0\xcc\nd\x11D\xf3ӓ\xf1\xcc\xd9_і2\xf2\xcda\xb1\xa9W \xdbFM$ٴ>N(\x86\xac]\x9a\x1b\x0e\x86ˆ\xfa\x952Z\xc1^f5\x15$O\xc7rc\x13ب\xcd4" + - "\x1aH\v ,\\\xf0Si\xb6h\xfa\xea:/\x15\x0f\x13\x9a\xa6??\x97\xc8h\x18\xb4T\xd7T7\xf9\x80\x017Ϻ\x14\xed\x9cɔ\x15\xb4j\x96R\x00\xd5:\xa5\xf9\xd31\xfaQ\x8a\xd6\xc0C\x13\x1e\xc4\xf2A\xed\x13\x9dK6#G\x1e~\xa0\xc9\xf2\x0f\xac\x1c\u070eX\xd5y-\xecœY\x0e;\x06\x81bR5l\"\xa4" + - "\x99\x8c\x16鵿\x8f\x81\x06jj\xd5\x01\x97\xb2\xa9\xc7Un\xe7\x9bC\x9b\x98\xbbT\x86Lk/'\xfb\xf5f\xc7j+\xe2K(\xa9\x17\x82\xacU\xce\xf8p\x86\xe1{\xaa\xeb\xbe\xdd6^\x9d\xabl}\xe8\x047\xa5-N\xd3R\xa5\x1bKm@\x87\xdb\xe9\x9dӑ\x9f\xe9\xe9\x9d\xdc6\xbdo\xe8L\xdc\x14X#\xbab\xb9\xa6\xf2\xeb" + - "| $7\xc5Mb'\xc3\xef./\x93y\n\a\xa1]9\xfb\x87Ic\v\x84H\xd0}\x97} uH\x01vҤ\x8b\xa2\xc3/J\xd1m0\xa7J\xc5.\xa7\x88|\xbf\xddݩ\xa5:\xa6b\x94(\xc9\xe1LO\xd79\xd0\xf3Y7lU\xdbc%f;\xb5ˉQp\x9a\xebI\tV\x9d\xd3D?\xa8\xc1\xd9h\xc4\xf2\xb2" + - "2Cvt\xd4|o\f\xa1J\xea\xe9j\xba\xf36#\x8fzvfM\xaa\x86\xe6f\xa2\xb7{\x9e]\x00\x14wt \xa8˵\n\xe5\xd6\x13\x93\xffC\xeb\xed\x84\xf5\xa7F\x9bC\x9ez\xadmv\xbbeM\t\xad)\xd2Ȳ\x86|8\x14\xcc\xfd\xfd\x8cy\xb3\xcfQ_̚\x95\xb5\x0f\xc9D\v+\xb5D\x1ak\xab\xe4\xb8K\x93\x01" + - "\xe0Ǵ\xc1\x15\x8d\xaf\xe9\xa4\x12\xb5\r>\xb6i\a\x84$Dn\x03\xf4'\xed\x17zc\xfdB\a\x9c)\x14\xc9ťE0\xca-aWj\x8f\x11\x18\xfcpS\xf7|\xbes\xf6\x11\xad,\xb9jE\xe7\xc2l\n\xe3\xe5\x89\xcd2\x19s\xedz\xcf\xc2\xc8!)\xacÅQ\x131\x9d1H\xf2(1Zw\x94\x8d\x88r\xd2\xe9\xa84" + - "J\x1dN`D\xf1\xf4\xa1\x99j},\x16\xb8\xc8\rU\xd2\xfa\xf46\xf9\xa0\xaf\xae\x80!\x15\x95,\xe3*\xe5\x1b?\x1a\xa3<\xfd\xaaU\xb2\xf8\x19`]\x0e\x11\x04\xb8\x8a\xa8h\xd2\xfdDV\a\xd0]\xa8\xa6J\xae;\xe8O}\xfbhI\x12\xf3\x88\x1b\xb9b\xa6\xe5.8\xa8\x958I\x92\xaf\xee4\xb3)\xecG\x87\bP@\xa1\xac\xe2" + - "\u007f&\x1f\"\xb8\x84\xd2Ϫ\xd4\xe0\xeac\xf3\xc0\xc0_a\"7xe\xe8ū\x8a\xe2\x1d\x9c\v\xe4\xc4\xc1,\xcef\xc9\ns\xf9`V\x15+|j\xec}\a\xbc\xf2\x9f\x133\b\xd3\x00.\xe3\x80Q\x84\x93\xb9\x8e\xc0\x14&\x82\xa5\x8e\aUz\x99\xbc\xa8\xe2\xcb\xf5\xc1{\xa27\xe0\xebbv\xe19\xb6\x8aʌ#\x04K\xf5\xd0\xe8" + - "\xea\xcd.hb\xe0\xcf\x13j\xe4\x01}\xc6?<\xb7\xb2`\x8f\xb4\x9d\x02d\x03\xd1\xca\x05s/\xf2\x93q\x1310\x99\x8f\xebǰ\x1a\xe8R\xe0\xccw\xa7\x9c\xb9d\xea%[ȁ\xfcP\xb7\xadR\xea\x96\xdf\xf4\xef\xef\a\x8b\"\xbf\xd4Cz fϿ\xe9\xdf\xdf\x0fh\x8fL~㿿\x1f\x94\xb3\"I\xb2\xdf\xf4\xef\xef\aU" + - "\xaeS\xfdI\xf3\x1a\x1baI;\xa0T\x847C\xa7\xecQ\xab\x0f\xb8hs\xb5\v5K\xae5\xdf\v\xdb9\xd5&\x1ci\x1d\xa6\xd61\xbdΗw, b(\x9dg\x9dY\xcfgk\x15jP\xbeZ}\x9f,*a^\x1b\x01à/\xb1$\x8d\x13\xcb\r`\xd7\xe6\xdcM6\xf7\xdf\x1b\xb9\xbf\xcc\u05cd\xcc\xf9\xbd\x95w\x1d\xc7y" + - "\x1f®&\x194\xe6-Sj~+0Z9K\x91\xaf\x1eu\a\x84+T\x8e'\x12q푨\x9a\x99\x99urT\x02\x1c\x99\xfe>\b\x1f\xd2\xdf\xfb\xe1P\xe6\x91>\x90ÛU\x1e\xcf\xe1\xfcQ8\x03v\xd9-\xde\xeen\xf6\xf8Rk\xaf\b\xf6\xbf\x02M*\x9b\x1f\xa2\a\x8e\x00\xb7\x0e\xa5\xf3\xf8\xf0\xc4\x15આ\xfc\xc3\xd3" + - "\x82fo\xa7 ]\xee,\xd2\xc93j\x14\x8b\x14c\xdf>rQ\xda\x12k\xaf\x88|Sy0\r\xa1\x93\xf0c\x858w\xb0BI\xeakX\xe2B\xedu\x82Qe\x14(v\xad0J\xf9\x8e\xfd\xfa\xb9\xae\x8b!һ\xee\x9e\xdc\x1b_=\xae\n k\xd4K\xe7\t\x9d\xd1\xc9&\x93\xc1qi\x94&ŬI\x14K \x81\xb8J\xb3" + - "x\xf5\x95\x16Y\xa0\x1c\xb986Qqe\xa6\xca\xf4r\xb3j\xe0pjћ\xb9-\xb6\x92U瀁e\x16\v\x18\x12\x95\x96/t\x0eb\xf2\xec\x96\x1a¨`T\x8c[L\x01q\xa4\x02\x87\x10\xec˫\xb5g\x10 %\xde\xc2\xfb\xec\xf3M|\xd5\xe2\x88t\xa2\xd8}\xb3\"\xd3\xf6\xe5i\xd2\x15\v\xf2Ҏ`\xf6\aD\xe3\xb8" + - "ۻ\x82\x95\xbb_\x96LT#\xf0\n.\x98\x93Q5\x13\xba)eO\xa6\x85\xe1\xa9\x1a\x91}V|AC\xa4\t\x9d\xd7P\x98U\aiVV8\rq) \x91\xc7>\x83L\xf2\x15\x80̼\xc6(D\xda,\x84\x19KM\xc4p\xc0~\xffFV\xc5\xc0\x06\x81\xf6w'\x8f\x88\xd0\xf8^\xeayc\x1c\xb4\xa5\xf4\xf3\xd6\xe0\x8c\xd3*" + - "\xcc+M\xabH\x15\xa0\xd3dg\x95P\x85Zg\xd8\x1eʑ\xb4ȼBf\x97\x11\x83*\xd1\x1cJ\x8d\x81\u0382\x86\x00\x88\r\xfbL?:\xae\xdfn\xf6\x9bK\x15S]̕\x84\u007f\x84GB\x84\xe6,\xdcǚ\xdd\x1f\x88\xd1m\xbd\x9eV*\xe9\xe0`\xc6\xfb,M\xd8\x1c\f\xccH\xd5\xe2q\xfe\x93\x9a췬\xaeK+[\x83" + - "\xfc\xdd\xe0\xa6\x14IJ\xa0\xcc\xe4Ĉ؊\x1f\xb1\xba\xfaέ\x98.\xff#]\x8c\x8ap\xac\xbdBk\xf5\x86\x1b\xa6\x80ЇE\xe8\xf13\xad\xdb\xc2\x13\xc2h\x95\xc4\xef\x13\x13\xcc{~[Ӡ\xc5\xfdO\xa3\x9b\xc6qQ)#1\xa2Ga%\xba\xf4\xe4E\x1e\x90F\xad3\x9a\xd1:,C\xac)\x1e\xb6.N\x05R\xfc\xb0\x06" + - "\xa5\xf7\x8d\xcf/Y\x9dDz\x1b\xceXe5\a\xdf\r\x1d\xact\x1a\xa8\n\xb6U \x18\xf1M\xa3\xb6\x89N\xaa\xdbb\xfd\x9d\xaf\xbd7\xeb\xbfr\x04\n\x1a#\xd4Ll^0+\x94\x8f|\xda\r^K\xa6 \x87װ>5\x01\x9e\xda\xeb:K\xc1\xb0\xde}\xad\xdal\x8fZY\xf5u\xb0\xf6G\n\xe15j\x12\x12\x1d\xe9 !\x14" + - "\xcak4\x98\xad\xae\xdcj\xda\b\xdduJL\xf0\xebs3\x99\xb97o\xc9\x1d\x02\u007fFU\x87\xb5\xdf\xed\x87r3\xcf\xfa:\xa0\xfdE溫\xcf\xc1r\x1a-\xb0\xaeo}\xcdq\xed{\xa6\r\xad\x84*\x91\x9a)s\x0f\xf2\xbf\x1cX}\xc7!\xdfm\x8fq{\x1b\x93L\xc0\x04o\x9fd\xf2\xfd\xf6I\xf6oa\x82\x1bf\x15\xc1\xd8" + - "\xf7\xbb\xa9\xac\xed\xd6Ѱ5\x81큖:\xaf\xb5\x8bu\xa9\xc0\xe0\xb5\xfc6\xc7\xdcbE2=ݤ\x98Lz\xb1$\x92\n\xbe~\xb3)+\x9dӜw\xbbZ4\xba\xb7\x12\xba\n\xdcϥ=Н\x05\x9d\xd4\xc5\xd4\x13\xc0\xe4\xaf%\x88\\\x1b!6;zC\xa8HV\xa6\xa0\xc4ݕ3\xdaGZHeF\xc6Um\xb5\xab" + - "\xadR^c\xe4\xf7V\x9b\x8d\xd0]\xd6akڂ\xa4pHIy}i\xae4>\xde\xf8\xbd\xd9\xef\xac۽z\xba\xeb\xf6\xb6M\xbd\xee\x03\x87\xf0\x82\xd1\xc6\xc7k\xa9\xa7&[w\bKPOb\x1b8vN\x85\x8f\xef\xeca\xf5'\x8b\xb8s\xa1ꎡ\x89й\xb2\x9a\x8bW\xf3\\v\xf5\x9asU\xb8>˒\tG\xe6\xb2" + - "O]v\x8d\xb0ds\xbbro\xd0*ew\xfc\xa6t\x9f\xc7l\xd4>\x90\xabiǮ\xc1~\xe3{=\r\x00ߤ\xd1\x13\xb9\x86\xed\xee5$\xec\xf73$\xec\xa2\xefM\xda=8\x88\x86gmո\x8e\x8d\x15\x03\xa6\xed\xc3\xda\xd0Ʋ\a\x92\xc6\xc8[\x05\xabh\xd3Y]\xfb\xd4M\x02!\xcf2?\xe6\xdc\x13v\x81\x15\xb83\x0f" + - "n\xe1\xf4ݠ\bI`\xab\x02T\x0f\xdc\x19F\x95\xb1\xcebT\x8f\x0eH\xb2\x94\x95\x98(\x9a~\x92\x1a\x00\x8b\x8bo&\xd2(\xafF\xc6\xf3\xeaa\xea\x9a\x00\x9bJ@\xb2\x9c\xb3\x83\x93\x94Ru\xb1\xaf~\x00\x18=\f\xe5-\x1e\x0ev\xc4ϱ\xf2Hi\x94Jʖ\xd2T\xa7\xd9`=\x8b\xecVF,'[\t\xc0\xc62Ϻ" + - "\xf8VW\xf4\u0a12\x80V\xa6J\xdef\t\xa1M\x1f\xda47\xab\xf3\x9b\x05[\x9b<:\x81\xea\xdao\xdf\x11Io8\x17$\xe3\xfa\xb2\xa3\xe7\r\xbc\x9e\xf3)\xac?\xa9Zޮ\xeaK\x10\xee\x97\xdb&\x1a\xcb\xef\xddyD\xe5\xe6Ԯd\x92O\x9b\x93HS\xa0\x99\xe6\xe0n\xc3\xd43\xf3\x83-\x94\xf8b\xa5\xa0\t\xf2'\x83\xe3" + - "\xeeA\x89\x1d\x9d=\xe1\x8a+\xff\xfch~FP\x90h\x9br7\xbbo\xb5\x1aW\x97\n\xb61W\xb5j\xdf\xfb\x19j]\r(hʭb\t\x1d\xc6\xc1\xe4U\xf8\xb7\xb3\xc9\xd9@M\xef\xdd9V+\xad\xfc(\aK\xb9Ŕ\xa0\xd7_\xb2*]m\x1f\x13\xf3\x1e\x1c\xabM\x15ݪ \xa6fDVπ\vI\xe9\x19rY\xd4" + - "`Kµ\xe6\xc9i\x03\b\"\x1e\xc7\xfa~1c/Um\xa4\bm}\xa4=B\xbe\xd0Ӈ\xf8\xc7\x04ֱ৵\xbf\xafQӧ|\xb3\xff\xf3\x1aj\xceN\xd7<\bs\f\x03[\x95" + - "u\x19\x10\x8c;ܺ9>\xbbds\xc2q\x110Z\x83q\xb75xC\xb9\x17\x1f\xc6p\xbe\x1c\xea\x19\x1c\xea\xd8\"V\x06~t\xdd+c=\x97\x8b\x12^7\xb1\x8dЖ\xe4\x9b!\x85\xd5Y[\x13\xda\xd2h]\x15\xe4\xef\r\x85#>\x06k\u007f\xde\t\xd5J\x8c\xe3/\x13:݄\xa2\x84\xed]\xe0\xac\xf4\xf6fc:\r\xee\xd0" + - "P\x9d/cכWk\xde\xe3p7\xf6\xf8\xfaR3y/Jta\xeb\xdd\xde\x17\x06Mܽ\xb5vE<\xcf\x01\x93\t?Lr\xed\xb9\a\x18ik\x9c\xec\f\xb9+]\xfb\xd7-1N\x90c}\a:\xae\xb4\xb1\x90>.\xba\x05\xfc\xf3\x94\xed\f\xeb\f\xa1)\xacS\xf0\xc1r\x9b}`WR\x96q\xf2A\xd2Q\x16w\x85\x87" + - "\xaf/\xd2\xf3\x15\xdbD\xec䴹52\xbe\xa6\xf9\xa6t\x12 =ͫ\x8f6\xa6\xa3\x8c?KrKI\u007f\xad\a\xdc\xf2\xb8\v\x90\xdb_\xec\xbcV\xb9\x9c\xbc\x94\x97[FL\u007f\x05\x9a\xb6˨BU\xa5F\x9a\x06\xe0\x93\xb2G\xfdG\xf3q\x9d\x85\"\x91\xa1\t\xfe\xe4>Hy)\xdb\xd4xlz\"\x89\xea\x8bP\x1b$:\\" + - "\xf6J44\xab\x956lX\xacP\x99\xa8~\t\xf1i[\x10\xba`gO\xae\xcei}\xf9\xc3\xf8\xbf\x17\x8c\xeec\x17\xbb\xc7].z$\xa2X\xd1\xffTӎ\x81``\xb4\xa1)5\x9e\xa8^\xbb,\xeeTι\x02\x0f\xd3\xfe\xacb\x10+\x8e\xa87\x0fD[ٳ\x863I\a \xcf\v\x98\b\x99<\x1c\xea\"hBSt\\" + - "\xc0;ĢC)\xb2\x95u\xe4\x85t\xb2\xfb\x8c\xcd\x02\xe5i\x86*\xb1\xda('\xec4ǁ\xdf\xedd\xf1\xfbm\xbe\xa9`\xd9f\x80-\xb7e\xc2]\xb1-7\x97\x14\xf3\xc3\x16ׅ\xdb\xf7T\x8d\xdcSK\xe2\xe0\x0e\xde\xfc\x04\xba\xealދ<\xe2\xdepFo\xe9%\xf0\x8e\x97겊\x8c.\xf7#\xfa\xe6\xf5.*Z" + - "\xf4\x93\xb3\xb3\xf2\xf8t\xeaіK\x1d\xf9\x01\\\xe0Y\xd9;V\xef鉢\x1d\n\xd2a\xb1\x9d\xe5\xab-\xa3|o/\x8amz\xb9܊\xcd\x1d\xbct\xa1\xbe\xf1\x96\u038b\xf82\xf0\xfd\xc9\xd9U8\xed\x05\x93W\xa7\xd3{\xc1\xd9\xf1\xe9\xf12U眙\xfer\xac\xae\xf1ʎ\xc1\x8eSu\x85\x97\xed\xd1\xdf\xc6gW\xbdѱ" + - "z)\xe5\x86\xe5\xacH\xd7\xd5VlZQJ@q\x9fT\x0e\x9c\xe2y~\xbde\xf1#\x1b\xfa=\xa3OZ\xb4}Vޣ8\x93W\xd1t\x1bѳ\xb1]\x1c \x87\xb7\xc8\xe1\xce\xf6\f\x9e\b\xde\xc4\xef\xe3m2\xbb\x8c\x03)\x8c>\u007f\x85\xcf\xc0\x12\xa6\b\x83{T\xd5\x17\xd2!\xf7\x1e\x1d\xc2\xd8o\xf2\xe4\xe9㗏\xcf&\xdb" + - "~?\xd8\"`z6\xc5\xf3)ŸC]\xfc\x98x`\x8d\b49Q\xde#\xe1\xe4\x0e.7\xab*]\xaf\x92\xe8\xaey\xba\v\x0f⏎\xe5\xfb\xa97U\xabdI۷\xa4Z\xa4\xc9j^&\x95ĩ߈\r\xa1\xc1\x908tF\xc9g~\x98*\xee}\xf9$\"\x13\xf9j\x9e\xc1\xd0\xd2<\x93\b\xc6όg]\xce\xd0" + - "\xe7\"\x9c\xdcW\xb5\x9f\x1a\f\x8e\x8e\u008fNT\x9a\t\x1dqmD\xfa\xccSYR\xdb7\xb7,\xaaǃ\xbd\xf4U\xa1\xcb+N;\n\xb5\x9a$\x8e\xad\xb5\xebHn<\x19*\x18\xe0{Sn\xe3o\x8f\xc4A\x86\xa7=eLw\xeaM\x15\xcdق\xedi\x15\xbd\xa9\xfe\x8aG\x93\xd1c6i\xe6\xfaG\xf2L#K\x83\xac}\xde" + - "\xe1\x01\x8b\x18\x0f\xa6\x9d\xfc,뜿\xa3\xd79\xc5\x05\xbfΛ\x92\xd6\xea\x16r\xb6\x89\x98y\xdb6=\x16O\xe0~\xcd=\t\xf0\xa9o|\x11\xf9\xfe\x1eK\xb5g\x8c\xa0\x9b\x0e\x8bn\xb6\xdf\a\x93!\xba*\xc9\x1e>'\xd8\x1a\xce\xf8\x16\r%\xa2\xc4.\u007f\x88\xb3t\xdd\xe9ݙO\x8e=,4:\xae;¾h\a\x99}\xff" + - "{#$\xa0#\xa61\x86\x89\xe0\xdf\x12\xcd\xfb\u007fQ\x05ӬL\x8a\xeaK\xbe\x88©֠\x86Q]\xb9\xa3\xfa_\xd6v\xef\xfe\xb4\x15\xb0W\xbc\x11+Ƌ\xeaV-\xb3\xff?\nm\xd0G\xbb\xa0\xd3\xf4\xb1\x16\xc0\b\xa1\xa95d\xeb\xb9\r\xc0%\xa1\xb9Di\x92Q\xc9\xd2)\x9d\xef\xbd^\xa0\xa9\xbe\xcc\x19!\xd7\x13\xc6׀" + - "\\\x81\xd8ͭ\xb8\xcfxEV\xf0\x955׆\x82h\xf8u\xc5I\x95'\a\x84\xd7ʣ\xe5\r\xa7)|\xde\xf7\x1cΪ)\xaaj5C\x94U pci\xdcM\x9b~l\xb5#aɘ\xe1\xf4\xdd\tլN\xe3\xd3\xc8\u009a\xb5!\x9a\x8ckRџ\x938z\xb5G\xc3\x16D+\xbb\xad\xbb\r\xf2\xda\xc82\x00NEm" + - "\x94\xd7j\fE\x12\xd1\x02'\xa6\xaa\xebF\x8f35b\xf4J`$ic\xff\xcfvE\x8d2*{\x1c\x1b\x88\xed\xc9\xf1j\xb7\x13\x0e\xf7QϗqV;Y\xb2@\x80ˊ\x91\x00\xd9x\xe1\xb0C\xea\xbcݾt\xa4\x82\x87\xb7\x1cMGG\x97ݱ\xf6\xfc\xac\x1e\x1d}pb>\xae&\xfe\xb96\xc6M\xc4n\x17\xe7[\x00\x97" + - "lM\xdc\b\x18ư2\x8eT\xfb=U\xfbѝ\x13:>\xef\xdc?\xf5\x02\xb6Zj\b\"\xad\x10\x92\xbbj\x0fw\xb6\xbdrx\xc6)\xa7\x83\"\xc0\x91GC\xc7A\xc2.\xd3\x1bA\xeb\x00J>z\x98\xe8\n7\xbd\xd4\x1b\x15.\x87\x0fߟ\v\x93\x06ϥ\\i\xc5\x147\xdd\xd1p\xf4W\xf7\xb4\x1a\xccfB\xebo\n\xb5&" + - "~\x18\xe1r\x91\xf5\x95뼵\x8b0-\xb5ww5\xd5D\n\xf6Y\x99\xd3\xdd\t\xc1\xcaR\x93\x0f\x87T;\a\xfd\xdeD\x87\xde.4#o\x95\x17Z\x03\\\xbe\xee5\r\xda\xe3\xf3\x13qֶ\xfa\xc0B\x10\xb9\xee\xb1F:\xb0\xa5\xa5u1kȷ\xd7rò\x88f\xfd\x13u\x11A\"\xab\x96M|\xd3\vf\xa2\x964y" + - "\xfd\x93\xd3h\xd6!\x00\xbf\xc0~ۀ\xfe`\xb7\x95\xb4\xad<\xd33\xfa\xe2cH˖\xcb_\x0f\x92w@fZ\xb2\xde\xe8p\x1a\xb9VI|CH+\x8b\xc5 i=\xa8ړO\xa0]y\xf9+\xaa\xfd\xf9\x86\xf6=\xcb\x04\xca9\xb2G\xff\xd0\xc4V\x87z\xe6Bڻr\x85\\X\x16+G\x8aT\x1b_\xaf\xe0\t\xabЖ" + - "D\xb1\x9e\xa8\xb4PV\xf59\xa1\xbe\xad P\x88\xcd\xe63;\u074c6lfDC\x00\xbf\x9b\xc6\xdb\f\xef~)\r*ό\x1c۳ȰbE9\xa6\xce\xc9\xc3\x1e\x88M_\xc0\x04;U\x1b\x8d\xa1*\xde\xc4\xe3\x89)\xae\u007f\xd2n\xa8\xd41V\xef*\x18\f\x0eG\xb9\xadO\x8c\xac\xde\x1a\xbb\x1c\xa3q乊/T\v\x81" + - "0\xf8\xea}\xbc\xf2\x82ƩI\xc72\v\xa9`9C\xe7\xf6넢\xfcR\xac$\x00\"\xf6:\xa5\x8f\xec\x19eH~\x9f\x88\x10\x0f\xafvg\x11h\x01\xb3\x91\xbd\xe0\xfd\x17\xd6\xef\xda\xc5\\\xe3Z\x05\xa7@;S\x03\x11\xd2\x04\x86\xa8T\xad\x85\x01\xfe\xa5=Al\xc6\xc1\xcelL \x1e\x80ą\x15-V\x96\xb0\x8b\xf4\xbf\x85p\x90\x9fu\x10m=\x10\x17\x86\xb5FG\x94\x8d\xfd\xaaE\x91\u05eeʡ\x9ch\x9e\x1b\bk\xd6\x1b:n\xec\xec\xc6\xc1\xdb\x15\xc3\xd3Wu 㣻d\x8b\xf3\x89j\":" + - "\xb7Ҁ'\x86\xf0\x92\x15\x83\x9ai\x89\x83q~]Y\f\xac\xc4q\x83\xcdpT\xdc\xee\xf7\x02\x87\xea\xeb0\x13\xc2M^k\xad\x13 ۛ|\xadc\xf8\x1a㬶E0\x1fCߩ%m\x8e\x06۪\x86\u007fo\x02$6\xf1\x12\x83\x9d\xbd\xef\x93]\xeae\x1ez\xf2\xe4\x19N\x19A\xfa\xd1S.\xc5\x12j\x05J\x13\xfa\x98\x99" + - "F\x8fyGϐn\xb8\xfa\xf2\x1c2\xaeC\xe5\xbcuӒ4o\xdaY\xac\u007f-\xeb7\xb7Ǘl2\xf1id\xe8UH\xf6c\x87l\x92s\x13G\xe65\xdb\xe5\x06\xc4?\xc1\x1f\xe9\x85\x05\x80\xc8\xe4\xba\xf6\xb6\xcbڴy\x95\xfau\xe5\x9a\xf2Y?\x13\x0el\xf2\xde9\x00Z\xf0\xb6#\x02Cu\x0f\x9c\x83ɀo\xbb͍" + - "\xc9c\xdeܑ\xb8\x1d\\'d\x96\xa3\xd4';\xeb\xc1\xb87Zt\xee\x98-8g\xc7v\x01\x1b1\x1ff\r\xfd\xf1\x9cZ4.\xcd\xfd\x86\xbd\x1d+AY\xe0\x9b\xa3\xb2\xc2\xf7&Y\x8b9\xcc\xe0\x13Mߨ%SE|xY\xef`_\xf2q\xd3Z6\xccE\xb6֍]-\x81\xebJr\x8f\x95ܳ(W \xe3,\x9d\xd1" + - ":Y\x95\xe0\x1dum\v\xe2\xcb\xccA\xaf>4\xec\x97\xf7\b\xe7\xa6i`\xcf#\xdeh\f\x93\x85\x86;\xf6\xd0\u007f\xda\xdc2\xec.\xa4\x9eV\r\x0e;\x8f\x9e6\x04:\xb4%\xfb\xb7\xed\xc9{\xe1\xbawDl\xd1p\xf5\xd8\fh\xb5&\xd0\xe7\xd3\xd7l\xf0\\◗\xce\xd0L\a\x1c[\x98\x0e\xbd^\x1c`b\x1c\x1d\xfd\b2R" + - "\xe6\bn\x83\x18\xcf]\xcf+\x9aG\x92\x01\xabiJ\x9e\x1dyaj\xfdP\xe7\u008a\x93|Z\xd7:\x9bR#\x87\xfe\xb5\xee\x17\x87,E)\xd4\xe1\xea\xe8\x88W\x99#K)\xa22J\xc5Ed\xbeS\r\x92\xfd6\xdb<ՀŢ\x8e\xd2\\\xcc\x02\xc2]\"n\xe7\f:fȔ\xf5\xe9\xc5\xe8BT\x9cpyx1\x05p\f" + - "\xbb'\x0f\x1aʅpJC\x9dM\xed\x0f̌\x9f\xab\xdc\xd1\aɧa\x1eX\x95\xd1+=\xa1(\xfa\r\xf7\xe2\xa2A\x05\xee\xd1}\xdaA\xf6*\xb2\xfc|\xfe1~\x9e\x184\xe2\xfdWS\x88\x00,Ή*\x9dY9\xa34\xbd\xfc6\x86\xbf7\x9b\xdc\a\x1f;\xc3mo\xeds\x96j:X\xc5z\xb6\x8e\x9a\x80\xde\x1f\x11E\xc0" + - "\xad\xc4\\\xa3跅\xc5\x1fls\xa8\xa8\xa0A\x930\xad\vo4\x9a\xfc\xa6Y\xbd\xa2\xc9l3\x1d\xdb{\b\xfa\x82\xf64>\x0e\xc32,]\x8a<\x8dĔ\xb8͎9\xeds\xf6\xaeM\xe4F\x9d\xa4Dujڛ\xe8\x84M\x17S\x977\x96\xf6\x06{\x95\x99\a\xa5\xabJ\xa0J\x97w\x89<\xeb\xa7\xcc\xdd\t\xcaFf\x8dO" + - "\xa3\x12\xe0df\x14\x04n\xeb\xb6ޥ\xe95*\x01\x15\xd6\xc8\xcd%\x86̬\xd3{\x89\xbe]\xa5e6\xb7\x16E\xeaKZ\x15\x17\x16\x1f%\x8f\xe6\x93\v\xa0\xa2\xc0'\xe5!\xad\xfa\xfe\tO\u007fs\xf5\x9a\x83\xb1e\x1c}g\xf3\xcd[\x9b\xaf\xd9z\x9a\xd3>\x0f\x9c\xf5\x1f\xf3\xb2/\xa1.\x05\x1a\xb4.\xbe\x14\x14|\xc3q\xe6.\xc7" + - "\x99\x99\xb3\xca\xf0y\xa5l\x0e\v\xf1k\x97ux\xd45\x04\xb4\x80\x90\f\xf9\xd00^\xc07\x91v\x18\xcc\xc07\x9d>\x90i\xdfh\xe9\xe0\xef\xf17%my\xa5\xec!>\xf32\x0e\xacP&^\x97\xa3\f\xf8A1\xa6\xe8\x06J\xc8L\xba\x1b\xfe\"\xb0Dw\x1dB\x14˸\xa5H\xcc\xfe\x17\x9a\xd48\xda\x15[j\xfc\x13d][" + - "S\xe1M͌\xdbfT\xc0P\x1bY\x9blgbc/\xd4_\x05af\xe0\x8e\xd4\xdat=\x94e\f\x17\u007f\x8b\x10\xf6M|\xed\xdfl\xe8s\xc2n\xf4C\uf6ef^z\f9)6\xe7z\x12\xa8\xb8\xfc\x90\xcd\xc2\xc3\x13\xa5\xe1J\xe9ɫ.\x8a\xfc\xaa\xf4B\xd6*m\x1b\x1e\\\x15\xf1\xba\xadL\xf5\xbf\xf5إ\xf3jz\xeb" + - "2ng\xb44\xc8\xe2\xe2\xdf& \n \x8e\x1a\x065\xb99\xdaWM\x04\xf3Ӑ\xf4\x99\xccU\xd5\x16z\u05f6\xa9\x1d\xf2{\xe37\xc2\xf1\xe8oY\xc1\xa4\x11^k\xf3Y9\xab\\\xed4\xa4\xf5\xe8\x80\xefpbt\x8f\xe2\x9f:\xcej\xf5%g\xb5ߛ\x1f\xf5ᩝae\xe2\\\x9d5\xbf|8\x15\xd3\xceA\xb3z\x90(" + - "\x1fGd\x1cH\xed;=\x184\xea=\xba}*d\xfbS\xa1jz\\\nB)j\x935\vk\xe9'\xf3@\xfbA\x87\xe2~ˢP\x0e\x18\xda!\xac$زE\x1a\x1c\xc1\xd1H\xa3\xfc\xa8\xad\xd6\a\xe5\xf3J\xfd\\\xa9_+u\xa7\x8a\x8e\xe3\xd5\xfa\">\xf3'\xaf\x82\xe9\xbd3(-|G\x819\x80\xa9\xab\x0fg\xe5=\xe8" + - "4\xc8\xc7\xe0X\xfd\xc1\x1a\x11U\xbe\xde\x16@;ߞ\xe7U\x95_nW\xc9\x02\x1e)\xd5o\xfc9\x03Y̧\xad?>\xec\xcf&\t\x91q\x03(b\xfc\x82ϗq\xb1L\xb3c\xf5\xafZ?\xe4\x95\xef\xf5\xaez^\x00\x1d\x88;Z5\xe4\xf7\x8e\xcf\xe3\xc3\xf5u0\x89\xfb\u007f\xfc״g\xe2\xfdÍ7\xe9\xf5\xa7A\xa4\xa3" + - "\xeb\b\xdfT\xd1͗?>\xfd\x9d\x18\xccU>{K,\xe3O\x14\xb2\xce˔\x15'\xbc\xf8\xbc\xccW\xb4Ay\xea}Z\xa6\xe7銚\x1dz\x17\xe9|\x9ed\x1ec\xa7\xc1\xf3\xaaM\xfcOJL{ \x11\xe9\x1a\xbb;\x1c\xaa\x05Ͷ_\x19\xfe=|8\x1c\xeeԿ\xabh\xe2\xbd́\xd5\xfd3\x83\xc2+\xefK\xee(z" + - "\x00ĉ7UIFQ~M\xce\xdf\xc2\xc0\xd4\xfb\x91\xfe\xfd\x90\xff\x01\x80\xf0қ\xd6|bU\xbbCѾ\x9d\xad\xa7!}\a\xc5\xd05\x8f+\xec\x1aU\xfe\vMiM\xd4\xf5*\xad7x\x02\xba\xb7\xc25C\xb6Oð'\xa3$#\x8a\xa5\x97\xa9v\t\x86֮\x99\xb0\xac}\v\a\xedH\xe5e\xda\xfd\xd35\xb0\xdaAr" + - "\xebN\xf3\xe4\xfe\xe9#LU\x9du\xd1vwc\x14\xe1\x87\xec=\xc5u\xddf\xfc\x19\xe2\n\x05\x18Z\x82\x13ψY\xf14r̉\xf3\xd5\xdc\xd6D\xc1O\x97\x00\xca\xeb0U\x8d9\x05\x11\x03\xdc\x00\xb1>\xf4[\xb1\"\xb8\xb2\x11l\xfe\xe6\a\"\x1fp\x91\xf0\xf1bՊ\xe2Ԧ\x81\xf4\xbfP\x8a\x84m\x19\x92+\x9f\xb8`\xb7" + - "\xfc\xc3\xd4A\xd9meF\xa7j(}\\8}\x1chc\x11pR\xb7vM唲\xd7\x10\xaf#\xb4\xa3'\xaa\xb1\xee.\xb8\x87C^AC\xd1\xdb9Xge\x1b\xbc\xedO\xaeT[\x1cWt\xb3\x03ue\xdcg\x1a\\x\x83\xa5\xf633\x91im\x80\x92\x9e\x96L3œ\x8c觩\x9d\x88xåK\xcd8\xc6։" + - "\xfa\xa1h\xb4p\x13\x8d?*\x9b\x8e\xb6i\x04u:\x8c-/\xf2\xab\x8eݛ&07\x8a\xef\xcbh\xf7\xe8Ҳ\xd0q\x02\xe3\xc1\xb2\xe3\xa8\xdc\xf7U\x99\x8c\xb5\xc6>\n\xf6\xf5\t\x88\x02\xfc[N\xc3L\x9726'\x83Nh^%\xed\xae\xa5\xc8K-\xb7>\xe6x\xebo{\xf51\xfb\x90\xb9\xfe\xfe\x95\xb9k\x1d\xd9\xfa\xf4\xf1D" + - "\xec\xe8\x9dxaƎ\x94(\xdfg\xecK0\xbc\x99\xd1>{\x991T\x1f\xac\xb3\x16\xe9j\xf5\xa3.백\x89\xd2\xdb*͒o\xed[^Gc\xb7\a\xf2@\xc7V\xc6\xf6^W霨<<\xfd!\x0e\x89\xf0\x94痌\xafD\x15x\xce\xd0]7\xdeb\x95Ǖ\xe7\xe8tѷ\xaf\x116\xf6\xcc\x13\xcdm\x9e\x12\xf2\x02" + - "\xa8\x8d\x0f\xab\xb6\xe7{@f\xd7^\x9c\x92\x16voC\x19W\xe6W\x03a;r}\xdcd\x01\x83\x16r,\xd6\x1c\x95\xb9\xcb\x15f\x96\xdco\xbcGt l\xd4*\x00C\xc4\x1fj\u007fh\xce\xebj*\xce\xcf\xccV^\xd6\xee\x9dJ\xe6\x1fJ\xed\u05c9\x96F\xaa}A\xe5\xe1\x06\xda\xc8`$\xacJ\xb9c\xef\x14Ŝ\xf0\x1f\x9a\x01" + - "\x17\xa6\xad\x88h\xef;\x99\xf6N\x82{\xf9\xe4\xfe\xb4\xc7Μ\xb8\xe3\xfcz%A\xc4c\xbcIBd\xa5\xcdl\xb1\xeb\x1a\x17\x93\xc8<-\x9f\xc5\xcf|F\xb16\x1f\x80{\xa5\xdb%3H:\xa4\xe8E\xde\xfa\xdak $\xc0\v9˹^\x88O\x12O\xe3c\xb3No\rq\f\xf7\xf6P\x9b\xcb\xe6\x1e\xe3\xeb\x02\xa4\x8fz\xe5\"" + - ")\x18x\xa1\xac]f\x95ܼҺ̢n\xe2\x1e\r\x18y\x8b\x13\x16Z\x1fa\x06}\x04\x9ef\x1d\xd3\xe4\xf6q\xaf\x85\xa1\u007f:\xe2z~\xfc\x95qo\ru\\\x0f\xf5\x10\x9c6\x8d\x85\x80WŲ|36\x13\xa0\xdd\x1c.d\xf4H\xf0\xc5\xd4?%\xd2?+\xc6E\xf6\xb4\x8b\xa1\x82N\xcc\xc8\x19\xe5X۰\x0eElH" + - "\xa3D=\t\xf1\xcc\x18r/\xf8͋\xb1ɰ\xd4\xfaI~\xb9&*k\xce#4\xf6\u007fv\x00\x98\xaa\xa6әFL\\{\x01\xcbiG\xd4j\xb7\a\"͋S\xf5\xe4\\XE\xe5\xb8\x14\x9c$\x81\x97\xe0\xbb\t\xea\xf1\xed\x16=\x16VΊ\xab\x17\x88\xef\x19\x91\xd1\xc7\xe8\x15\xf64\xe1\x1c\x1a\x01\xe8T\x91,\xachE\xfcR" + - "\x19\u007f[|\u07fe\x19\xb0o \xa2d6\x83\xcb4\xfb\x95_b\xbc\xc4\xd7\xf2R\x87;\xa1&]\xb4B[t\x1e&,u\xd3\xe4\xcaI\x15C\xe4G\x1cR\xdc\xc6\xec3\x18\xb6/4-\xf0s\xa7;\x94\xa4\x11\xed?\xec\xee[\xfaU\xd6:pX!\xa9Ȧ\xac̰\xe1)\xe5v\xdb\xe1\x1f\xed~\x03?\xc1\xf0>\x05\x9d\x15\f" + - "Q\x85\xf9\x1f\x8bP\x8e?\xf2~ďQ\xb3\xe6\x1cF\xbb\xaa|\xf3p\xaa\xbcH\xffH̱\x94\\z!\xfau3X\xa7\xd7\t\xc3\x12\xf6\xb0\x9d\x98\x04\xa9\x9b3\xba\x94\xe7\xfej,^\x98\u0095{\x8b\xd36w\xf9\x97qeP˩\xc7?\xc4\xd5\x05\xc6ȧ\xf5G{e\x1fW.\xc3 \xe8\xf9\x85x6\xc0N\x16V\x8e{" + - "\x96}\xc7\f\x11\xeeK\xfcbL\xa4\x01\xbb\xfc\t\x8d\xcb\x1f/\x18?\f\xb5\xff)V\xd0=!^$6\xc2臧\xf9(\xefE\xf7\x03O8.}\xf3\xe8ǽ\x9a>\xea\xfd\xbbb/\x05C\xde\ahy۬M\xe4~Mկ\xb5w\xa2f\"\x93\xfb\xe1~\x02]_\x89\xdf\xf3~\x15GY\x92.\b݊t\xe6]\x87\x1e" + - "\xee\xd5\xfc\xe3y\xd7Ԟ\xedײ5V\x88\x19\xb9}\x97\f\x04\xa6\x93s\n͛\x90 \xcaМ\xb1#\xd8;ϯibQ\xf5h˕\xda\xf45\x96\x8eSI\x1d\xc5\xd3T(\x1d\xaf\xc3S\xc0\xfek<\t\xa6#RًY\xceI\x9f\x9d\xaf\x1a\x9f\x93\xd7\x1446\xed\xaaI\xadT*\x1d\x15|6w\xd4\xeb\xe7d\x95\x82" + - "\t\xdfnS\x96\xf4\xd4٤\xee&\x9eҮ64dq\xda3\x13\x90\xb6\xba\xb8k\xcaA\xf8\x19\xf0\x92\xa9;w\xe5\x88Lbⴾ\x81\x9d\x99\xebt6\x8b6BA\xaa\x9aס\x93\x86\xbe<\xaf\"\xfa\a)\x86\xf7H\x8c\xf0\x0e\xf8\xaf\x14\x1c\xdd\x1d\xde=\x90\x8d\x0fO\xe2b\r\x8fǧ^\xc0\xbd\xeci\xf7`\x9e\xe5\x88B" + - "\xe6\xd4\x0f\x0e\xd3KtG\x8c:\x1b\xb9\xd5\xcb\x1c\x17\xd8\xcd\xdd\x11\xda{T\x03\b\xd9\x1af~\xdbm#\xb0\x16љ\xf4\xaa\x1a\\\x11ݐP\xc5\x0f)\fD\xd3\x01\xae\x05O\x1f\xc9_1i`5*\x18\x80Ô\xd7\xf6\xc2\xf3J#\x13\xc2\x0f\x03\xf7\x16\xec\xfa\xb2\xbaG7\r\xeb\xaf\xeb\xbd;\x9e\xa4\xd9&\xbe\xfc`\xfba\xf4" + - "I\x06\x9d\xba\x9aA\x1c9\x88\xf0ZY\xb0\xd8՞\xe2\x12-\xa1\x90\xb5\xb0\xef\xbeΡ6\xf6<\xf3\xf1&e\xf7\xba\xa1`<\xd5\xcb\xe8\xe8\xe87=a\xf7E\x03\xb8\xec-\xafb\xa8\xd3\xfdT\xa9}^\xa94\xae*\xe9H\xb3\xcfa\x87ø\xdaf\xaf8:\xe2ej\x1al\xbe\x8fcC\x91\xfd\x1f\xac^\xe0e\x06\xe1\xb0\xed\x04" + - "Os&\x86l\x13\xf7s:p\xaf\xbbjB\xe7;\xdd/>\xa3\x9f\xb8\xe7\u05f8u\x9ci\x03K\xe3\rO^\xc5\a\xfex0<\xb9\xe7\xacd\x91\x83\r\xee\x9c\xd0\xfa\xf4\u008a\x990ϻ\xd5\x01\xb5\xd9\x12\xe4\xb2\xdf)S\x89\xbfyC\xceU\x01\x9d~\x90\x11\xfa\xa6]^\xefd8\xbc\as.\x14@\xbb#\xeb\xadJ\xd5\xe0[" + - "\xdb\x15B\xe3\xa7RK\x17օu\xf3%#Q\n\x8c\x99\x130\x10ak\x17UJ\xa7ekGqB\xe4p" + - "n踛q\xfa\x96s\xfc\x91\xa3\x95F\xf6\x052*1\"\xb1\xa4-\xef\xeaآ\xac\xe3TSQ\x96\x10wz\x91;\xecl\x12\xdf.\xd4X\x9a<\xa4X1\x9a\xb0\xc1\xa3l>\xa1\xa6`\xf6\xf5\x99\xec %=\xc0u\xc9ec\xb8\xafN\x0ez\x06\x9ej\xf6\x01(\xb2q\xe6`\x8a\x87`\xf35\x81(\xeaN)e\xfdo\xe8J" + - "\xa2\x80\x9c\xd5\xf4\xe9o\xff>\xff\x0e\x1d\v\xe5\x9d\xfaű\x17\xf0[u\x03\xaf\x1c\xe5\x99q\x958ˢ\xe3\xff\xba?<^\xaa5=\x9dMΦw\x8e\xd5\x02\x8f\xc5\xf8,\xa3\xe0y&ƕ\x82{\xb8ծ\x19\xd2\xcbx\x99l\x8b\x842\xdbR_&lly\x91}\xc4\xef\xe2\xf6m\xf2a\x99d\xc1qڄ\xf9)\x8dAD" + - "'\xb2\x1b\x1b0\xfa\x1a\xffFG\x149#\x86\xbd\x19t\xdb]M\xe7u\x9b\xf6p/w4\x89Vժ\x0faX\x1b90 \"\xc2\xdbu\xa1\x069Ȳ\x18\xc8\xc6\xddSƈ\x89\x87F\xa2\x97\x12\x1d\x14\x1aO\x14\xb8پȺ\x90\xe9(\xc5\xa8a\x96\x0f\x04u\xf2@\x9bx\xd7\x18\xc0\x9c\xaf\xc1\x02\xc6\x03e\x9f\x14EN;p\xeds\xb6\xe9Tb_c\xb6\x9avá\xef]\x80\f\xe5*\x82\xc7N\x1bZe\x06y\\\x03\xc0U\xfb\x8a\x16\x17h" + - "\xe0G@\xea\xea\x16\x83\xa6\xa8\x1b\r\x05\x18\x98t\x9d7\x11ۚ\xbe\xfd/\f\x06\xa1 \xde\xf3\xe5\xcd&\xdbK\xd2J\x00(E\x83\x91_;1\xf8s\xa8Cƛ\xc0\f\xa12nI\xd5\x00\x1ci\xf7\xe0\xd8)\x1e~\x1cu\xe7!\xa0\x02\x14\x19\xc2\xd8\xc1\xb8\x9c\xa2\x97\x99\xfa\x90\xa9\xf7Yd\xd0\xd9\xcfq\x82\x8e\x8f\xd55\xfd\xfem" + - "\x00$\xbd+z\xf2'\xe3\xa3i\xf0:\x9a\xbc:\x9a\xde;V/\xf9\xbc\x1c\xdc\x1b\xd3i\u007fpVMq\u007f\x8f-\x12\b\t\xc5\xf8\xce\xf1\xf2R=\xd1Gj|NSnK\xac$\xfe\xf5\xcb*/p\xfe\x0ez}\x1e\xbbR\xf0#V|\"o\x89C\x04\xf2bH\x85>\xd3ɿ\xf9\xea\xe5\xf6ۯ\x1e?\xc5\xe5\xff[\x84\x9d\x1d" + - "\x9f\x1d\x1f\xab\xaf\xf8\xf3\xe4\xec\x8a2\x9a\xf6B\xf6\\L\x1fP\x8d\xe3\xf1\xdfB\xf1e\x1c\xfa\x80\x8a\xd8\xd2\u007f\xc7\xea\x05ZH3\x06\xcbG=\xce@ɼ\xe1\xbfO\xb3Ȼw\xec\x19\xc7<\xd0Vf\x03\xc3\x0f\f\xdb]$\v-\x85\xff\x9e\xba\x9d\xc2\xf6L\xebc\xa0Ld\x1c\x13\x1e\xf3)\x8a~\xdb]f\xd1W\x99\b\xec>d" + - "M\x8dH\xf6CZomߺ\x14\xa9\xb3ye\x1d(\xa4\xb2\xbdW\xaa\x8a\xb8\xaa\xe6\xbc\x19\xd2qS5\vq]\xa4NGm\xbd\xa3,Ш!\x05\x91d\xac\xc2F\xfb-\xa4\xf0D\x91\x81 /\xec\xf5>\xabp+q{\x900\xf56\x99\x06\x83M&\x0e\x1f3H\xdaZ\xdf4:\x9bc\x1f\xf2\xae}e\x81\xae\x8f#\x18\xb0\xbe" + - "\xc9\xea\x8e(\xfd\x95|\xdfX\x16\x1bW\x14\x87CC\xe2&|\x831i\xb0\x1a:\xc9,Z\x89\xabM{S\xd8\xee\xba\xd9v\x1b\x83\xe4\x9cM\xc7\xf1\xf8\xd0\xdfD3Z\x1c!qpFի\xb4\xad\x9a\x05\xaa\xc4\x1f\xa0\xf3\ajc\xf5\xf7\xdc\xc8Љ\"\xaa&\x9fP\xf7L\x8f\x8eJ\x9e;\x8e\xa5Q\x93\"`\xe3\x9e\xc6\x19\xbcX" + - "\xc5Տb\xa1\xcc\xfe\xea챑\x05P\x98\xd0^@|\x1a\x9d\xe98\t\v\xdcL\xc1\xf7t\x00\xafT\x19[\x8a\x1b\x06\xca\xf1\xc5@]\x05\xdeJ\xe9\vsL\xf7=1{'\xe2\xe4\xd1ы\xcc\xc8\xfc^d\xdd\b\xb0#W@\xcf\xdfVl\x83\xa2o\xbf\x0ej*t%nBS\x8b.E\x1b\xb9u\x17\x96\xd8\xd0!_9\xb5" + - "\xe6\xe5\xd8\x02\x98\x86\xd0]\xe8p\x05\xeaǑ\xf7\xfc\xc7\x17/q\xa5\xe6\xe8ew\xa8\xf2Ŏ\x1a\x1f\xa4f\xa2\xd6\x17f;\x88ٲ\xc4w\xa9Ƽ\xdeK)[6\xccL\xc7\x10\x1b2\xe2\x86UMc\xba\xafL\xa0\xb7\xccR2F\xcdLE\xf9\x8av\x91\xcb5\x14\x18ah\xdb<\x1c\xf45z\x01\x8d\xed\t\xbbo!ҭd" + - "\xe5X\xdaӓ)\x03Z\xb3\xa2\x9b\xe5\xady\xb6\x10\v\x02\xe1\x99<3\xb3\x8d\xc7'\xba\x1c\xfd\xfa\x15\xcec\x13k\xc3\x1a\x10\xe6\rv0\xd3?=\x92\xbb\x8e\xa1\xd6\xfd\xbdxq\x0fi\xc8\xe2\xb2\xfa!\x9f\xa7\x8b4\x99óVR\xc5Kv\xdd\xeeL\xee\x90\a\x81N\x16G\xa12-\xbf\xcfg\xf1*|\xa2\x89\xb1\xcblr2\r" + - "\xac2%\xd0TsԜ\xb5b\xe9U\xab[Z\xe4U\x19EL\xcct\xc6~$\x8e\xaf\xfbWWW} \xdf\xf7\xa98!\x8b\xe7#v\xea\x05^\xf1\x97\x97_\xf7?\xf7\x94\xe8\xb7\xe2z\xfe\x9e\x17>\xa5*\x01\xa4\x84-\x8f\x8e\xd7 n=1З\x10\x99$\xd7xo\x94t\xb9R\a\x1c\xe1\x1a\xdfߔ\xac\xd8\xe5D@\x88\x8e" + - "\x01\x18\x1e\xad2\xea \xc4\xdd O\xa4>\x96⸤cɉS\x1f\xc3~\\&\xc5\xd7\f\x91#I<\x13\xf8\xdb\x0f\xdf{\xba\xee\xee\xe41\x951a\xffx\xf1\xe33)\x97H\"H\n\xd0n\xae\x98\x17\xbe\xe0E\xaf\xb8\xa5,J\x86ު~E.\xd0\\\xe0ɍLt8\xdak\x82\xa9\n;\xe5l[2\xcaf\x84\x18\x12" + - "wg\xe7\xc1f}\vy4\xa6\x9d\x917\xc7\xe6~\b<\xf7\x90\u009b\xa1\x8c͇\x80\xe7t\xa4\x8a\xa4\x92N\xcb\xc7Y\xc0\x81/\x8b8+!\x97A\xe0\x1b\x1dؒ\x8c\xedC.\xf3\t\x9a(q\xb8\x01\x9d(\xda|\xf7\xec\xca\xd9\x1c\xc3\xd6e\xb3\x86\xe1c\x06?\xb8k\x83\x87Jl\x85\x9a\u05ef\x94\xeb\xc21sYh6\nr" + - "\xac\x85\xf5\x92\xa4.(ϧɂ\bh\xb8Bb\xc3\xf4'\xf1j\x05Ł\x12\x9e\xddgp~w\x99\x17\xd0(\xbb\xa4\xcc\xcb*\xae6\xe5\x13\x8dZ\xa8>\xe0\xdc|\x8f?\xe7t\xe4_E\x9e\xf8n!\xa6\\=\x89\xa8\x87\xe3\xf9\a\xda1*,S\xa2\xa4~\xd6s\xe2[\x86\xe4\xdaW?\x05Qp\x9f\x8e\xe0s\xf1*<\vn" + - "f\xb0\x1e\xd5hb\xd1KM\xbd\xc4A0\x9bT\xfb0\rQ5\xb9?\xddU\xd1lҲ\xe5\x9c\xee\x1al{%l{\xb5C\x9d\x1e\xafV\xcdj\x95\x1d\xd2\x0f\xae\xd48֘\x9c%ZB\x9dYV{\rqe͍*\x98\x83\xe8\x1c\xdeӢ\xf7\x90@\xbegu\x86D}\xc0mHev[p\x0eE:O~H/\xc5g" + - "LǦ\x88LփK\x1d#JL\xdazp\xba\xfb\x96\xc1o\uf7de\xb3ʼ\xd6~\xbc\xc4\xc6;\xb9\x14\x1f\x8e\xd5t*,\xe3\x93A\xbc\xba\x8a?\x94D\xe0<\xd1c\xde\xc2\xfeVDH\x17\x9d\x00\xa7\xdb핉\x89k\xf0\x01G\x84\xed\xd0[\x1f\x9e\x95\xa4\xae,\x1e\xb8\x80\xe8\xe82\xa5\xfeyR\x1fU\xd1\x12ֿ\x8a\x8a" + - "\x95\x83#z\xc2G#\x050\x97G\xaf\x8b8\x85B=\xad\xf5\xc8\xf7\x138+\xa6\xc7\xed\xf6C\x86k\x80\x9ae\xbfΔ\xfb\xfa6S\xbc\xc3\xf7\xbc\xe3c\x9a\xcck\xb1\xd4\xce\xe0?\xf2\"\x9fC\x8a/\x96\x12k\x1b\"Q(\xa6%\xb1\x8c\xfc\xbe\x0e\x12{\xc2\xdb\t]\x8f\x0e;\x99u\xb40\x8b\x9cN\x93\xfc\x92\xf6xֶ1\xd4" + - "8\u05ffE\x90\xabF\xf4\xe8\x90mIp\xa1N3\x91\x9bqt\x84\vuy\x83+\u007f\xbf\x98<\x802\r\x91\x15\xd5:\x14\xca\xf9d:\xf6>\x1fz\xa1\xf7\xf0\xe1\x03\x8f\x15zpȵ\xa2qn\x8dx\\\xba\x98[\xaf\a\xce!X\xa3pZ2\xcd\xc4\xd3=\x12\x199\xa3\xbc\xa2\x93\x1d\xc1N\xa0\xdea\xabTk\"\xfb\x9e\x04J" + - "V\xba\x9e)OF+\xea!9{\xd5\xea\xe8hȗ%r\xc6\xc37C\x1bu\xdd!F\xecX\xcaOS-\x98\xbe]ĥ1':|\xa6\xcfz\x89\n\b\t\xee\xfcF,^\\\xbaY\xfa{/\xf2ϳڲꈺj\xec\x05=\xddJm#\"o\x96\xc93Z\x88\xfd\x1f0\xbb\xbd:6\xd5ʯ\xe7KݏxsH\xa5Cq\x12\x90\xb9aAwI:\x83>\xa2x\xaa\x91K\xa0\xba\x12\x10\xbd\xa4\x0f\xdd\xe9\xb1lm2\xbd\x86):m\xc8RQj\x1a$\\8\x1bd\x9b\x1c?\x8b\xbc,7\n1\xa1n\x8f\x84V\x97\xa6\"\xa1\xff,\xbabZ\x81H\x1az\xe2\xad\xf1==" + - "\xf0\xbc\xa3n9|\x0f\xd1\xcc\xfb\xe8\x99¡}\xf8\f72\x94G\"\xbc\"u\x15\x03&\x0fq\xfc\x18\x9a#J\xec#x\x8b\b\xe2\xeeg8婷.\xc0\xb3\xe6\xab\xf7b\x00\xb4P\x93\x0f\xea\x99z2\rB|\x00\x85m\u009fP\xf8\xfbi\x9d)\xe8#\xff\x12\xe4l՜ҳq\x83a\r]V\x16s\x9c\n\xfd\x10\"" + - "\xa7%\x8c\xc5\x12'\u007f\n\x83O\xdd\xd6ꨙb\xbdB\xfa}s\xa4\xd5\xfe\xa7Z\a\x1aqԎC\xf9'L\xa2\x82\xfb\xb9\x1d\x8c\\\xd4]!\xbc\xf5\x98g\n8\xcd\vf\xf8n3Jp\xd2\x18\x8b\xd2]}o;a\x8dZ\xe5\xc1\a\xdd\xfe-:HצF\f\x9c\x17uٽ\x89\xb1H\x94o\xb7\xf0\xf1#\x1e\x83T\x87" + - "P$\xab\x85\"\xb9\xc8C\ne\xb6\xadt\xd7\x04\x92\xf8\xa1K9\x93\xc5>\x86\xb3e\xadL\xbbwk\xe6\x81vg\xb8\xb2\x87\x88\x8c\xf6\x13\x16\xa9\xe1\xf0\u05ce\xe7)\x81!\xa6q@u\xac\x99Ɖ\x14\xb8\xb0P\xd8\xecW\xa0\xabW\x93\x92N\x1c\xfc\xad\x8d\xd77V\x80W\x1a\xdf\x10\xd8f\xa9\x1a\x94\xaa\bb\xae\x11S\xdc763" + - "\x11\x88\x1dn4\xfcQ\xcd8OJV\xdb\xc0\x87ip\x13G\xa5ɑ\xadk\xca`\x17C}<5s'\x1e\xfb\xf1\xa1\xb4\x19T\xb8\xa9\bT\x98\x013\xe0\xea`\xfex;\n\x00X\xbb\x99ۡZR&``\x10\x98\xd4n\xa7\x9c\xba\x06\x9bI\xdc\xe6\xce\x1am\x89\xa7\xa3<\x9a\x99\xa10\xd6\xcb\xe8\xc7Z\x16%b\a\xb1\xca\xcd" + - "&\x1d\xe1\xcc6\x01\xf8\x80}좊_3K\x8e\xab\xde\xc8\r`?a\xa6\t\x8c\x14\x90+\xa7x\x06+\xe0\x19\x92\ay\xb4\xb2\x97kB\tP\xfe\xc0\x13\xc9\xc5\xea\x98:t\xc5\xe3\x90\xd3\xf0l\xe8\xd8\xe7Gu\x18\a\xf6\xec\xdf \xbf2J\xdd;\xa8RH\xf7\x9c\x85\x85&\v&8l.\xfc\x16`d\xa1a>F\xb4t\x1a" + - "nD\xf4z8\x14C\x06h\xba\xcd\xeaY\x85\x01pfV\xcc1Q<\xd1b\xc9\xc4X\x03O\x83*b|\"n\x18\x0eVy\xd7\xe7\xe9\xda\xdeP\xf3\xee\x1dz,\\)\xf4\xc6,dC<&n\x81\xceS\x19B\\\x93\xb0\xe7w\xaa6\x9aR\xe5\xe8\x85\xddn\xd7̧4\xa2?^\xd4\x15\xd0r\x1c\xf9\x85\x95\x83\xc9\x16\xa4\x05^" + - "\xb5\xb4J\x1d4\x04Z\xb7\x84\x03_\xba+\xfc\xba_\u007fiȽti\x9d\x00\xd5-9\x15\v\x9ct\x16\xddV\xbe\x0e\xfa\x9ax\xd0ߙ\x1d\xceʇ|k\xaf\xed\xe6\x90X&A\\k\xcb\x1b\xbc2&->QC\x8a\x89\xcc2\xd1%Fr\x11 EY\x1a\xa7\xbb(^SN\x9e5@P\xccT(\xeb\xa2\xe2AC\xae\xed\xe9" + - "ӏ̨6\x80\u007f\xe5.{\xff\x02\xcaB\x14dB\x0f\xe2\xb6$\x19H\xe8\x13\x91\x84\xb2j\x9b\x91\x8a\xb6\xbe\xb1\xf3\xa6\x02[\x0e\xf8\xb2l\x90\xf3\rs\x84\a&\xb6xji\x0f\xa0M\xb9\v.O\x0f3\x87$\xdbn\x8f\x916\x99o\r\xc9{\xac\xd5\xee\x9dHl\xd8\xf3\xf1b\xf8ִ\x89m\xfb\x11\x94Z\x88\xf0\xf8\x9a\x95\xf6" + - "b\x9f\xe8@e\x97\x01\x14m\x8a=\xd4ʦ\a\x8f\x96T\x85z\x18\x85I\xed\xa8\xcbş\xa0\xbe+\xfd\x9a=x}\x89\xeb\xd0(8\x1b\xfb\xe3\xe8h{'؞\x8d\xcf\xc6ǣ\xc6R\x03a@\xebw\xa6%{\"\xa3]\x1bA\xdf>6\xe8י \xf43\x99\"H\x0eą\n\x13\xeaJ\x81 \xb9\xc2\xf0vN{\x94\xc1b" + - "ܵ3\x1f;̄\xb2\x01G:\xd4\xfc\xf2\x97\x99\x19$\x9a\x00\xc4\x05\xd3_\xb6Qk\xe9xi\x86\xf3\xd0o0\x94\x82oho\x80\xfeT8\x0fݡ\xba@\xe6ߏ\x8e<\xfc:wG\x94\xa94\x83\x81\\\x1bl!\xb0)\x06\x8d\xcel*մ>\xc2\xcfp#\x00\n7\xcd\x10\xb5\x1a\vj\x04\xfd\xb1\x82\x82/YP@[" + - "\xac\x8dnz+k\x89'L\xaf\x19ف\x8e\xcez:9֖s\x06\xeb\xa5*\xa2v\x87\xa8\xabU\x92y\xfc\xb1\xff\xfbP\x19\xbd\x8a\xcb\x03\xa2\xf8\x0f0\x8d\x98\xf3@\x17\xecT\xb3K\"\xa1Bq\x99\n\xc3\x06\xfcqs.\xebK-\xf8o\xd4RF'\x02'\x88U\xa6\x8f\xfdV\xe7\x16\xad\xce\xfa\xdaB\x9a\xb05[\xa3\xef1\x94" + - "\xb1/P\x11TlT\xed\x1c\x00\x15:\x8d42@\xa6~\xceԯ\xf05z\aR\xdb\xc7L\x9f\xff&\x1aFΥ\x99^\x1a\xccX'8\xe5\x9fg\xc1s@\xaf\xe9UY\x93\xa8߱7r:d\x8d\xd09\xb9\"\xda\xe8\xb7\x1f\xbe\xff\xb6\xaa\xd6Z\x10\xa0O\xde\n\xa6t6\xe1\x1f\x9d\t\x1b\x15\xf2\xbd\x1fRl\xe5\xf9\xa2\xe2\x1c" + - "_\xbe|\xee\x05nf\xad;\xdd닢ݦ\xf1\xde8\x8b\xe3\\}\x1dvt\x84\xfao\xb7\xa8\xcc.\xfc\x0e\xbdӾ(\xa6L\xfd\x865b^\x94\xd1\xe1\xe1ϸ\x1d\xbd\"\xa6\xe8I\x91\xcci\x80\xd3xU\xc2.\xefg\x9d\x87\x05ա\xbc8\xba\xfa93\x97\xa4\xf5\x11\xe6*z\x82\x0e\xceܣ\xab\x81\x82K\xa5\xea\xdb\xec\xee" + - "\x03\xcau\xaa\xca\xdb\f\xd7[ܕlh\x0f\x86~\xd8x5\xc8\xd7\t\xd6)\x8bz3}\xe8\xf0\xc1\xa5\xeah\xbc\xfb\x97\xe5U^̃\xf0#I\xb0\xc0\xa8\x14!Pk\xfe\xc0\r\x04\x83\x109\x01\xf4:\xca,\xfbA\xa4\xe6\xa0}\x03\xd0\x15\xe6\xd7IxQ\xbb]\x94N\xbc\xdf\xfaz\x9e%\xf3>\xc3\x06\xb2\x05~Wx\xe45'" + - "\xa6\x03g\xcdUO\x83վ\xfc\xaaT)`{\xf4\xbc\xdbм[\x89\x90&k\x88\xffdc\x10랠\xe1\xc9\xd7\x1c\x01\xa5\xdckq\x914.\xec\xd3i\xbb}\xc8\xc8\xc0\xee\x11\x8do\x91\xd8\xc0\xad\xbaNh(\v\xe5kZ\xc0\xc4\u038b0\x96\x96f\fß\xe0\xe1a33\xf4\xa6\x11\x971\xe3\xb5\x16\xe3\xfb\x95\x96\x0e\x10\xcb" + - "\xb3\x1at\xde\v\xf9\xc1\xbe?\xc4U\xe3\xe2\x9c\x05w\x8c\xc9\xd9\f\x97>\x9d\xd92\x10\xa6;o\x81;.\xcfەL\xbb\xe85\xc8R\xd2zH\xc7'\xf7\xef?\xa0>)Y\x9av\u007f\xf80\b\xcbH\n\x1a\x13\x81\x11>\x1c>\xdc\xe9\xec\xe6\xb4h\xb6\xdb\x1c\xd2/\xa2&\xd6GG9\r\x16\xf5\xb0\xda\x00(\\&\xe9\xb8ݿc" + - "G@W\xc0N-\xea\xf5~\u03787\xfd\xe7l\xb3ĚI\xac\xff.\n\u007f\xfe\x1dX\x82r\x1f\x03\xab\xb9sL(\xa7\xc2\xef\xa2h`;\xd1&e~\xcb\xd4/\x99\xfa\x97V\xb2\x12\xb0\x80-\xcc\xf8\xb70އ\xb2\xd5\xef\x99\x03{2\x0e5\xf2\xc960P)\x82\x92Ré\xfc\x83\xf2\xa29\xbbIXa\x9b2\xf8\x86\xa8\xa5" + - "\xac\x98\xaa\x9f\xa81\xb8y\x9ft\xddډ\x86\xb0\xc0\x84]%\x89\xb6^\x82\xeb\xcf\xd9\x06\x9b^\x1a\xfd\x9e\x19\x9bG\xe2 ӣ\xa3T\xeeS\\\xab\xedd\n\xedY\xb1َ\xa3\xd6'1\x81\x8eJelwM\xbe*&2\xc0`\xaaQv4\xa1tێQ\x19\x80#\xd24\xeb\xf7WV\x06\x952˚a\xea\x16Uԣ\xf5\x8c\xb2\x86\xd8\xf8\xb2\xb4\"F:\x03\xd4N\x94\xe2\x16)\xee\xf9\xa96\x90O'\xf7\xa7a\x0f\u007fa\xe75u\xce\xc7\u007f\xba\x14F\xa7h" + - "\xf8\xb7\x8c\x0f\xeb߬\x16`}F\xfe\xbb\rf\x19\xf9?AwD\x14\xbd\xb4\xd2\x1c\x85\xb08\x9eF\b\xf6\xa1i\x03M%f3ў\xec))\x91\x19\"_Ϡ\xf5bE\xea\x0e\x06\x8c\xf6\x19\xdcМB\xae\xdf\x184\x0e6Q\xaf\xef\xd0;h\x1a\xbd'\xadx\fv\x10?8\x1fa\x10i\\\xc1\x9e\x8c\xe4\x0e\xf57Zu" + - "\xe8&\xe2%\x1c{ڍ\x8c\x01:\xac\xb7\x19\xcc7\x05\x13\xb6}\x99\xa0\xc7u\bF'\x8fN\xfa\x05\xa3\xc9\xc0\xf4\xb7\xc2\\.\x1bݰ\xd2\xc8)\xe6#-e\x18\x1f\xfb\xb5\x1a4\x14\xe9\xabt\xf1\x81圉\x9al\x14\x8d5u\xea\xc9)M]\xa2RC\xbfl\x88`\x11e**j\xb4\x89\x96\xf6n\xf7\x06\xad\x0e\x13\xa8Ӭ" + - "\xcb\xd0\x05n\xc6\x1a\x82\x04\xc0\xd5\x16\xbb\xd18q_\xc5%\fF\x88\xa4\x81\x9a\x03\xdcY\xa7Y\xbc\xd2&\xeeiR\x86\x95\r4\xda\x1f\x99\xb2\xfd\x13\xda\x1e4\x9dB\x84\xb3yT\xd2\xe2\x90\x16\x8e\xb3\xd4æ\xa2\xa3\x18\x99\\\x0f\xcc6\xb0\x81\xf7\x0evY\xa8\x1f\a\x8d\x8a\xf2\x14\xd4\x1f\x12\x0e\xb1\xfdh\xbb\x9f)U@\xdb\xe3\xa6>" + - "w\xd4Q\x1a\xfe\xee\xabqk\xbcB\xde\x01\x9a^\xd4Y\xd6D\xacר8\xcdF\x99;\x8c\x99\f\xe3\x89\x03J\xbe?L\xaa\x9a\xd2\x19\xe2\xca\xc9M\xa8\xbe\x9d\aF\xe6\x86\r;\xa4\xac\xaa\xf0g\x9d\xed\x0e\x9a\xeb\xe9\x9b\xcc.\xa8\rm6&M\xbd\xaeFVt\x023\x89\x99\xfa7ugK\xe3\xce\x14\x83\xb1\f \xba\xac_\x8d\a" + - ">N\xb2\xb8\xe6ۢ·\xd3g\xa5\xcc\\\x8b\xb3\xf42\xdc(>\x00B\x9d\x03\xbf\xec\x02\x98\xca\x1b\u007fo\xa6,\xf3\xae\xb5\xf0t(\xab\x1d\xe8g#A\bX\xfb\xc0\xc4\xc0\xb3]\xf0:Lޜ-\xab*\xf6\x90\x9eT\\C\xa2'\xd2s-\x90\x944b0wq\xc9\xe8XD\xe4b#\r\x18\x12\xfd1ʙÁ\xaf\xe3\x82" + - "\xbd:\x14\x14d\xee\xa4\x13\xc6\x1e\x88]\f\r\xca\x157\xf9\xc2փ>\x8fY\xd5P\xf3\xf9@\x99\xb4i\x8bi]\xcd<\x90\xdaB\u007fEJ\xa5z\x01-#J\x03\xb9sC\x85\xa3\x948\x90\xc7\xd4\xf9\xbc\xd0j\x94\xf6\xa4P7\x83/\xfe\xef\xe3\x0fD\xaaPj\x9d9x\v\xc0\xd5X\x8b\xb3\xf1Z\x9b\xff\x86\xeb\x1aP\xada\xefʞ~L=\x99a\xb0\xed\xb2\x18|u\x05\xca\v\xe27\xde\xfeZ\xc4k\xaeD\x893f\u007f\b\x9c<\xea\xbcqS\xe0\xf4\x8e\xfb\xe5\xc4\xfd\xf2\xbb\xfb\xe5\xfeԸ\xe2/\xc4`\x88\xe1\x1ax+\xfa\x97\xa6SS\x81" + - "_՛\x84ޥr`\xe73Վ>\xc5u\x1f\x91\x96\x8b1Z\x94@z\xc7S;\x80\xa0.\xcd6\xc9h\x86\xad\x82\xe6\xed\x9cU\xf4k|\x99\"\xd8\tnrZ~\x85\xf9\xa2\x85\x1e3*r>6\xddC\xf5\u0094_Dsmt\x1a\x84]+I\xdd\xec\xd8\xe1\x8bo\xa2E\x87\x8b@-ČW#\x84mZZ\xd7\xc0\xb4" + - "Lj\xc00\xb5\xff]t\xe9\xa84\x11\xfa>m\xaf^\xabY7\v\xeafUj\x06\x18\x8a\x9dӳ\xb3 \x8e\x88\x96]\x8c\xd1\x05!\x9d\xfb8\xd3\xf8\v\xadF\x1f\x81\xb4%\xf3\x99\xa7\x16\xec\xf5\x024\xb6\tѿ\x0e\x9c\al\xcf\xf5\xea\xc1\x1b\x80Q\x1a\xfe0\x8a\xc2EYq\xe4KE\x81ï\xcaYs*%\x82މ\xb7\xd3" + - "\xd4OT\x14ʍ\x17\xdd\xd0@\x12'\xbc\x01\xaa~H\x1f\x91nϒH\xee\x85\x05\xb0\x8d\x0e\xe5H\xdb\u2066\x882\xa5\x81\xdc@B\xb02EyŸ\x03\xa2\xee-\xf4\\\xa4=\x9bI[\xb5e\xe7\x95fј\x1b\x93L\xa8c\ny\x14\x86\xa4ōe57\xb6S\x94n_\xda-m[\xcb\xf1h+i\xed\x80\xd9vz" + - "\x99T\xe2\x8c@{\x83t\xd3X\f\xf1\xfa\xfbN\x11\x11\xb6\xaf\x1c\tPƏ\x17&!95>r\xfb\xc2Ү\x805\xd6\x04g݃S\x8d\xaf\xbb\x17\xfb^\xa2\x86\xea\xa4\xfb[\x10\x1a\xe7\x81ԩ\xbe\xe9\xca~\xdd\xe5\xc1\xbd\xaaW\xbf53)\xabd\xad=\x92\xb9A5\xfc\xab\xb0\x9b&\u007f\xa5\x81j!\x13\"\x96o\xcc\u007f?" + - "ړ\xf6\xbb&H\xd5\xdeDu\xe6\xa3\xfbM\xb9\xf9E7֯i\xcb\xde߬\xe4\x86bpµ\x9e$2$\xb8}ǻ1\xa0\x17\xccj7\xcc\xc4\x04Ѣ\xcf\x11\xcdfs8\xd4O\x15N\v\x86RbԹ\x8a\xd6e\xd8,\xa6\rW\xc1\xe6\x10\xd7ܝ6\xff\xbd\x10P&\xcd\xda\xf9\x1d\xd5s\x80\xd5t\xba&~\x9a\x0e" + - "\fjX\xc8F\xf5q\xae]\xf5\x12^V\xedZ\xf3\xc9}\xb5\xb3\x03\xa3\xc7O\xccB_\xd2\x12\xef\b\x06\xf6Tt\xd3n\xad\xae\xb1\x8b!\xc8\x01\r\xc75]\x85\x03I\xdb\xc1}\xe0\xc3G\xc9Q\xa3\xe4\xe0iۙh\x83n\xb16\x19u\x18\x826vG\x99\x12\xb47u T\xdeb\x90$\xb6\x8d1ӿ\x89\x9fj1\x97\x92\x8c" + - "\xf7\xacD\x17159\xff\x13\x13L}\x9b\x96e\x1a\xfe\xc7\xe0O\xaa\xa19\xc5\x04\xe9ؖj\xe1,\xab\x9d5\xdd\xd4\xdfns\xfa\x10\xb5\x0f\\\u058c\xbd\x06\xa7\x97\x88\x1f\xa6\x02LD\xfb\x18\x8c\xa0X\x81\x0epyz$\rF\x10\xe3Z\xbfH\x8c\f\xb0\xa05[^0\xd4\t\xadnb\u007f}\xbe51\xca*\x03\xf9\x1e\xc5\n\xf2" + - "K\xa1\"Y\xd9сΎu\xff\n\x89\xa9#\xa98h\xb3\xd3\r\xbf\xf6\x1d\n\xea\\\xfc\xc8p9\xfc\xa6 \xf9\xdc\xddf\xa8'\xbe\xefa\x03f\xac4\xc4\xed\a`rɈ\x16\xc0\x96\x02\xf0\x17\xf3l3\\o×*_\xcc\x17\f\xf3;O\xa4\xabxN\b<\xb8\f|\x97z\x85\xe9b?\x89t\xd7~\xac_U\xd6\xec" + - "/\b\xc5&\xa6w=\xc8J\xebW\xe9\xeci\xb3\xb7\x8bqQK\\\xb8g̤d{O\xb7\xe2<\xc4\x10\xfe\x9aA\xe0_\a\xfc\x9c\xddP\xd6\x1d[I\xc7Vұڵ1\xfa\xb3\x9aک.\x80Ε۟\xec\xb2\xd0\xf4e\xc5}\xc9\xf4e4\x1cŧ\x15\xbb\xb3-(\x05L\x01(\x9dT\xb6\xf1R\xd7(0\xf3\xdd4\xaa" + - "\xa5W\x976\x85\x14эP\x93a\xb2\xb3~\x81+\x01\xdc\x1b=\xe8\x8c\xeao:\xbbݟ{\xdb\xda߰\xcd>l\r\xe7\x05>\v[i\xd4V\xe2ԎQ;\xacJ\x01\x9b\xe2n\xaa\x00\x13\xd6j\xdb\x00͆K8\xc1 ud'\xb4\x99\xd4\xe2NکD\x82*Q+\r\x9f\xe1\xc0}P\xb8\xdd\u007f\vK\x16FLk\xe4\x8b\xc5x\x18\u0588" + - "\xb5\x06!\xb7\xa6C\xebǰ~\xc4\xd6#\xb4\n\x9a[\x8e\x9d\xe7I\x1dk\x1a:\xe1\xb5\x03\x1e\x83\x94k\xe4\x1fE}\n\f\x19}W\xbf\xcbF@\x13iE\x84\xbf\x15̩\xfa1j Z\xb9\n\xa9H\x13\x00\xba\x8b~\x9d\xb5\xa1t\xd6{;\x94\x0e\a9/\xb4\x06\xf3+7`\xe7\xe3N\xbf\x0f\xb4\\\x98\x93\xe9\xf86\xf8\xb4\xcf" + - "\xb2\xfcYNd\xe2=~|\xfe]p|\x9f\xa9\x18ل\xa0\u0383\xae\x89\xf6\x88]#\ue73dm\x9f\xc2\t\xef{z\x133\xfe#\xeb\x9b\x13\xeb\rB\xcb\xc7\x12\xda\x05\x89cOpŏ'\xd9\xc83\xb3\xc9\x14\xfd>m36\x11\xa6\x18S\x9eP\x06R|-\xe3\b^\x1bg+\xe5\x88\ue4ca\x18\x91\x19\xe3t]\v\x03\xe1" + - "\a:m\n܋\xf7\xf1*:y\xa0\xea\xcfn\xbb~\xc1\xa5\xe3/\x19\f\a\xbeӑ}\xdb\x01\xcdL\x02\x93+\xea\xe8\xe6\xc1z\xfb6\xf5/Y\xa0~\x91S\xd7\xc4\xe7\xd9G\xe4\xe8*\xbf\n?\x1b\x0ei#(\xab\x10\xfaZ\x96e`\xd7\x06\x96\xf4\xe6+п\x88\xef\xa5\xf7\x80y\x97E\xb3v\"d\xc7̽\x05\xb0~\x06\xe0" + - "\xa8R.\x8b\xf4H\x18\xdaQ\x80\xc0\xa2\x96~ߞ\xefg7#ǭ\u07fe\a\x12\x9d!\xf8-\x01\x0fs]\x85\x8f\xac\xf7\x9f\xe8\x06\x14\xd6P\x01X-\x1c\x02*A{a\x81f\r\x91\x19M\xe0`\xf1\bj\xf1\x9e˶B\xa1r\xdd\xc2\x13\x01G\xfc\x93\xec/18\xe8/\x81WMk\xe8\xc9*\xa5\xb8?Ӷ\xa8\xddBC" + - "J\xdd\xf9\xddg_gPY\b\x14W4\x1f\xd0ߞ\x0f\xd7\xd2\xcb\xe4wi\x18\xcfrÞ\x04}\xe8\x8dq\x06\xf4\x06\x84Zi\x9a\xe0\xe0\x9a\x94\xbf\xb5S\x82\x83q\x92\xe2\x15iwA\x98cr\xe8\xc1\xb9\xb1\x9d\xd9\xed\x81\xcfA\x81\xd5hr^0\xf2pw\x9e\xceX|\xc3\f\x8f\xa0\xb5\x99\x18\x91W$\xab\x18j\xa1\f}\xa3\xc0\xf3\x94\xb3\f\x0e\xa4\x9e\x03]\x97" + - "\xe8\xa0\xf9\x9d\xaa\xff\x03\xf1Bϋ\x1c\x00m\xc5\xe05\xc5x\r\u007f\xbfy\xb6 \xe6\x05\n\x9d\xcd\bw(\xc2\x1d7BUl\xe0\xe8\xb1\x19\x8b/\xbd\x10\xaaKw?R\x06\xee\xabt\xa0\xf4\xf8\xe0\"\xaf\xde&\x1f\xca\xc1\x9b\x12\x81\x80S(\xc3\xe3\xe3eZ]l\xce\xc1\x8a\x1e\xbfI\x80\x95\xb8_\xe5\xe7Ǘ\xc4" + - "l$\xc5\xf1~V\x9fԧ\xd8<\xb8\xb1[ᅿl\xe0dEvn,\xc5j\x81\x97\xf5E\xb4\xd4\xee,\v\xf5&\x92/-h\nG\x99\xc2ƭW\x83\x06^\xe1\x8d\x03f\xd0\x03\xe2̖l\xafsl\xd1g\x05\x90\xf18\x95S\xc9D\xa9\xaf\xc0\xb5\x17uT\xd1~d\xb0\x85\xc0\xe0\xa2y\x06\xbdѓ2X\xea?\xb7\xbd" + - "\xa0\xf5\x8b\xfeIϓ\xf3\x01\x1d׳\vbX#\x01\v\x1a\xc0\xea\f\xa6Blū?\xb7\xf07\xe0\x80\xc7#:\xf3f7:\x1fī\x8ar\xc2%̊!2g\xe2W\x01\xaf=\xea\x04\x1a\xaa\xaaXI\f<\xb9Q\xf0.qhY\xc4\x1c\xc7?t\x13 \x98\x13\x04:\x05\x02$\x05\xeb\x8fH,~t\xf3\xe5\x00D\x9b\x8d" + - "\x17\x93\xb87\x9bF\x9f\x1c\x0eC\x1f\xcfbO\x83'\xa7?\x10\xfd\xd9\xe6\x12\xd66\xfc\xd9d\xa0\xbd\x14-&\xb7\xc7\r\xa8\x10-\x13H\xa27F\x1c9{\x94\x8cf\xa2\xb2\xb5\x98\xbc\x99̦Sì]t\xdfk@Q\xd7\x16\x12\xddh\v\xc0\xd0\x1b\x0e>'r\xa6\x1e\xaf\xf0\xe6\xf3\x90\x9d\x0e\xb1\x8fcO}\x11\xc2;\xb1\xa7N" + - "\x1e\x00\x10\x8a\xa9_u\xf2Y\xa8\xbbD\x9d\xfc=\x94NW'\x94\x0e\x03\xa4N\xbe\x00Q\xb4))\xf1\xfd!,\x96\xd6%\xabM\xa8\xfb\x147)g\x9ezp\x9f\xd2K\xf6\x0f\x1e\b\x05\xb5!\xba\xf2\xc1Cy\x06<(\xbd}J\xb1\x81M\xf0\x80J\xbb\xc8/\x11\x992`&H=\xa0\xc28\t\x95U\b\x15\xf0\x90ʒ\x94\x0f?" + - "\xc5)\x0f\x13-z\xa6\xc4\xf3\x84\xaa\xf7\x05=\f釲8\xa1\x1fJ\u007f\x9f~(\xf9\x03\xaa\xf1\x90\xd2>\xc4\xefI\xe8}\x8a_\xaa\xe0g\xf8\xa5\xda\xfd\x1d\xbfT\xb3\xcf\xf1K9\u007f\x81_\xca\xec\x1e~)\xb7\x9e\xa7>9\x19RF}\n8\xa1\x8c\x06\xf8\xa5\x8c\x8e\xf1K\x19-N\xf0@9-\xeeひZ\xa0\xcc\x13\xcak" + - "\x81Bћ\v\x94\x8a\xbe\\\xa0Xt\xe5\x02\xe5\xa2+\x17(\x18\x1d\xb9@\xc9\xf7O\x90\xe1\x10O\x9c5\U000be3fcO\x90\xf9Ç,\xf0\x93\xee>A?\xe8S\x9a\x06Ejt\xff>E\xe1I\x0f\xafpz\xa6\x857\xde\xff\x10\x11\xf2\xffP\xb4\xd0;\xa4H\xa1\xf7\xdfԷ\xa1\xf77\xea\xc0л\xe3)\xca\xe9\xbf\xe7\x1e\xa0\xfa\xf9\x9e\xf2\x00<\x03ߕ}\xfa}M\xbf\x91\xc7\xfd\xe2\x8d\xe87<\xa0\x87\xbb^x\u05fb\xab\xe8)\xf4\x1e\xd1\xdf\x01\xfd\x9e\xd2\xef1\xdb8)\xef\xec\x8c\x1e\xb6\xden7\x9a\x9b\xeb@\x8d\x13K\x1f\x19 V~e\xcfi\x9c\x93\xf3\xa6sb\xbeT\x9fF7tڇ\x17L3\xf8\xcd\x13E\x9f" + - "\xa1\x94S\x05\xd5Xg\xf3\xa7\xbd\x1f\x16e\x83e\x9e/W\t\x1f\x00\xebcy\xe9\xe3Cߤ9\xb6'\xcd\xf3\x9f_\xbf\xf8\xf6\xc7_\xbe\u007f\xfa\xfa\x97\x17_\xbd~\xf2㳗\xdf=\xfb\xe5\xf1\xcb\xef~|\x16\xe1\xa4\x1a\xd5\xd1^>\xfe\xf2\xf5\xaf\xdf=}\xf9m\xf4\xb9\x13*^\xac\x88\x9c\x99\u007fK\xbcKd?\x98'.\xf1\xc3" + - "s\xda6\xab\x1f\xb3\xa4#4z\x9f\xa7\xf3\x83\xa1\xc9\xf2\xf5\xbax\x9d\x96\xdf}\xf5Y[\xc6\xf8!\xca\xe2\xf7\xe92&\xba\xe1\xe8\xc8>\xb2u\xcc㥘z\xec\aj\x14\xa4\xe3\xb3\xf3\x1f^|\xf7Ձ?\xf9\xec\xef\x9fO\x83\xb3\xc1q0\xfa\x10}\x18\xf7>LN\xa6\xe1\"^\x95\xc9G\xcb\xd7\x1b\xd3\a+\xaa\xa6\xa7O\\V" + - "Ϟ\x91\x1fp|\x19\x84,k:\xf7\xbd\xf2\x8e\xe2\xcb\xf5\xc8A\x82\xfa\x81\x82V\x95\x1b\xf2\x8cB\x96\b\xa95f\xbe\xf5\xcf\xd5\x02\xf4ry\x95\xa2\x1d絷\xe0\x9b\x19\x1d3\a'\xa1\x00\x87\xe2\x90[\xe2\xe4k\x01~-D\b\x8a\x19\x9b\x8b\xc8fEqc\xe3ʡTY\xb4\xb2\xfe\x1c\x17\xda\xdc)\x15\x97\x8f\xc2\xfa\x11I\xf7" + - "&\xcaF\xfd\xfe\x9bS\xdaÃb\xf2f\x1a\xad\xe8Ϩ\x18\x94\rS\xa9w\xeaҶ\xfc\x1d\xe3^?\xba\xe4\x9fq\xff$\x94\x00\x00=I\xd0\x10\xb8/\xa3UT\xecP\xd2\x1b\xca\xf9ͣl\xd4뽡,l\xf6X\x0e\x82Bb\x9aA\v\xb1\xe0\fZg\xed݈\x96f!\x10\xdb\xff\xcbN\xb7!\xbfQȻM\x8e0E" + - "+\x1e\nL\xba\xf4S:-?A}ч\x8e\xa7\xe6\x155d5Ȉ\xdex\x91\x9e\xaf\xa0\x8f\xfc\xad\xbf\xe2qC\x9f\xbaQ\xb7\xdbC\xb6-9/\xb6\x14\xef\xed6\xbd\\\x06w\x8e-T\x83\x1d-\xda\xe6r\xc5\xe5\xb1U\xfd\x88\xc7\xfaA\xc8?\x0fC\x1d탞\x0e\xeci\xcd\x1a\xe0;\x80\n\x98\x8a\xf6m\x01\x97y\x80K\xa8" + - "}\xd7\x125\x80m\xcb\x1c\xbb\xf2\x05$\r\u007f\x1d\xe99g\x13\x9c\x04z\xd2y\xe7^\xa8\xd3|.U\xf3*\x1b\xf2\x85\x0e\xc9l\xc8\xc9P\a\xbd\xaf\x83NtТ\x0e\xba\xaf\x83\x8a:\xe8\x81\x0e\xdax\xd2t\xef\xda~c\xf1\xddwYE\xd5+7\xe7B\x90\xfa\xf7\x03:؉\xf6k\xb4\xe4$й\fM.'\xe6\xe1\xbeyx" + - "`\x1e\x1e\x9a\x87O\xcd\xc3g\xe6\xe1\xef\x1f/\xfb$P\x9f|\x8e\vN\x11\xdbw\xf5鉫\f\x97\x9a\xf1x\xf4\xe0\xbe\x1e\x01z>\xf9lLCr\x8dӈ~\xbc\xa0\aa\xe6\v]\xc2g\xa0\xa3\xba(Й\x00aD2\x9e\xd4~<\xf5\xcd\xc3\xc4\x9e\xefC\x8b\xa2\x17\xdd\x17m\xf62Z\x8eb\xc9r\xb2\x84\x04|Ĝ" + - "Q\xf9\xe8\xb3O\xb7\xdb\xe5)QP\xb4&\xcd\xdb\x17C\xc0&Hd+\xf9\xf8\xecS\xb5\f\xb6\x0f\xeekYH\x9a\xf9\xa5\xfab\x88\x10ʬ|\xf4\xc5\xdfu>\x1dI\xbf\xf8;%=\xea?x\xe0\xa6E\x91\b\x9b\xd2\\\x8e['\xc0{ueO\x80\xf748\xfd+\x86r\x80\xaao\xff=\xfd\xa1\x1d\u007f\x8eq\\F\x93g\xf13" + - "E\xff\xa6\x9a)\x18\xd2p\xc5f\xe4x\xd4.\xa2\x18#\x06|F\xca\xe4Q\xb4\x14\x8b.\xfc\xd4\xd6HxS\x17\x80\x1f\x11͓\xb9\xee\xfd\xe8\x0284\x13\x9a\xf9\xd3\xd1[\\\fɶ\xfa\x8a\xf6Sy\xd6\fF\xacf\x81S\x83y\xab\x06\xb4\xfb\x86$\xf6x\xfb\x1f\xa4K\"\xc6\x13\x90DGGEବF\xbbfn\x8fr+\xcd\xe5|t\xff\xe8H\x9f\x18\x92q\x8e}\xcb4lf\xc8\x05\xfe\xb4\xb4\xf4\xd21\x8c^\x1f\xf7\xff==^\xd6LM\x89\x1d\xad" + - "l\x11\x14\x9a\xf9\x9ex\xbd\xaeC\xac䭦\xa4\x9d\x89\xbd\x8c\xec\xac\xed\xe7\xdcY%z]\x88\x91\x1a\xd3\xedD\x9d\xca\xef;\n\xbb$\xc2L\x0f\xf9\xbbG\x97\xd4\xecwF\xdf\xed|\U0008e1f4rz)x#,\x8ei!\xb7dj\x84J\x95Yy\xb6\xa1\xfa\xb0\xabO\xbak\xfb\xca+\b\x8b\x86z!U\x9f\xc0\x9b\x1a(Y\xce" + - "^W\xd0\xd0g\xa8\xcf\x1a\xdb\xe0;-\x13骴[a\x01\xdb\xd9n\x89\x99!\xca\"\x85އ\x06\x1cdX8\xea\x98^\x15\x8c\xd6z{\xc1d\xec\xad\xfc*\x80\x9f8ۇz\xdfX\xeb\xae\xdc\x12m\xfbf\xec-S\xa23\x96\xee\xee\xf3;hF\xd4pA\x95k\xfb^p\xf8\x82\\\xe0eV\x11\xd4\b1\x16ּ5{T" + - "P\x13\xb2@\x9f\xb5\xa9\x99k\x99\xa5\x1eψX\x84~|N\x9d\x10\x8cr\xbdO:kc\x05\x17\xbfDS\x9f\xf7\x17\xffu\xce]\xb4\xe8EDd\x83\x01Y\xf5#\xa2\x83r\xc3\x0f\xb4\xfe\xe79\xb90\x8c>\xe5\x92\xf5N\\*\xda;#\xca\x14\xad\x930C\xaf\xf5z\v\xb6\xfa\xc8k\x17\x9f]5\xab\xbd\x9c\xe6\xf5\xac\xac\xbb\xef;" + - "\xe2\xd7>Y\xc8u\x17\xe4Z\xc1\xcdyt#\xd3(\\\xa8Yx\xbe\x1b\xa5\xd4\xc3:k}\n\xe5\xea|0ws\xf9\x12\\\x9fQ\x1d\x85w\xb1Q\x83մ\xacٹ15^\xd0hb\x93}\x87ؗ4\x1e\xb8\xc0\xd5\xe3q\xf9\xa8\xa2\xf1\xb8\x94\xec\xd6Q1\xb9\x9c\xaaY\xb4\x9e<\xe0\xd95\vܣF'\xe9\xf7\xe7\xcc\xeb\xa5" + - "\x13K\xfbσi\xb4\x1e\xad)\xdd\tv\x10\x9ark&E\xde\x01k\xe1ǫ\xccx}f+\x997\xd2q\xeb`\xf4n2\x9b\x8a\xbe\xcbN\a\x1eOΆ\xfd\xb3͂\xfe7%&<\x8f~\xf4\xdf@\xc2a\x98Ӆ5\xa8\xb3Fn~Q7\xfa\r\x94\xad\xa8\x9d\x937ꏩmj\xe3\x88\xccٵ\x87Z\x8b\x9e\xc0P" + - "\xcd\xf9\xf2]\x8b\x1c\xe7\xd4\x173s\xf9UQ\xed\xe8tZOb\x9cO\"\x86P\xbc\xd1k\xb1\xf6[l\x86Z\xd8\x1d\\\xe8e\xccx\rrz\xa5\x93\xb8\xdeJ\xa7\xa3O\xb0\x99\x067I\x14\xeb\xaa,\x994yK\xc4\xcbp\xba\xb3\x00{8\x06/\x1e\xad\xa8&\x17ؔ\x17\xb4\xeb3Y\xd8L\x16\xdcH:\xb3m@\xd3\xf5m\xf4" + - "\a\xdb&Q\x16o\xed\xa6\xfd)\x1d\t\xab8[29\xf9\xb6\xb1\x00>\xc5!s\x88kf\xa3\xd0'\x00p\xb6M\xa0r\xa4Uo\xa3\xe7\xbb\v\x80\x0e\x03M\xe1m@D\xeb\xe5\xe8\xb2\x17Ŏp\xe0\x02\xb1\x91\x83\x90\xb2\xf4\xcd@\x1c]\x04\xea}T\xf6.\x9c\xc8\tl\xeeo\xde\xdb\f\xfa\b0\xdf\xcb\xe8}\xdfD\u07bdmT" + - "\xfa\xd3`\xf4\x9d\xff\xa6\xb7\x84y\x91\xd3\x12\xd8m\xa8w\xfa[\xafT\x17\xea'\xff\xad\xa2rm\xd8\xfbF\x8a\xf7\x12_N\xe5w2\xf5\x90+\xb5\xac\x18̣w\x16\x8b\xbd^u\xd7\xf5\xd67\x99\xb2\xb32\xe1\xde)\xc3\xf5*\xf9i\x93\xb3s\xf4\x82Q\xf95\a>y\xac\x98\x9d?\xbb\x8b\xff\x84\x1a\xbb+Tׄ\x880\xe2d\xce" + - "\xee2{\xe3\x8f#|\xa2Q\xbdg\xa33J\x96\x87\xff$\xa1\xd7L\xe89\t=\x93\x90\xa3sB]\xda\x19ej\x13\xe9\xcc%c\xf3\xddk\u007fG\xfa\xe0X}\xc2\x1b\xb8w\xf7\xcc\xf3\f\xf9|.\a\xcc\xf7)<\xfasC\xc7{\r\xfd?*v{\xf6?\xe6\xfb\xff\xb4\xbf\xff\x8fT\xcb\xd6\xea\u007f`y{{\xf1\xecX\x89\xb2\x18" + - "t\x97\xde\xfa칙\x9fyw\xd1\xe4\xf3\xc1\xfb\xa48\x8f\xab\xf4R7\x16\x1a\xd4uq\xffm\xc7e\xca\xc3Tg$\xf9L\xb5p\x87\xf6\xbf\x8b'\xf9\xa5\\QpȌݹڰ\x1bӈ'\x94\xeb߀\x1a2\x0e\x85~\xdc&\xabt\xb1E\xd7o\x93l\x8eG\x9c\xe7\xdbtA\x9f\xb7i6[m\xe6\t\xbd\x81ڄ\xb8(" + - "ٮ\x8bxy\x19o\x99\xfe\xdc^\xc5E\x06Y\xd3\xd9\xf9\xd6\xfa\x992M\xfc\x1b\x1a\xe8\xb6摔\x8b&\f\xe8\xbf\xe3\xe0\xde\xf6\xecx\f\u007fP\x93\xb3\xab\xfe\xb4Ǯ\xa2\xe41\xe8\x05cy:\x1b\\l\x99$:\xbb\xba\x17\x9c\xea)3Ջ\xaa\xd1*S\x81f\xf9]\x9d\x91:\xc9\xe0\x9c\xaa\x99ҩ\xb5\x8epO\xe6Ƚ" + - "1jx\xef\xec\xd8\xe9\xff\x1d\xe4\xab\xcb\xe4\xfa\xfb\xb4J\n\xda\xc4\xea\xf1\x93\xfd\x90?z\xca\x02\xb6x\xbd\u007f\xf7<\xff\x98\x97\xd4\xf1\xbd)7\xfe\xd5q\xcd\xc6`\xbeЏ\x95B\xf0\x97\x0e\x16ˉ#\x93\x02\x1f0\xc1z\xc7Dqaf\xd1\xc9\xfc6\xf9\x00\xa0\xa6\xb2\xa6\x1e_\x9d\x95\xc4[\x95\xbd;D'{|=gT.L" + - "\xb5\u007fV.\xb8\x8c\xd7;wHϲ\x87d[\x00\xb1\a\x90U\x04\xa6\xbf\xcc8\xfc\xa1\xb8\x043\x02\a\xe8ֳ\xeal3\x1c\xc6Cw6\xfc\x03s\x1b\xa3\xfa\xfa\xceT~\xfe\x1b\x8c\u07bd\xe3TrT\x93\x17\x881\x9e\x80\xa4\xef\xf1\xf0\xe3э\xa9'\x82\xe22?\x9a\xd5?d\xdd\x0e\xaf'\x9a\xd5\xecm\xd1as\xfa\xf3\x1an" + - "\xc8\xee\x9d\xcd\xefɜ\x9c\xdf\v\xc6[\xfc\x9e\xf500ɤw֟\x8e\x11g\x1cp%L\xae\xca\x1b\x9e\xdc\u007f\xf0\xf0\xd3\xcf\xfe\xfe\xf9\x17\x1e\x15\xf1\x15\x151\xa0!*Ϯ\xce\x06w\xfe\x9bv\x06\xef\xec\u007fh\xe2\xfc͙Sz\xb3\xff҇L\xb6\xde\xf1\xef\xb4\x04\xa4O\x99h{z*\xe0\xb7o\x8e\x8e\xde\x10\xcbC\xc4x" + - "fŲ\xe5:\xce \x95}#D\r( \x8aFQ\xdeD\xefF:\xda\xddG\x88u0[\xc5e\t\xb1\xf4\x1bu\xd7;\xbd\x1b0\xdd\xff2\xfa\xe0\xaf\x1b\x14e\xa1\x9e\x12\xab`\a:\x19\xcf\xc3\x19`\xf6\x8e\xfev\xf2\xd9pDE%t<2?\xf220%\xbc\xb4\xd1c:\x18\xa9y\xd1Sa+R\x9axB\v)\\\t" + - ",\x15\x04\xd5s\xc5\b\x8d\xc0+\x90j\x13\xf9\xc4?B=\r\x89R\xfa\xdd\xef\xb8\xe5\x01\xfaƱ?\xc1<:\x98\x06\a4\xfd>\x99S\xc0\xab\xed\x01^.\x89\xc3?\xc67\x1a5\xf8\x95}\x1b\x1dOx\xce\xc1\xe1l\u008c\x0f\xf1\xfb\xed;\x15\"\xf3.\xa2\x8b\xf1\xf9\xc0\xdeW\x80\x1ay\xfe\xf3W\xde\xf8\x82\x9e>\x1b{\xd2n\xf6" + - ",\x1a\"\xe8\xef&\xe8\xd1yqz\x06\x9f\xf8&\x86}\xa4/\aǧ\xb8\x96\x93\x87\x91\x10g(\x84\a\x81\xafE\xec=\x106\xd2lsY\x9e\x9d[gx\xc1\xf88P,\x9a[֔\xe6{t\xda\x15\x91jW\x8fN\x86D\xab]\x05\xef'W\xd3\xe8\xa2w\xf7\xd1\xf1*=}\xb4J\xcd\x10\u007f\u007f\xb7w\xd5\xc3\x18\v\x1e&\x8b" + - "\xaa\x88\xb7\x87k\x18\xed}\x10\xcf}X\xad\xd8)\x92\xafLjS\x1f\xaf\x99\xa5\xfa\xfa\xbfN\x86|\xff0\xfa\x9a\x91>9\xdd\x01\xdfp`V}\xdd;\x91\xaf\x99s9Q\xb6\xef̞F\xef'\xbd\x1e\xb2\xb2\xb6\xbd\xc4\xf6\x99y\xdc{\xdakM\xd6\xde\x1bnH\xf8tg\xe4\x8f\x17r\xe31\x1a\xe1l\xbb|\x94[\x87\x8a\x8f̽" + - "\xd18'\x96\xe2Q\xb4\x9aT\xd3\x10\xc3.\xd7iԑ>>\xf01\xf0\xe6#k\xc8`'N.!\xcf\x00\xcdy\xdf\xcaR\xeaB\x90\x1dJ \x96\x02%Q\xd4Qec\n'\xb7\xf0\r\x0fJy\xdb.s\n\\\xba\x81\x18\xc2\xe3|\xc5W,\x03 K\xedK\xe26\u0086\x99\t\x91ּI\xbf\x9f2\x83\xa4\xbd\xf6-&)\xd3" + - "\x8aߴ\x99\xa1<\b\x1f\xd0>J\u007f\x13\xee\xba\x05\xe3\xca\t\x96*\xf87YiqLG\x13h\xe8Z\\#\x04\xf5*\xa8y\xb9!mE\xf6\xfa\xf1ͣwr\x01\xc8\x1e8\xe5\x12\x10s\xce0:'GG\x975\xb7\x85}\xe3\x91'\x9aB\xe7\xb1\xf6\x9dƒ\xb6Y\xfdfH\xafKg\xc3\xfdB\x99\x1c\xfb\x0fh\xef" + - "\xccz\x91}?\xa9g\xde|?\x13\b\x0e\x02\x886l\xa4K\xcb\x00\xfd+`\xd7~\x97\xee\x81\xed\x9f]\xf5\x02\xea\xfa\x88\xfe1\xe9\xe831y/ \"\xf2\xae\xcf\xec\xc0\xbd\xe0\xee\xd6?{A;\x10\xed\xa0w\x0f\xee\x9cDޝ\xfbw\x1e\xdcyH\v\xdb\xecX\x93ٓ\xe9d\xf5=\x1d\xb0\x8f\xa7\x93\xf2\x05\xff\x8b\xce<\xc9\xeb" + - "\xec\x1c.\x11\xe6\xc9\xd9\xf9q`$]\x97:\xe5\xaf\x01q\\\xb4\xb9\x9f\xa8\x19q\xecoz'\xa38\xe4\xa5<㎶\x97=+\xe2\x82m\x12\xf4\xf8\xfc\xe8蓹\xb8\xf5a荹f\x1a\x8f\xa5\xbb\xfb\xfd5\xbd\r\x03^u\a1\xf7F\xaf\xb7\xde\xf1]\x16\x1d\x85\x85\xf6t\xa9V\x1a\xa5\xfd\x8d\x9a\xf5N\x02\xbb\xc0\xb0\xf2g" + - "҇6\xeae\xd0\x1d \x8c\xfahM\xcc(\x9e\x88W\xafau\x8f<\xae\xed\xdbG\xc3 \x8e\xd65~}\xbf\xffv\xe47c\xfe\xcdSo\xa9\nA\xbdh\x13\xf7\xfb\x88>s^\tE0Jlkgμ\xed=\x80I\xf12:a\x14,\"\xd9.\x9a3\xf1\xda\x03o|ѐ\xef\x8e(\xfag;a\x95\xed\x8d\xe1\x85ZR" + - "It$=c\xab\x03\x98&4\xf8ܷA\xb7l\x14n~\xeax\t\x1a\xb3\xdbQ\xb3k\xc2!VX\x0f\xb5\u007f\xee\x98\xef\x8f\xed\xfb2\x86\nK\xfd~\x11\xf3\xf1a\xdfS\xfa~\xe0|\u007f\x13\xabO\xd0\xc5\xe6\xf2;\xe6\xa5b\xb8\xf9\xdd.\xaf\xe5Zvd\xd5EX\x88Ӹ\xf7Q\xae\t\x91\x91\xa1H\xa2\xf7Ps\x83\xdcm\xb0" + - "\x84\x13\xd9\xd1O~\xaa\xde\a\x90\x86\x81\x0e\xd3БW\xa2`\xb8\xb7i\x06f\xcf\\\xe5K\x9f\xb6P\xf6\xf11{;ֿ!\xec\xf0Q\xf0c\x96m\x10\xd1\x1fyo\xaf\xd8\xff\x1b\xe5u\xe9\xa9\x17\x91W}X{\xea\x1f8p+O}\x15y\xebM\xe6\xa9?\xe8wE\xbf\xcf)]1\xf3Կ\xc4\xc9\b\xed\x83\xea\xdfQ\x87\xd0" + - "\xed<\x9a@\xbd\xc8;\x8c\xf8\x0f\xfe\xd2\xe4\x82f\x91\xf7_x9\xc2?\xf9ï\xf8\x03\xf5\xa2{\xf8\x87\x97\x1e\xfe\xe0\xbf>\x1e\xfa\xa2AD\xff\"V,\xa2\u007f!+\x1d)\xd61z$\u007f\xf0\x8d\xff\xf0?\xf9\x83\xbfH|\xca\x0f\xfc\xa4\x1f\xe5\x99_\xa0\x97\xf4\xdf\xf4oB\xff^\xe1\x1f\x02_\xf1\x13?\xdex`)\xe8\x1f^\xb6" + - "\xfc\x84\xc7O\xa0G\xe5\xf1\xfa\xa6_HM\xf1\xa3\xaf3\xe9Q\x8cx\xf1\x90{\xf0\xb6\xcf\xdf\x17Б]}\x00\xf0eFc\x92͒|A/F\xe1N\xbc\x00\xe0\x17z\u009eȣ\xa0\x06\xc5\xd7'\xaf^m\x01\xa5鱙o\xfa輾\xb7I\x83\x05uٖ\x98!:d\xeb\xed\x95\xf6\xcf\xe8\xd1ix\x04\xce\x00\x9b\xa7w" + - "vv\xe7\x04\xc87\x14\x99\xf8\xa3\xf2\x9eg\xa5\xd7;?P\xdfG\xc7G\x14\xeb\x87\xe8\xf8\x11\xfd<\x8b\x8eO\xe9\xe77\"`=\xfaM\x88\x92\x85V\b\xee/\xf0\xb8\xe4\xc7%\x1e\xe3u^\xe2\xe5\x02/\xac\x14B/o\xf8\xcb\xe5\x1a\xcf)\x9e\xb3\xf3\x92_\xde\xd2\v\xd3˸\n\xf9\xa7\x10\xd9ql\x11C'\xaf\x1e\x11\xff\xf3\xe8\xb0" + - "\xdf7\xec\xe3\xbdq\xbf\u007fvJAgg\x93'O\x1f\xbf|L\xbf\xf5\xb7\xb3\xb3)\xfd\x9f>\x1f\x8f\xcd\x15\vs\xa3\xa7g\xde\xdd\xe9\xf6\xee\xe4\x15\x1d w\xb7\xf6(\xf0\x82{\x14W\xee\xdf\xd49U\xe5գ3*\xebX\xcd\xf8\xf9\xd0\x1419Vs\x0e9/\xe8\xd8Hկx\xf6Y\x1a`\x8aѿ\xcc\xccAT\xb4\x8a\xa3" + - "k\xffư\xb4\xa1L\x8d\x033#\x0e\xe6\xf9\x811\xfc\x87\x8a\xb6\xeex6q9\x80\xf9\xd6\x01\vޱa\x1e0fρ&8(\xe1\xe6\x9c\xe2\x80\xfe=\x80\x89\x13\x86\v\x16Y\a\xcb\x1c\xca\xdf\x19\xbc\xbdgK\xcap\x99BS\xf9\xa0\xbcȋ\xea\xa0L\x97Y2?\x80\n}\xbe8\x10C\x99\x03A\x02:\x90[\x87\x03L/" + - "*\xe4`\x931!\x97\xe9$,\xe2}\x9fÄ\x8d\x8a\xe5\x1dGH\xdf\x03m\x97Τ\xeb\xc1\xff\xcb\u07b55'n,\xffw\u007f\n-\xf5\xcf\x1a\xad\xb1\x9d\xfaW\x9d\x170vɒ\x00\xc5B\"\xba\xd8\xeb\x18\xe2\x12\x17gY\x03f\x11\xac\xeds\xc6\xdf\xfd\xfc\xbag$\x04\xcbf7\xc9Kr\xcaU0\x1a\xcdM=\xdd=\xf7\xee" + - "\x9e\xf1\x94\xc4\xe2\xd92\x11M\xa5H\xa2L\x9b/ƟI\x04\x9d4bG\x83%\n\x9b\x03v|\x98\xc5\xcf\xe5q\f\xcd~\xe9b\v-S$\x9c\xd0Y\x93z\xdeJX\x92t\xaa%O\u31e9F:\x16\x84\x0f\xba\u007f\"{\xdeN\x93\xb9\xc4\xd1-p\xb6\x94^R\xea\x04\x80\x83\t\x15\xab\r\x9fg\xc9t<\x90\xf1\x88\x02\fc" + - "\xf6\x10\xc8w\x8b\xf1h6Ԥ\xad/\xcc$\x97\xa3\xdb\xc1\x87\x11]\x86\xbfZ&\x84j\x92\x9db\xb9U\xb6,2_.\x80\\\xd6b%\x81k$\x8b\xa9\xcd\x1e\xc0J\\; ;k\n\x8b" + - "\x11\nW\x1aGh\x0e}\t\x1d\xdc\xc9\b\xa8Z\x81\xea\x13p\xc3H{Lf˄4\x90\x15\xad\xcf\xed\xa6\xe3i\xb6g\xfd!\x06A_\x8c椺Ҍ\x1a\x84\xf3_7on#ɴ?LP\xad\x99\xac'\xef\x1a\xa0~T\xaa\xac\xe4\"\x19˫\x95$\x96\x9fɶ" + - "\xbf\xd6`\xbaGD?\xba9\xf3\x0f\xc1?\x19\x13\xf8\xa8E\x1fl:S\xbc^\xa8\x86$\xab\"\x13\x92\x8df\xe9j\x91\xb3\xdaL\xa9\x9d)r\x8cs\x90\x15\x11\xd2\xc1\x8a\bB\xf0\xa2\x8dީ\xdei\xf9a4\x93춃4\x8f\x14)\xeb\xf5\xa7(\xc25 s\x8a\n\xffi2\x90\xfcu7^s/]\xa6\xc6\x18&\xeeep\xe4" + - "\xc713.\x9e\xf6\xf0nWe\xf3\x80C\x86m\x1f\xa3\xc9Ѝ\xc3\n\x0ez\xd1+MR\x10Z\x95'I\xe5fs\x1f\xa6\xa7#\xf8\xbc|ӫ\xdc\xc8}\xf6_O\xcez\a\xc7=N\x87\x95\nO\xe9\x1e1\x1b\xec\xd1\xee\xc2)\x9d\x8b\xf4*|j\xc2Ӿ±\xc9a\xf70\x8bV\aŜ\xe8\xac,\xd3\x1c\xf01P\xf7l" + - "G\x9a\x1f6\x92\xfc\x90\xa5\xb0\xe5\xae\xfe\xc9\xcd\x0fg=A\xce\xe9vƧ\xe9\xbc\xdbg\xd8N\xd7E\x9ct\x8f\v\xe1\xc7\xe3<\xcbǔ3\xc9[Q\xb6\xf2\xbdç\x91q3N/d\x1e\xa4*7\x91\xe1+\x99\x8bQż\xe3\x19mCSvJv&\x0f;~=ɒ\xf5\xf4\x02Q\xd4n\x19\x16G\x1f\x96Ӓ\xd2Ԯ" + - "\x94\xa6|\xf5}\xe9I\xbd\xaa\xb7t\x92\xd3O\x12\xaf\x9b\xf6\nG3K\xde\xdf&0\x92\xe5\xe7\x92:\xdb\xcc\xe7\xf1g\xa2\xbb/\xb7\x87\xba\xfbg\x9b\xa7\x96\xc4\f%\x05\xf2\xaf9\xc8\xf2\x14\xef\xa8z\x88\x1c\x8ft\x8cr|v\xfa\u007f\xb2\x9a\xc9r&\xcb\u007f#\x8d\xf1u\xd3zO<\xcc\xf4B\xbe,[\x01/\xabO$JO\x19y" + - "\xf3\x8a\x96\x1ct\xac\x922\xab\xe5o\xdd\xe3\x1e>U>C\x1a]\xcf\x19\xe3\x06\xeb2\xc4\x1c\x1co\x91\xf7a\xd6}\xb3\x8eb\xafbK\xce\b\xae\x1aűL\xa8\xf0\xcd\t" + - "_\x17Z\xaf\v\xad?\xb5\xd0\xfa\xde\xd1\xe9\x858n@;:\xec\xccI/m\xf0\xf4D\xee3\x85Lw\xf0!\xcf\xe5\x18\xebL\xb8\x12\x97!o\xecz\xe5\xd9\xd7\x05\xdf?z\xc1\xf7ݳ\xba-q\xa1BcJ_\x9b\xc1?\xbf\x19\x80\x0f\xbe\xd6[\xd2\x15\xad\u007f\x8d\xc4\u007fq\xdd\xf1%\x83\xee\\b0\xb0\xfd\xf4\x03\xf5\xe5\xec\xc2\xf9" + - "k\x9c\xf9w\\\xc0~7:*;D7\v\xad\xf63\xdd.\xfeL\b\xda\xdb\xc2\xd0?lG\xe2\xfb\x11\xb2s\tzSB\xe3\xa0e˜\x9d]\xe3\xff\xffޞ\xc1.\x9c\xed\xfd!\xa4-\xfa\xaf\xbd\xfe\xdf`\xf7\xb0\xb4s\xac\xfe\n\xcd>\xa6\x1b\xab1ck%\x86\x05\x9e\x14\x1aE\xa2\xafZ8h\xd5v[6Xۯ)(" + - "o\xdcU\xfb\x95Q\xf5\xee\xa5\x16\x97ǹd\xcd\xf8(y\xd9QȆ\x05\x9c\x82X\xe2\xfa\xf4yY\xff\xa6ц\xb3\x8f\xd2\xe4\xea\xc1\xff\xff\xeb\xc7j\x86\xa8ڧ\\p\xeb\xed[\x95\xe0dY\xfbtp\x90\xa9\x85<(m\xa3\xf9Zd\xee\xed\xdb\xc2\xcbZXB\x02\xcc]XI\xcf\xe5%\x06\xf5\xf9Na;Z.KA\x98\xfe" + - "\xb1TR\xd6\au\xba\xb1\xbf\xb6\xd6;\x91\xea[$̰\xb6\xb6_KjI=)\x04\xb0\x0e]R\x94\x1a\x04 %\xd2Z-\x04\xf1\xc6\xd9V\xd8\xd3tN\x06\xf5\x92bŒ\xef\xa8\xd8\x1ej6\x94\n\\\xf9\xcd\xf6o\x86t1>k\xbeH3\xc1\xf5\vJ\x94\xdb+ۺ\x84\x9c\xe4\x1a\xf5ڐ\xd4|\xd0\xd1ɫ\xb9\xb7\xd2" + - "\xd2%\x9cT\xbd\xf2\xfe\xc9\x1b\xcb7\xa3뎍\xce\xe2A\xeb\xc4\xe7\xaecj%\xf2\xf7\x93E\xe9\xb4;;!\xff\xf1龮\xd7.\xeao\x8e3\x89\xae\xe1\x11\x9b\x83kEm\x97uC\x18\xa2d\x1dH\xc0\x96\u07b7;l\xa8'C\x8c>\xac?\x97\x87\xea\xeeQ \x9a\x13\x11\xb8\x1b\x89\x92M\xf5\xb8{%\x135T\xa2F\xf7J" + - "\xf10\xa1\x8bP\x88N\xdc\x0e\xf5\xfb\xfaf\x00YGZ\x8eBZ\v\xe7E)6FCG\xb3\x9d\xafxx\x96y\xbf\x12SV&Ԋ\x85%\xf57\xf7B\xdcg\xbc %\x88\x14\xcc\t\xdd_S\x1f\x16\x04\x06\xe8\xb8;}G[c\xba<\xa3g\x81j\x12\x1a($\xa2\r1\x8e\xbbѺ\xcb\xde;\x9d\xd2\xec\x91\\\x8c\xfe\x82\xd2" + - "\xa4H\xd20SE'\x06-X\x81\x90\x1c\xbbi\x05\"\xa9\fI繠\xc1\xb8\t\xd4Y5\x13\xa1\xa5\xdbEI*|J}\xc6\x10}ƠүΩߘr\xbb\x99קG\t]\xd3:=\xea\x17I:ȩ\xf5MF\x940\xffXKN\x06\x05\v kQ\x8b\x84T\x8e\x8aQ7\t\xf7\t\xf7kK\x1c:\xbf~i" + - "\x80\x83\x1b\x1f5\xa9\x92>\\\xb7\xad\xfa\xbd\xb4ȑ)g\xa3;7\xb2\xc2U1\x15\x95\x04\x88Y\xb3,Z\xd8`\xf3j{Ɨj@\x95\x81\x12\x16\x1b\x14s\x90q(\x00\xb7\xee\xe8\xf4⭞\x15\U00106652\xcb۷\xfd\xf2Z\x93t\\\xbfɱ\x06\xa6S(Kϟ#\x89V\xee\x17J\x18\x1a\xbe\x91J\xcaNV\xbe\x91" + - "\x8a;#\xb2\xf8\x8f\xe1gBڌ'\xe35\xfeג\x91J\xa5\x92._\xdfҪ\xcct\x12\x11\xc5w'\x8cYʤ&\xc5)-м\xc6\xdd;\xb8\xffc\xfd?\xf0|i\xa9\xb4L\x837\xa5\xd4\tF\xc2PY\xcf.\xc0e\x15\xda\x1aF\x9c\x97\xf5\xf0G\xf7,M\xfb\x18\x80\xf9R\xfd\xa7\x0e\xd8\x03\xb3\x91\xb4\xea\xabk+C" + - "^\x95\xb9X\x01,\xaa\xe7\x95lB\xe2\xa2\xe3oI\xf9\xd5\xea\xaa\"%\xc0\xac\xd1\xe0\x81\xa7\fէ\n\x060#\x8a\x02\xe7\xfc\xd63\xdavU\xeeS\xaf\x03/\r7\xe6\xd0\xcf\x1cj\xfa\xed\xb6\xedEU\x93^,\xdbt\x8d\x80\a\xbb\xaa<\nA\xe0\x85}}\xe5\aV5\xa0\x17\u05c9\xec\xc0p\xab?ы盾eW/" + - "\xc9\xdfq\rǫ\xfe\x9b\xbd\xb1gFrȬ\xda\x14\x10\xfaq`\xda\xd5\x0e\xfb\x01\x84\u05ec\x1a\x95=\x16\x88oV\xe5\x9e;\xbd\xa0\x83\xae\x86/\xa4\xb0\xb8\xb7'\xcd0\xf1\x18\x97~\x9a\xfcI3L\x9d\xe0h\a\xd2\xca\b\xfe\x02\xbf\xe5\x9b\x1b)\xadF\xb3\x96ew\xd6]h\xdd'\xe3\xc7\xf5\xc9B\x16\xa8\x94>0\xe1aa8" + - ">_\xd8\xd42;\xd2ߑ\x14jQc\rA\xfb;N\x1bX|\x8eK8<̔u\xc4n\xc5\x1cy\n\xc4rw\x9c\xc1\xb0,a\xb8.\xfe\xa0\x870<\xbcy\xd7\xc2\b\xf13\x85\x11G-?p~a\x12\x88sü\x88;\x82\xe7\xe7p\xa3+\xdb\xc63\xb0\x8d\v\xb8\xfeUh\x8b\xf3\u0605\xffZ\x98\xc8lX6=\xe1" + - "\xb4l\xf3B\xba\x1d\xdf\xf1\"a\xba>\x05\xbbq\x88Oږ0}õC\x13A\xbe\xeb\x1a\x11?\xe3\xb6'\x88\xa3\x9c\x88\x1e\x9d\x98C=\xd0\xdc\xe0\x120\x99\x82'\xcc=\x91q\xeer\n\x9ac\xb1\xe7\xd2\x0e\x90\x0e\xc0Q\xce\xc0\x0f\x916\x0e\x02\x9b2\xcb\xe7\xad\xc5Q\xea%rڛ/(\xb2\xdd\xc9C0\x83\v\xe8%\xf4\x03" + - "A\x02Z\xe7T1\xeb\xdc4\x85e\x03{\xbeIeI\xa6\xa7gÈ\xdd\bO\xd7\xe6` \xd4B\x05\x85\xe5\x84\x17\xe4\x00H3b\x0f\xda\x11\xaaf\tˏ\xa9\x02V\xe0w\x84\x15\xb7\xdb\xd7\xe4v\x84\xed\xe23X\t\t;\b\xdcKW\xa0\x10\xa3\x83\x90\xf7\xa6݉\xf0\xb0Mv\b;\xf6{\x14\x17\xd2#\x12\r;2[\xa2" + - "\xe1\xa0D8n\xc30#\xc0ݐ\u007f\xdbiz\xa2\x11\xd8\x00\xed}\x94{$\x02\x1b\x81\xdf\x16\x8d\x18\xecР\xa6GDo\xfa\x91/\x9a\x81\x01\xc45\x03\x1f\xe4o\x19\x97hw\xa2\xe5\xbb\x16\xea}!\x1c\xd4/r\xa2\xeb\xdc\x03\xea\xe5\xfe[І\b\xe14\x04x\xc6\xf1,\xfb=\\\x0f\xc8\xcc\"<\xf0@h\x9b\xec\xf3\x85\x13\x8a" + - "\x9f\xc0#\x02]\x85\xb8\x00\xe8µ\x1b\x91p\x9d\v\x1b\x8eg{\xbep}\xc3\x12\x1e3\xa4\xe1\nt\x1c\xcc]\x9e\xef\xad\xf9\xc9\xf3#\xe1Q%\xc8\xc1\x97}\xfa\xf1?\xb4\x81\"T\xca\xef\xd8\xd2!Z\xcaN\x85_\u007f\x8e\xed\xe0\x9a}\xcc\xcf\x11{߷]<\x19\x19\xc0 :0@\xef\xc7\xd4Z|0\x99\xe8\xd8\xc8\r\xec\xa0\xdf" + - "\xf2\x04\x06q\xd3\t)i'p\xda\x06\nÓ\"\x03\xdfdǶbp\x88\x9c9\n03\x90\x10\xa0T\xf0\xa9\xc5\x0e\x13\x05\x85\xf8^\xc3iR\xd2\xc0n\xa0R\x9ei\x87\xf0v\x90K\xb6\xc5\x00\f\xeas41\x91Iy\xa28\xa0\xf0K\x1f\xc8\n\x9cf\vahO\xd4h\xe1\xb92\xfdأ\x90\xabf\xecXD\xa2 \x06\xc1" + - "C\xe3\x12\x0ep\xd86D\bvEA\xa1\x1dR\x05$\xcb\x13\x0e\xf0\x97\xfeV\x1cY\xfe\x95'B\x1fm\x05\xed#\"N6C\x11^\x03\xf1m\x99A\xf2\x11\xd5\"t~\x81\xa7\x05D\x83\xae\x11\xf8\x1am\xd7c'4$k\x01\xf0f\x93\xf2\x04`6j@Qh\xff\x1c\x83\xaa\xb1G\xd1pA\x0f\x11w\xb8\xa1\xca\a\xa3\a\x1f\x12" + - "\xfc1\x1e\x81B<\x82kb\xc9KǾ\x12W\x86\x13\x11\xa7_ї\xe1\x00GW-j\tWN\xd4\x12W\x81#\vѥ\xd2\xee\xe3a\x8f\xce\xcbǹ\xb6\x9c\x94rQ\x1c6\xec\xc0\xf2\x1d\x9f\xc2\x1fp\xb1jVݓ*\xc7Ǹ\xea;>FӘ\xc8ж\xc5\xc5\x12\xfe" + - "A\x0eT>\xd3{\u2bbc$yg\xdb\xfcx\xb8\xa5U#\x84b\xb8\xf47\x96\xb3\x8fF\"\xde\x16Ձ\x88wNJ\bV\xe4\x93\xfa\x97\xdfX\x961N\x93\"OѨ\x8bU\x8f\xfec\xce\xd0\xed\x03_\\\xcb\u05cd-\xee_'\xf9\xdcg\u007f\x92Q\x82\x0e<7:M(t\xa0\xaf1\xd2\xeaPz\x82^\x16\xe5\xb1l#\x14" + - "\x12a\xf9\xb6\xb0\xc3\x13\xb6\x02cm\t\xe9(\x9a\x03\xe8YR\xdcъd\xd9,5\xf1\x8cV\x93G\x87\xfe\xc0\xa7nD\xfd\b\xf7\xd9\xcdi\x85f\xcc\x04\x93\xe6\xab\xedI\xb2g9\xadMW\t\xb9\x84O\x82T\x82\xa6\xf0\xb6\xfe-\x16\xc5\xe7\xcd\xfa\x93\xa8\xf0x&S\x98\xc3\xe5\xa5" + - "\x1b;\xaf\x0e\x8b\xb6\x99\xa8lE\xf5s\xff\xdc:\xe0u\x96\xda\xd3}\x83k\b\x11\a\xfc\x05~~\xf9r\x94\xb9/|\"\tY\xdf\xc9\xc2N97i\xd8\n\xc8\xd7nR\xae3\x86GwVF\x1ajhA2Q:\x9eH\x19\b\xa1\x0f\x99i\xf1f$c\xbb|\x9e\xd1-FCk\az\x87?{`\xfc\t\xf41\fߏ\x05" + - "ú\x1e\x9d\x8c\xd9Q\xe1Dۋ\xbd]\xaaw$;\x86\xa8@\x96\xa9\xf1Ŝ\x9f\x16\x8d\x19\xdfT\xec\x8ea\x15yͪЏ\xebf\xf5\x14 \xcc\xc8-\xcd\f\x97h\xed\xa6\x9cNEҶ\xbd\U000846ec3zkAX-\xe1e\x90\xf9\xfa\x9a(](M\xfb9R\x9b\xeen\xd3\xe06V\v\xeb\x1c\xf8Y\x1e\xc3\t\x8d\xc4" + - "y.\xfet\x9e\x8fj׀\x83\xe3,\x16n\b:4<\x02*\xa1\x963c\xf9W\x1b\x15\x16\x04\xf6\x15\xddj\xa6q|\xe2{R\xd1\xcfU6\xb9I\xa7\xeajխ[\x14\x98y7<\x8e\xbd\x19\xa9\xb0\xba\x96їی\xe4_\xa3\x95\x92[\\\x13\xfb\x8a\xe5r\xe4\ai\x94]r\xd2\xca^v\xb4-V\x92A\xeb\fU\xcb\xf7" + - "]\x93l^\xf2-\xf3\x81;\x98\x0f\xa2\xd8\xed\xf0څ\xc1\xefDTY\x18\x96\x9f\xedY\x9a\xd2|\x86-\xcd\xf1\x90c\xa8R\"H\xfdn\xa0\x05Rb\xb8\x96\xce$ /\xa3-EڇZ\x8b\x9b8rE\xfd\xca\xc9\x1d\xe2\x11\x94\xe9\x82\fT\x85Ig\xd8\x1b\x03g\xc3n\xb8B\x96\x13\xf2Whޚ~G+\xe1@\xf2\a\xa8" + - "\x8a{\x0e\xea\xe2\xf0\"\x13o\x14\xe9\x1bc\x1d\x1a\u05cdK/\xcc\xc90\xd6\xdbx5\xe7G\xe4\xbbK\u0601\xbb\\\xf7f\u05fe\x18o,\x83\x05)\xa7'\x8c\xb6\xa7\xb8pK\xda\xe38\x8f\xae\xc3T]\xb1\xdd\x1eъ\vZ.n+\xb8^I \x04\x8b[\xd5CuW\x91\x93\x1c\xfdg\x1fk\x0fv\x03R\x05\xaaL\xbe\xb6*\xdd" + - "\xf56\xb0y\x84\xed\x93\xf5\x00Q\xdb\xf1\x9c\xc8ˊ\xcd\xcf\b\x1c\xac\v\x12=W \x8d\n\u007f#\xa5}\v\xda\xcdy\\V\xf4\x0e\x1fwn>\x83z6\x9d\v\x15\x9b\xb3+\xe0s\xdeգ\x92\x83\xc79\xc6\x10\xf7\t\xd5ٹ&\x1bU\x81\xad\xdcD\xf6 \xcdc\x11\x9fC\xcan\xb5\xeb\xe2\x99\xedH\x89ȕ\v\xc2rw`6" + - "\x06\x10r%\x82\x9dF\xed\x1f$!\xb4%\t\xf2\x9dU\x8a\x8b\xeb\xd2),\x87\xd5\xeab\xc3\xdaT\xe3I\xf9\xab5\xa8\xf4\xee\xb7ccJ\xbb}[\x82^\x1c\xdf4\xbd\xdb[\xb8\xf4CpY\x0fzj\xc8\xd3\xf7@\xb9\xb7\xad\"m\x9b\xbb\xfe\x96\xae\xbd\xe1\xa9\xcc0k\xd5\xdc\xe9\xc5\v\xb0\xfe\x8c3\x9a\xef\xb0\bW\xf0\xfa\x17\xd3P" + - "Z\x9b\x99A\x95\xdfR\x86Y\x8b\xe5\xc8>\"\xea\xf6/\x15\xc57Սz]\x9b\xf2\x8e\x96b?m\xa7Z\xe0\xed\x1a\xf3\x8c%t\xf2\xf2\xea\xf5/Sm\xc1\xd9~\xc4q\xecN+\xeb\xbeh\xb0\x91\xad#\xd7\xf4y\xf2Һgx\xf1E\xc0S\x84Q\x1c\x85b\x90z\xe0t\xd9\xf2\x83\x05\xb4#M\\\x1d\x06\xf3\xf7?\xb5\u07b5Q" + - "\xe9\x8f \xcfp`h\xa0\x15\xf6\x89\xe4)0\xc1\x1b\u007f\x1e\xeb\xc3\xff\xd7h\xbf\xbfnI\\\xd2\rͰ\xb0i\n\x9c\xe5\t5\xab\xd1\x16\xcd@4\x1d\xc9\xd4\xf3\xfam㦚\xcd\x0e\xfa\xd8r\x8c\x1cv\xc9\x04\x95\xff\x8f\x1f1\xa9q\xd3\xdda\xa8\u007f)\xd9\u007f\xdb\xc2C\x81\xb5ʪ\xf7\x03\x80Q\xe9`\x92\xf9\xf2\xd1bR\x13\xd1" + - ".\x1e\x9b&C\x9d\x9d\xf3\x8d䄨v\x82c\x8c\xe9̎\x98\xe3K\xc8\xfe\x1a\x02\xec)V3\xb7:3\x0eo\xb0\xa4\x8d\x88\x99{\xa5T\xd0\x04S\xeb\xf9\xa5\x1f\x91\x93\v\xe5$_\x1b\xa5\x93\x93\xddu\xb3e̽\xc7|\xee\x996\xfcI:e-%hƩ\x93\x90+O\xe0\xa2\xe6ںWЭ\x9bS4\xb5\xaf\x06\x86\xec" + - "*Q\xd0\xe4\xd4Ǚ3h\xd0*\xcc\x18Z\xfd\xac;\x9b֪>\xe6\x0f\xb6c\xe7\xf0\xbf:\x1e\x06\x17\xf0\n\x96K\xf8ٛ\xdb\x14i\xda|`\f\x11?\x8f?\xe2\x15\xb7\x9e\x1e\x8d\xf1\xbf\xf3AM\xde\tV]\x1d5\xad\x8f~B\xaa'\xa4C0\xba9\x15Gy\x18BO\xfb\xb2ٱ\xd5iAu\xf7{\xd3&\xfeP\x92\x1b" + - "h\x8bV\xef>\u007f\xfcp\xb3\xfe\xeb\xe6\xd7\xc0\xb7\xcd:\xcbx\xbc\xc6\xf2\xdf\xe0Y\x9b\xce\xe89\x8f\u007f\xfdF\x93\xa3\xa0\xea\xe1\x9f\u007f\xda\"K\xb9\xc0~\xfd\x16\xa2\b!4\x82\x19\xfe\xf7\x93\xf7\xf2bս\xf1\x99\x83p\xdb7\x1e\xbfg\x15\x17\xef\xa9H\xf6a\xb6\x95\xden\xa5\f\xe8A\tl\xa5,M\xe7Ɖ\xe1\xf5\xb8\x18\x03]" + - "7y\xe3\xe7\xf8\xb4\x8f\xd4\xce\xfd\xd6\xea\x0eB\x99\xa8\xca\xcaFڲ\xeaN\xa9\xd5\x1d\x11\xbbh\x92\x98Ϭ*Ӓ\xaf\x1b\xf9\xe4S\xceʒ\n\x95\uee38O\x15\x15X\xcf\x15\xcb\x05d\x04k\xafs\xf4\xa88)R\xaa\xd4#^\xf1\x84\x94\x14#\xb1.\x0e\a\xec\x9f\xf4\xa7Z\xdd\xcej1{\xaf\x80\xc3\x06\xfe\x06\x01Ǿ\x94" + - "\x9d\x8e6MT\xe4\x85J\x82\x81ɡ];\x82]\xc0k\x9d1\x10\xba\x85q\xb7\xdb\x1f\xc7\x18\x8c\x88\xa5\xfc\xac\u007f\xaa\x10\xec\x0e\xdd3o l\x17\x8b\xa2\xfc\x9d\x12^\xe4\xf5\x94\x1a^\x1cR\xc2\xf7o\xc0\u007f_[\x83\x8f\u07b3o4\x9d\xbczRzvN\xeb\u007f\x01\x00\x00\xff\xff\x195P\xe4\xc1\"\x00\x00", - }, - - "/share.html": { - local: "../ui/share.html", - size: 268, - compressed: "\x1f\x8b\b\x00\x00\tn\x88\x00\xffL\x90An\xc5 \fD\xf7=\x85Ū]D\x1c\xa0\x843T\xbd\x01\r\xfe\r\x91C\"l\xa2F(w/\x82V\xf9^\xd9\xd6\xcc\xf3\xc8f\x96\x95\xec\v\xd423:\xdf\xdb6J\x10B[\xa2[\xf1\x82\xd7\xe2sr\x12\xb6x\xc1\xcao0\xc0G\xda\x1e\x81B\xfc\x86O\xe4L\xc2Fw\xc7M" + - "\xe0)\x85]@\xce\x1dG%\xf8#zq\x87\xeb[e\xe1p\t\xf6F\xc1\x04#\x94\x85+\xfd\x1d\x8c\xee\x8a\x1bTB\x9c({\xe4\xab\a\xd5wR\xf3\xb5\xf9\xf3\xe9\xa4\x0f\aL\xe4\x98G\xf5\x8f\x1eR\xcb7<2\x91\xb2FWɟWws\xe5\xb5'\xfc\x06\x00\x00\xff\xff\xe3\xbf\xf7\xdd\f\x01\x00\x00", - }, - - "/": { - isDir: true, - }, -} diff --git a/_third_party/github.com/MiniProfiler/go/miniprofiler/templates.go b/_third_party/github.com/MiniProfiler/go/miniprofiler/templates.go deleted file mode 100644 index e309e3bf..00000000 --- a/_third_party/github.com/MiniProfiler/go/miniprofiler/templates.go +++ /dev/null @@ -1,26 +0,0 @@ -package miniprofiler - -import ( - "html/template" - "io/ioutil" - "strings" -) - -var includePartialHtmlTmpl = parseInclude("include", "/include.partial.html") -var shareHtmlTmpl = parseInclude("share", "/share.html") - -func parseInclude(name string, fname string) *template.Template { - f, err := webFS.Open(fname) - if err != nil { - panic(err) - } - t, err := ioutil.ReadAll(f) - if err != nil { - panic(err) - } - f.Close() - s := string(t) - s = strings.Replace(s, "{", "{{.", -1) - s = strings.Replace(s, "}", "}}", -1) - return template.Must(template.New(name).Parse(s)) -} diff --git a/_third_party/github.com/MiniProfiler/go/miniprofiler/types.go b/_third_party/github.com/MiniProfiler/go/miniprofiler/types.go deleted file mode 100644 index 9b475b36..00000000 --- a/_third_party/github.com/MiniProfiler/go/miniprofiler/types.go +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package miniprofiler - -import ( - "encoding/json" - "fmt" - "html/template" - "math/rand" - "net/http" - "runtime/debug" - "strings" - "sync" - "time" -) - -var rnd = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())}) - -type lockedSource struct { - lk sync.Mutex - src rand.Source -} - -func (r *lockedSource) Int63() (n int64) { - r.lk.Lock() - n = r.src.Int63() - r.lk.Unlock() - return -} - -func (r *lockedSource) Seed(seed int64) { - r.lk.Lock() - r.src.Seed(seed) - r.lk.Unlock() -} - -func newGuid() string { - return fmt.Sprintf("%016x", rnd.Int63()) -} - -type Profile struct { - Id string - Name string - start time.Time - Started int64 - MachineName string - Root *Timing - ClientTimings *ClientTimings - DurationMilliseconds float64 - CustomLinks map[string]string - - w http.ResponseWriter - r *http.Request -} - -type Timing struct { - Id string - Name string - DurationMilliseconds float64 - StartMilliseconds float64 - Children []*Timing - CustomTimings map[string][]*CustomTiming - - profile *Profile - sync.Mutex -} - -// NewProfile creates a new Profile with given name. -// For use only by miniprofiler extensions. -func NewProfile(w http.ResponseWriter, r *http.Request, name string) *Profile { - p := &Profile{ - w: w, - r: r, - } - - if Enable(r) { - p.Id = newGuid() - p.Name = name - p.CustomLinks = make(map[string]string) - p.start = time.Now() - p.MachineName = MachineName() - p.Root = &Timing{ - Id: newGuid(), - profile: p, - } - w.Header().Add("X-MiniProfiler-Ids", "[\""+p.Id+"\"]") - } - - return p -} - -// Finalize finalizes a Profile and Store()s it. -// For use only by miniprofiler extensions. -func (p *Profile) Finalize() { - if p.Root == nil { - return - } - - u := p.r.URL - if !u.IsAbs() { - u.Host = p.r.Host - if p.r.TLS == nil { - u.Scheme = "http" - } else { - u.Scheme = "https" - } - } - p.Root.Name = p.r.Method + " " + u.String() - - p.Started = p.start.Unix() * 1000 - p.DurationMilliseconds = Since(p.start) - p.Root.DurationMilliseconds = p.DurationMilliseconds - - Store(p.r, p) -} - -// ProfileFromJson returns a Profile from JSON data. -func ProfileFromJson(b []byte) *Profile { - p := Profile{} - json.Unmarshal(b, &p) - return &p -} - -// Json converts a profile to JSON. -func (p *Profile) Json() []byte { - b, _ := json.Marshal(p) - return b -} - -type Timer interface { - AddCustomTiming(callType, executeType string, start, end time.Time, command string) - Step(name string, f func(t Timer)) - StepCustomTiming(callType, executeType, command string, f func()) - AddCustomLink(name, URL string) - SetName(string) - Includes() template.HTML -} - -func (p *Profile) SetName(name string) { - if p.Root != nil { - p.Name = name - } -} - -func (T *Timing) SetName(name string) { - if T != nil { - T.profile.SetName(name) - } -} - -func (p *Profile) AddCustomLink(name, URL string) { - if p.CustomLinks != nil { - p.CustomLinks[name] = URL - } -} - -func (T *Timing) AddCustomLink(name, URL string) { - if T != nil { - T.profile.AddCustomLink(name, URL) - } -} - -func (p *Profile) AddCustomTiming(callType, executeType string, start, end time.Time, command string) { - if p.Root != nil { - p.Root.AddCustomTiming(callType, executeType, start, end, command) - } -} - -func (p *Profile) StepCustomTiming(callType, executeType, command string, f func()) { - if p.Root != nil { - p.Root.StepCustomTiming(callType, executeType, command, f) - } else { - f() - } -} - -func (p *Profile) Step(name string, f func(t Timer)) { - if p.Root != nil { - p.Root.Step(name, f) - } else { - f(p) - } -} - -func (T *Timing) Includes() template.HTML { - if T != nil { - return T.profile.Includes() - } - return "" -} - -func (T *Timing) Step(name string, f func(t Timer)) { - t := &Timing{ - Id: newGuid(), - Name: name, - StartMilliseconds: Since(T.profile.start), - profile: T.profile, - } - T.addChild(t) - f(t) - t.DurationMilliseconds = Since(t.profile.start) - t.StartMilliseconds -} - -func (T *Timing) addChild(t *Timing) { - T.Lock() - T.Children = append(T.Children, t) - T.Unlock() -} - -func (t *Timing) AddCustomTiming(callType, executeType string, start, end time.Time, command string) { - if t == nil { - return - } - t.Lock() - if t.CustomTimings == nil { - t.CustomTimings = make(map[string][]*CustomTiming) - } - s := &CustomTiming{ - Id: newGuid(), - StartMilliseconds: start.Sub(t.profile.start).Seconds() * 1000, - DurationMilliseconds: end.Sub(start).Seconds() * 1000, - CommandString: command, - StackTraceSnippet: getStackSnippet(), - ExecuteType: executeType, - } - t.CustomTimings[callType] = append(t.CustomTimings[callType], s) - t.Unlock() -} - -func (t *Timing) StepCustomTiming(callType, executeType, command string, f func()) { - start := time.Now() - f() - end := time.Now() - t.AddCustomTiming(callType, executeType, start, end, command) -} - -func getStackSnippet() string { - stack := debug.Stack() - lines := strings.Split(string(stack), "\n") - var snippet []string - for i := 0; i < len(lines); i++ { - idx := strings.LastIndex(lines[i], " ") - if idx == -1 { - break - } - - if i+1 < len(lines) && strings.HasPrefix(lines[i+1], "\t") { - i++ - snip := strings.TrimSpace(lines[i]) - snip = strings.Split(snip, ":")[0] - sp := strings.Split(snip, ".") - snip = sp[len(sp)-1] - if strings.Contains(snip, "miniprofiler") || strings.HasPrefix(snip, "_func_") || snip == "ServeHTTP" || snip == "ProfileRequest" { - continue - } - snippet = append(snippet, snip) - } - } - if len(snippet) > 2 { - snippet = snippet[2:] - } - return strings.Join(snippet, " ") -} - -type CustomTiming struct { - Id string - ExecuteType string - CommandString string - StackTraceSnippet string - StartMilliseconds float64 - DurationMilliseconds float64 - FirstFetchDurationMilliseconds float64 -} - -type ClientTimings struct { - RedirectCount int64 - Timings []*ClientTiming -} - -func (c *ClientTimings) Len() int { return len(c.Timings) } -func (c *ClientTimings) Less(i, j int) bool { return c.Timings[i].Start < c.Timings[j].Start } -func (c *ClientTimings) Swap(i, j int) { c.Timings[i], c.Timings[j] = c.Timings[j], c.Timings[i] } - -type ClientTiming struct { - Name string - Start int64 - Duration int64 -} diff --git a/_third_party/github.com/MiniProfiler/go/miniprofiler_gae/doc.go b/_third_party/github.com/MiniProfiler/go/miniprofiler_gae/doc.go deleted file mode 100644 index 21e7fa2a..00000000 --- a/_third_party/github.com/MiniProfiler/go/miniprofiler_gae/doc.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -Package miniprofiler_gae is a simple but effective mini-profiler for app engine. - -miniprofiler_gae hooks into the appstats package, and all app engine RPCs are automatically profiled. -An appstats link is listed in each Profile. - -To use this package, change your HTTP handler functions to use this signature: - - func(mpg.Context, http.ResponseWriter, *http.Request) - -Register them in the usual way, wrapping them with NewHandler. - -Send output of c.Includes() to your HTML (it is empty if Enable returns -false). - -By default, miniprofiler_gae is enabled on dev for all and on prod for admins. -Override miniprofiler.Enable to change. - -Step - -Unlike base miniprofiler, the Step function returns a profiled context: - - c.Step("something", func(c mpg.Context) { - // c is valid appengine.Context and miniprofiler.Timer: - // datastore.Get(c, key, entity) - // c.Step("another", func(c mpg.Context) { ... }) - }) - -See the miniprofiler package docs about further usage: http://godoc.org/github.com/MiniProfiler/go/miniprofiler. -*/ -package miniprofiler_gae diff --git a/_third_party/github.com/MiniProfiler/go/miniprofiler_gae/miniprofiler_gae.go b/_third_party/github.com/MiniProfiler/go/miniprofiler_gae/miniprofiler_gae.go deleted file mode 100644 index 8aad19ac..00000000 --- a/_third_party/github.com/MiniProfiler/go/miniprofiler_gae/miniprofiler_gae.go +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package miniprofiler_gae - -import ( - "fmt" - "net/http" - - "appengine" - "appengine/memcache" - "appengine/user" - "appengine_internal" - "github.com/mjibson/goread/_third_party/github.com/MiniProfiler/go/miniprofiler" - "github.com/mjibson/goread/_third_party/github.com/mjibson/appstats" -) - -func init() { - miniprofiler.Enable = EnableIfAdminOrDev - miniprofiler.Get = GetMemcache - miniprofiler.Store = StoreMemcache - miniprofiler.MachineName = Instance -} - -// EnableIfAdminOrDev returns true if this is the dev server or the current -// user is an admin. This is the default for miniprofiler.Enable. -func EnableIfAdminOrDev(r *http.Request) bool { - if appengine.IsDevAppServer() { - return true - } - c := appengine.NewContext(r) - if u := user.Current(c); u != nil { - return u.Admin - } - return false -} - -// Instance returns the app engine instance id, or the hostname on dev. -// This is the default for miniprofiler.MachineName. -func Instance() string { - if i := appengine.InstanceID(); i != "" && !appengine.IsDevAppServer() { - return i[len(i)-8:] - } - return miniprofiler.Hostname() -} - -// StoreMemcache stores the Profile in memcache. This is the default for -// miniprofiler.Store. -func StoreMemcache(r *http.Request, p *miniprofiler.Profile) { - item := &memcache.Item{ - Key: mp_key(string(p.Id)), - Value: p.Json(), - } - c := appengine.NewContext(r) - memcache.Set(c, item) -} - -// GetMemcache gets the Profile from memcache. This is the default for -// miniprofiler.Get. -func GetMemcache(r *http.Request, id string) *miniprofiler.Profile { - c := appengine.NewContext(r) - item, err := memcache.Get(c, mp_key(id)) - if err != nil { - return nil - } - return miniprofiler.ProfileFromJson(item.Value) -} - -type Context struct { - appstats.Context - miniprofiler.Timer -} - -func (c Context) Call(service, method string, in, out appengine_internal.ProtoMessage, opts *appengine_internal.CallOptions) (err error) { - if c.Timer != nil && service != "__go__" { - c.StepCustomTiming(service, method, fmt.Sprintf("%v\n\n%v", method, in.String()), func() { - err = c.Context.Call(service, method, in, out, opts) - }) - } else { - err = c.Context.Call(service, method, in, out, opts) - } - return -} - -func (c Context) Step(name string, f func(Context)) { - if c.Timer != nil { - c.Timer.Step(name, func(t miniprofiler.Timer) { - f(Context{ - Context: c.Context, - Timer: t, - }) - }) - } else { - f(c) - } -} - -// NewHandler returns a profiled, appstats-aware appengine.Context. -func NewHandler(f func(Context, http.ResponseWriter, *http.Request)) http.Handler { - return appstats.NewHandler(func(c appengine.Context, w http.ResponseWriter, r *http.Request) { - h := miniprofiler.NewHandler(func(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) { - pc := Context{ - Context: c.(appstats.Context), - Timer: t, - } - t.SetName(miniprofiler.FuncName(f)) - f(pc, w, r) - t.AddCustomLink("appstats", pc.URL()) - }) - h.ServeHTTP(w, r) - }) -} - -func mp_key(id string) string { - return fmt.Sprintf("mini-profiler-results:%s", id) -} diff --git a/_third_party/github.com/golang/protobuf/proto/Makefile b/_third_party/github.com/golang/protobuf/proto/Makefile deleted file mode 100644 index f1f06564..00000000 --- a/_third_party/github.com/golang/protobuf/proto/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# 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. - -install: - go install - -test: install generate-test-pbs - go test - - -generate-test-pbs: - make install - make -C testdata - protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto - make diff --git a/_third_party/github.com/golang/protobuf/proto/all_test.go b/_third_party/github.com/golang/protobuf/proto/all_test.go deleted file mode 100644 index 8f637f06..00000000 --- a/_third_party/github.com/golang/protobuf/proto/all_test.go +++ /dev/null @@ -1,2083 +0,0 @@ -// 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_test - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "math" - "math/rand" - "reflect" - "runtime/debug" - "strings" - "testing" - "time" - - . "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" - . "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/testdata" -) - -var globalO *Buffer - -func old() *Buffer { - if globalO == nil { - globalO = NewBuffer(nil) - } - globalO.Reset() - return globalO -} - -func equalbytes(b1, b2 []byte, t *testing.T) { - if len(b1) != len(b2) { - t.Errorf("wrong lengths: 2*%d != %d", len(b1), len(b2)) - return - } - for i := 0; i < len(b1); i++ { - if b1[i] != b2[i] { - t.Errorf("bad byte[%d]:%x %x: %s %s", i, b1[i], b2[i], b1, b2) - } - } -} - -func initGoTestField() *GoTestField { - f := new(GoTestField) - f.Label = String("label") - f.Type = String("type") - return f -} - -// These are all structurally equivalent but the tag numbers differ. -// (It's remarkable that required, optional, and repeated all have -// 8 letters.) -func initGoTest_RequiredGroup() *GoTest_RequiredGroup { - return &GoTest_RequiredGroup{ - RequiredField: String("required"), - } -} - -func initGoTest_OptionalGroup() *GoTest_OptionalGroup { - return &GoTest_OptionalGroup{ - RequiredField: String("optional"), - } -} - -func initGoTest_RepeatedGroup() *GoTest_RepeatedGroup { - return &GoTest_RepeatedGroup{ - RequiredField: String("repeated"), - } -} - -func initGoTest(setdefaults bool) *GoTest { - pb := new(GoTest) - if setdefaults { - pb.F_BoolDefaulted = Bool(Default_GoTest_F_BoolDefaulted) - pb.F_Int32Defaulted = Int32(Default_GoTest_F_Int32Defaulted) - pb.F_Int64Defaulted = Int64(Default_GoTest_F_Int64Defaulted) - pb.F_Fixed32Defaulted = Uint32(Default_GoTest_F_Fixed32Defaulted) - pb.F_Fixed64Defaulted = Uint64(Default_GoTest_F_Fixed64Defaulted) - pb.F_Uint32Defaulted = Uint32(Default_GoTest_F_Uint32Defaulted) - pb.F_Uint64Defaulted = Uint64(Default_GoTest_F_Uint64Defaulted) - pb.F_FloatDefaulted = Float32(Default_GoTest_F_FloatDefaulted) - pb.F_DoubleDefaulted = Float64(Default_GoTest_F_DoubleDefaulted) - pb.F_StringDefaulted = String(Default_GoTest_F_StringDefaulted) - pb.F_BytesDefaulted = Default_GoTest_F_BytesDefaulted - pb.F_Sint32Defaulted = Int32(Default_GoTest_F_Sint32Defaulted) - pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted) - } - - pb.Kind = GoTest_TIME.Enum() - pb.RequiredField = initGoTestField() - pb.F_BoolRequired = Bool(true) - pb.F_Int32Required = Int32(3) - pb.F_Int64Required = Int64(6) - pb.F_Fixed32Required = Uint32(32) - pb.F_Fixed64Required = Uint64(64) - pb.F_Uint32Required = Uint32(3232) - pb.F_Uint64Required = Uint64(6464) - pb.F_FloatRequired = Float32(3232) - pb.F_DoubleRequired = Float64(6464) - pb.F_StringRequired = String("string") - pb.F_BytesRequired = []byte("bytes") - pb.F_Sint32Required = Int32(-32) - pb.F_Sint64Required = Int64(-64) - pb.Requiredgroup = initGoTest_RequiredGroup() - - return pb -} - -func fail(msg string, b *bytes.Buffer, s string, t *testing.T) { - data := b.Bytes() - ld := len(data) - ls := len(s) / 2 - - fmt.Printf("fail %s ld=%d ls=%d\n", msg, ld, ls) - - // find the interesting spot - n - n := ls - if ld < ls { - n = ld - } - j := 0 - for i := 0; i < n; i++ { - bs := hex(s[j])*16 + hex(s[j+1]) - j += 2 - if data[i] == bs { - continue - } - n = i - break - } - l := n - 10 - if l < 0 { - l = 0 - } - h := n + 10 - - // find the interesting spot - n - fmt.Printf("is[%d]:", l) - for i := l; i < h; i++ { - if i >= ld { - fmt.Printf(" --") - continue - } - fmt.Printf(" %.2x", data[i]) - } - fmt.Printf("\n") - - fmt.Printf("sb[%d]:", l) - for i := l; i < h; i++ { - if i >= ls { - fmt.Printf(" --") - continue - } - bs := hex(s[j])*16 + hex(s[j+1]) - j += 2 - fmt.Printf(" %.2x", bs) - } - fmt.Printf("\n") - - t.Fail() - - // t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes()) - // Print the output in a partially-decoded format; can - // be helpful when updating the test. It produces the output - // that is pasted, with minor edits, into the argument to verify(). - // data := b.Bytes() - // nesting := 0 - // for b.Len() > 0 { - // start := len(data) - b.Len() - // var u uint64 - // u, err := DecodeVarint(b) - // if err != nil { - // fmt.Printf("decode error on varint:", err) - // return - // } - // wire := u & 0x7 - // tag := u >> 3 - // switch wire { - // case WireVarint: - // v, err := DecodeVarint(b) - // if err != nil { - // fmt.Printf("decode error on varint:", err) - // return - // } - // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n", - // data[start:len(data)-b.Len()], tag, wire, v) - // case WireFixed32: - // v, err := DecodeFixed32(b) - // if err != nil { - // fmt.Printf("decode error on fixed32:", err) - // return - // } - // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n", - // data[start:len(data)-b.Len()], tag, wire, v) - // case WireFixed64: - // v, err := DecodeFixed64(b) - // if err != nil { - // fmt.Printf("decode error on fixed64:", err) - // return - // } - // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n", - // data[start:len(data)-b.Len()], tag, wire, v) - // case WireBytes: - // nb, err := DecodeVarint(b) - // if err != nil { - // fmt.Printf("decode error on bytes:", err) - // return - // } - // after_tag := len(data) - b.Len() - // str := make([]byte, nb) - // _, err = b.Read(str) - // if err != nil { - // fmt.Printf("decode error on bytes:", err) - // return - // } - // fmt.Printf("\t\t\"%x\" \"%x\" // field %d, encoding %d (FIELD)\n", - // data[start:after_tag], str, tag, wire) - // case WireStartGroup: - // nesting++ - // fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n", - // data[start:len(data)-b.Len()], tag, nesting) - // case WireEndGroup: - // fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n", - // data[start:len(data)-b.Len()], tag, nesting) - // nesting-- - // default: - // fmt.Printf("unrecognized wire type %d\n", wire) - // return - // } - // } -} - -func hex(c uint8) uint8 { - if '0' <= c && c <= '9' { - return c - '0' - } - if 'a' <= c && c <= 'f' { - return 10 + c - 'a' - } - if 'A' <= c && c <= 'F' { - return 10 + c - 'A' - } - return 0 -} - -func equal(b []byte, s string, t *testing.T) bool { - if 2*len(b) != len(s) { - // fail(fmt.Sprintf("wrong lengths: 2*%d != %d", len(b), len(s)), b, s, t) - fmt.Printf("wrong lengths: 2*%d != %d\n", len(b), len(s)) - return false - } - for i, j := 0, 0; i < len(b); i, j = i+1, j+2 { - x := hex(s[j])*16 + hex(s[j+1]) - if b[i] != x { - // fail(fmt.Sprintf("bad byte[%d]:%x %x", i, b[i], x), b, s, t) - fmt.Printf("bad byte[%d]:%x %x", i, b[i], x) - return false - } - } - return true -} - -func overify(t *testing.T, pb *GoTest, expected string) { - o := old() - err := o.Marshal(pb) - if err != nil { - fmt.Printf("overify marshal-1 err = %v", err) - o.DebugPrint("", o.Bytes()) - t.Fatalf("expected = %s", expected) - } - if !equal(o.Bytes(), expected, t) { - o.DebugPrint("overify neq 1", o.Bytes()) - t.Fatalf("expected = %s", expected) - } - - // Now test Unmarshal by recreating the original buffer. - pbd := new(GoTest) - err = o.Unmarshal(pbd) - if err != nil { - t.Fatalf("overify unmarshal err = %v", err) - o.DebugPrint("", o.Bytes()) - t.Fatalf("string = %s", expected) - } - o.Reset() - err = o.Marshal(pbd) - if err != nil { - t.Errorf("overify marshal-2 err = %v", err) - o.DebugPrint("", o.Bytes()) - t.Fatalf("string = %s", expected) - } - if !equal(o.Bytes(), expected, t) { - o.DebugPrint("overify neq 2", o.Bytes()) - t.Fatalf("string = %s", expected) - } -} - -// Simple tests for numeric encode/decode primitives (varint, etc.) -func TestNumericPrimitives(t *testing.T) { - for i := uint64(0); i < 1e6; i += 111 { - o := old() - if o.EncodeVarint(i) != nil { - t.Error("EncodeVarint") - break - } - x, e := o.DecodeVarint() - if e != nil { - t.Fatal("DecodeVarint") - } - if x != i { - t.Fatal("varint decode fail:", i, x) - } - - o = old() - if o.EncodeFixed32(i) != nil { - t.Fatal("encFixed32") - } - x, e = o.DecodeFixed32() - if e != nil { - t.Fatal("decFixed32") - } - if x != i { - t.Fatal("fixed32 decode fail:", i, x) - } - - o = old() - if o.EncodeFixed64(i*1234567) != nil { - t.Error("encFixed64") - break - } - x, e = o.DecodeFixed64() - if e != nil { - t.Error("decFixed64") - break - } - if x != i*1234567 { - t.Error("fixed64 decode fail:", i*1234567, x) - break - } - - o = old() - i32 := int32(i - 12345) - if o.EncodeZigzag32(uint64(i32)) != nil { - t.Fatal("EncodeZigzag32") - } - x, e = o.DecodeZigzag32() - if e != nil { - t.Fatal("DecodeZigzag32") - } - if x != uint64(uint32(i32)) { - t.Fatal("zigzag32 decode fail:", i32, x) - } - - o = old() - i64 := int64(i - 12345) - if o.EncodeZigzag64(uint64(i64)) != nil { - t.Fatal("EncodeZigzag64") - } - x, e = o.DecodeZigzag64() - if e != nil { - t.Fatal("DecodeZigzag64") - } - if x != uint64(i64) { - t.Fatal("zigzag64 decode fail:", i64, x) - } - } -} - -// fakeMarshaler is a simple struct implementing Marshaler and Message interfaces. -type fakeMarshaler struct { - b []byte - err error -} - -func (f fakeMarshaler) Marshal() ([]byte, error) { - return f.b, f.err -} - -func (f fakeMarshaler) String() string { - return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err) -} - -func (f fakeMarshaler) ProtoMessage() {} - -func (f fakeMarshaler) Reset() {} - -// Simple tests for proto messages that implement the Marshaler interface. -func TestMarshalerEncoding(t *testing.T) { - tests := []struct { - name string - m Message - want []byte - wantErr error - }{ - { - name: "Marshaler that fails", - m: fakeMarshaler{ - err: errors.New("some marshal err"), - b: []byte{5, 6, 7}, - }, - // Since there's an error, nothing should be written to buffer. - want: nil, - wantErr: errors.New("some marshal err"), - }, - { - name: "Marshaler that succeeds", - m: fakeMarshaler{ - b: []byte{0, 1, 2, 3, 4, 127, 255}, - }, - want: []byte{0, 1, 2, 3, 4, 127, 255}, - wantErr: nil, - }, - } - for _, test := range tests { - b := NewBuffer(nil) - err := b.Marshal(test.m) - if !reflect.DeepEqual(test.wantErr, err) { - t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr) - } - if !reflect.DeepEqual(test.want, b.Bytes()) { - t.Errorf("%s: got bytes %v wanted %v", test.name, b.Bytes(), test.want) - } - } -} - -// Simple tests for bytes -func TestBytesPrimitives(t *testing.T) { - o := old() - bytes := []byte{'n', 'o', 'w', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 't', 'i', 'm', 'e'} - if o.EncodeRawBytes(bytes) != nil { - t.Error("EncodeRawBytes") - } - decb, e := o.DecodeRawBytes(false) - if e != nil { - t.Error("DecodeRawBytes") - } - equalbytes(bytes, decb, t) -} - -// Simple tests for strings -func TestStringPrimitives(t *testing.T) { - o := old() - s := "now is the time" - if o.EncodeStringBytes(s) != nil { - t.Error("enc_string") - } - decs, e := o.DecodeStringBytes() - if e != nil { - t.Error("dec_string") - } - if s != decs { - t.Error("string encode/decode fail:", s, decs) - } -} - -// Do we catch the "required bit not set" case? -func TestRequiredBit(t *testing.T) { - o := old() - pb := new(GoTest) - err := o.Marshal(pb) - if err == nil { - t.Error("did not catch missing required fields") - } else if strings.Index(err.Error(), "Kind") < 0 { - t.Error("wrong error type:", err) - } -} - -// Check that all fields are nil. -// Clearly silly, and a residue from a more interesting test with an earlier, -// different initialization property, but it once caught a compiler bug so -// it lives. -func checkInitialized(pb *GoTest, t *testing.T) { - if pb.F_BoolDefaulted != nil { - t.Error("New or Reset did not set boolean:", *pb.F_BoolDefaulted) - } - if pb.F_Int32Defaulted != nil { - t.Error("New or Reset did not set int32:", *pb.F_Int32Defaulted) - } - if pb.F_Int64Defaulted != nil { - t.Error("New or Reset did not set int64:", *pb.F_Int64Defaulted) - } - if pb.F_Fixed32Defaulted != nil { - t.Error("New or Reset did not set fixed32:", *pb.F_Fixed32Defaulted) - } - if pb.F_Fixed64Defaulted != nil { - t.Error("New or Reset did not set fixed64:", *pb.F_Fixed64Defaulted) - } - if pb.F_Uint32Defaulted != nil { - t.Error("New or Reset did not set uint32:", *pb.F_Uint32Defaulted) - } - if pb.F_Uint64Defaulted != nil { - t.Error("New or Reset did not set uint64:", *pb.F_Uint64Defaulted) - } - if pb.F_FloatDefaulted != nil { - t.Error("New or Reset did not set float:", *pb.F_FloatDefaulted) - } - if pb.F_DoubleDefaulted != nil { - t.Error("New or Reset did not set double:", *pb.F_DoubleDefaulted) - } - if pb.F_StringDefaulted != nil { - t.Error("New or Reset did not set string:", *pb.F_StringDefaulted) - } - if pb.F_BytesDefaulted != nil { - t.Error("New or Reset did not set bytes:", string(pb.F_BytesDefaulted)) - } - if pb.F_Sint32Defaulted != nil { - t.Error("New or Reset did not set int32:", *pb.F_Sint32Defaulted) - } - if pb.F_Sint64Defaulted != nil { - t.Error("New or Reset did not set int64:", *pb.F_Sint64Defaulted) - } -} - -// Does Reset() reset? -func TestReset(t *testing.T) { - pb := initGoTest(true) - // muck with some values - pb.F_BoolDefaulted = Bool(false) - pb.F_Int32Defaulted = Int32(237) - pb.F_Int64Defaulted = Int64(12346) - pb.F_Fixed32Defaulted = Uint32(32000) - pb.F_Fixed64Defaulted = Uint64(666) - pb.F_Uint32Defaulted = Uint32(323232) - pb.F_Uint64Defaulted = nil - pb.F_FloatDefaulted = nil - pb.F_DoubleDefaulted = Float64(0) - pb.F_StringDefaulted = String("gotcha") - pb.F_BytesDefaulted = []byte("asdfasdf") - pb.F_Sint32Defaulted = Int32(123) - pb.F_Sint64Defaulted = Int64(789) - pb.Reset() - checkInitialized(pb, t) -} - -// All required fields set, no defaults provided. -func TestEncodeDecode1(t *testing.T) { - pb := initGoTest(false) - overify(t, pb, - "0807"+ // field 1, encoding 0, value 7 - "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) - "5001"+ // field 10, encoding 0, value 1 - "5803"+ // field 11, encoding 0, value 3 - "6006"+ // field 12, encoding 0, value 6 - "6d20000000"+ // field 13, encoding 5, value 0x20 - "714000000000000000"+ // field 14, encoding 1, value 0x40 - "78a019"+ // field 15, encoding 0, value 0xca0 = 3232 - "8001c032"+ // field 16, encoding 0, value 0x1940 = 6464 - "8d0100004a45"+ // field 17, encoding 5, value 3232.0 - "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 - "9a0106"+"737472696e67"+ // field 19, encoding 2, string "string" - "b304"+ // field 70, encoding 3, start group - "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" - "b404"+ // field 70, encoding 4, end group - "aa0605"+"6279746573"+ // field 101, encoding 2, string "bytes" - "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 - "b8067f") // field 103, encoding 0, 0x7f zigzag64 -} - -// All required fields set, defaults provided. -func TestEncodeDecode2(t *testing.T) { - pb := initGoTest(true) - overify(t, pb, - "0807"+ // field 1, encoding 0, value 7 - "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) - "5001"+ // field 10, encoding 0, value 1 - "5803"+ // field 11, encoding 0, value 3 - "6006"+ // field 12, encoding 0, value 6 - "6d20000000"+ // field 13, encoding 5, value 32 - "714000000000000000"+ // field 14, encoding 1, value 64 - "78a019"+ // field 15, encoding 0, value 3232 - "8001c032"+ // field 16, encoding 0, value 6464 - "8d0100004a45"+ // field 17, encoding 5, value 3232.0 - "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 - "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" - "c00201"+ // field 40, encoding 0, value 1 - "c80220"+ // field 41, encoding 0, value 32 - "d00240"+ // field 42, encoding 0, value 64 - "dd0240010000"+ // field 43, encoding 5, value 320 - "e1028002000000000000"+ // field 44, encoding 1, value 640 - "e8028019"+ // field 45, encoding 0, value 3200 - "f0028032"+ // field 46, encoding 0, value 6400 - "fd02e0659948"+ // field 47, encoding 5, value 314159.0 - "81030000000050971041"+ // field 48, encoding 1, value 271828.0 - "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n" - "b304"+ // start group field 70 level 1 - "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" - "b404"+ // end group field 70 level 1 - "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" - "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 - "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 - "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose" - "90193f"+ // field 402, encoding 0, value 63 - "98197f") // field 403, encoding 0, value 127 - -} - -// All default fields set to their default value by hand -func TestEncodeDecode3(t *testing.T) { - pb := initGoTest(false) - pb.F_BoolDefaulted = Bool(true) - pb.F_Int32Defaulted = Int32(32) - pb.F_Int64Defaulted = Int64(64) - pb.F_Fixed32Defaulted = Uint32(320) - pb.F_Fixed64Defaulted = Uint64(640) - pb.F_Uint32Defaulted = Uint32(3200) - pb.F_Uint64Defaulted = Uint64(6400) - pb.F_FloatDefaulted = Float32(314159) - pb.F_DoubleDefaulted = Float64(271828) - pb.F_StringDefaulted = String("hello, \"world!\"\n") - pb.F_BytesDefaulted = []byte("Bignose") - pb.F_Sint32Defaulted = Int32(-32) - pb.F_Sint64Defaulted = Int64(-64) - - overify(t, pb, - "0807"+ // field 1, encoding 0, value 7 - "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) - "5001"+ // field 10, encoding 0, value 1 - "5803"+ // field 11, encoding 0, value 3 - "6006"+ // field 12, encoding 0, value 6 - "6d20000000"+ // field 13, encoding 5, value 32 - "714000000000000000"+ // field 14, encoding 1, value 64 - "78a019"+ // field 15, encoding 0, value 3232 - "8001c032"+ // field 16, encoding 0, value 6464 - "8d0100004a45"+ // field 17, encoding 5, value 3232.0 - "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 - "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" - "c00201"+ // field 40, encoding 0, value 1 - "c80220"+ // field 41, encoding 0, value 32 - "d00240"+ // field 42, encoding 0, value 64 - "dd0240010000"+ // field 43, encoding 5, value 320 - "e1028002000000000000"+ // field 44, encoding 1, value 640 - "e8028019"+ // field 45, encoding 0, value 3200 - "f0028032"+ // field 46, encoding 0, value 6400 - "fd02e0659948"+ // field 47, encoding 5, value 314159.0 - "81030000000050971041"+ // field 48, encoding 1, value 271828.0 - "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n" - "b304"+ // start group field 70 level 1 - "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" - "b404"+ // end group field 70 level 1 - "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" - "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 - "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 - "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose" - "90193f"+ // field 402, encoding 0, value 63 - "98197f") // field 403, encoding 0, value 127 - -} - -// All required fields set, defaults provided, all non-defaulted optional fields have values. -func TestEncodeDecode4(t *testing.T) { - pb := initGoTest(true) - pb.Table = String("hello") - pb.Param = Int32(7) - pb.OptionalField = initGoTestField() - pb.F_BoolOptional = Bool(true) - pb.F_Int32Optional = Int32(32) - pb.F_Int64Optional = Int64(64) - pb.F_Fixed32Optional = Uint32(3232) - pb.F_Fixed64Optional = Uint64(6464) - pb.F_Uint32Optional = Uint32(323232) - pb.F_Uint64Optional = Uint64(646464) - pb.F_FloatOptional = Float32(32.) - pb.F_DoubleOptional = Float64(64.) - pb.F_StringOptional = String("hello") - pb.F_BytesOptional = []byte("Bignose") - pb.F_Sint32Optional = Int32(-32) - pb.F_Sint64Optional = Int64(-64) - pb.Optionalgroup = initGoTest_OptionalGroup() - - overify(t, pb, - "0807"+ // field 1, encoding 0, value 7 - "1205"+"68656c6c6f"+ // field 2, encoding 2, string "hello" - "1807"+ // field 3, encoding 0, value 7 - "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) - "320d"+"0a056c6162656c120474797065"+ // field 6, encoding 2 (GoTestField) - "5001"+ // field 10, encoding 0, value 1 - "5803"+ // field 11, encoding 0, value 3 - "6006"+ // field 12, encoding 0, value 6 - "6d20000000"+ // field 13, encoding 5, value 32 - "714000000000000000"+ // field 14, encoding 1, value 64 - "78a019"+ // field 15, encoding 0, value 3232 - "8001c032"+ // field 16, encoding 0, value 6464 - "8d0100004a45"+ // field 17, encoding 5, value 3232.0 - "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 - "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" - "f00101"+ // field 30, encoding 0, value 1 - "f80120"+ // field 31, encoding 0, value 32 - "800240"+ // field 32, encoding 0, value 64 - "8d02a00c0000"+ // field 33, encoding 5, value 3232 - "91024019000000000000"+ // field 34, encoding 1, value 6464 - "9802a0dd13"+ // field 35, encoding 0, value 323232 - "a002c0ba27"+ // field 36, encoding 0, value 646464 - "ad0200000042"+ // field 37, encoding 5, value 32.0 - "b1020000000000005040"+ // field 38, encoding 1, value 64.0 - "ba0205"+"68656c6c6f"+ // field 39, encoding 2, string "hello" - "c00201"+ // field 40, encoding 0, value 1 - "c80220"+ // field 41, encoding 0, value 32 - "d00240"+ // field 42, encoding 0, value 64 - "dd0240010000"+ // field 43, encoding 5, value 320 - "e1028002000000000000"+ // field 44, encoding 1, value 640 - "e8028019"+ // field 45, encoding 0, value 3200 - "f0028032"+ // field 46, encoding 0, value 6400 - "fd02e0659948"+ // field 47, encoding 5, value 314159.0 - "81030000000050971041"+ // field 48, encoding 1, value 271828.0 - "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n" - "b304"+ // start group field 70 level 1 - "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" - "b404"+ // end group field 70 level 1 - "d305"+ // start group field 90 level 1 - "da0508"+"6f7074696f6e616c"+ // field 91, encoding 2, string "optional" - "d405"+ // end group field 90 level 1 - "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" - "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 - "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 - "ea1207"+"4269676e6f7365"+ // field 301, encoding 2, string "Bignose" - "f0123f"+ // field 302, encoding 0, value 63 - "f8127f"+ // field 303, encoding 0, value 127 - "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose" - "90193f"+ // field 402, encoding 0, value 63 - "98197f") // field 403, encoding 0, value 127 - -} - -// All required fields set, defaults provided, all repeated fields given two values. -func TestEncodeDecode5(t *testing.T) { - pb := initGoTest(true) - pb.RepeatedField = []*GoTestField{initGoTestField(), initGoTestField()} - pb.F_BoolRepeated = []bool{false, true} - pb.F_Int32Repeated = []int32{32, 33} - pb.F_Int64Repeated = []int64{64, 65} - pb.F_Fixed32Repeated = []uint32{3232, 3333} - pb.F_Fixed64Repeated = []uint64{6464, 6565} - pb.F_Uint32Repeated = []uint32{323232, 333333} - pb.F_Uint64Repeated = []uint64{646464, 656565} - pb.F_FloatRepeated = []float32{32., 33.} - pb.F_DoubleRepeated = []float64{64., 65.} - pb.F_StringRepeated = []string{"hello", "sailor"} - pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")} - pb.F_Sint32Repeated = []int32{32, -32} - pb.F_Sint64Repeated = []int64{64, -64} - pb.Repeatedgroup = []*GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()} - - overify(t, pb, - "0807"+ // field 1, encoding 0, value 7 - "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) - "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField) - "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField) - "5001"+ // field 10, encoding 0, value 1 - "5803"+ // field 11, encoding 0, value 3 - "6006"+ // field 12, encoding 0, value 6 - "6d20000000"+ // field 13, encoding 5, value 32 - "714000000000000000"+ // field 14, encoding 1, value 64 - "78a019"+ // field 15, encoding 0, value 3232 - "8001c032"+ // field 16, encoding 0, value 6464 - "8d0100004a45"+ // field 17, encoding 5, value 3232.0 - "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 - "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" - "a00100"+ // field 20, encoding 0, value 0 - "a00101"+ // field 20, encoding 0, value 1 - "a80120"+ // field 21, encoding 0, value 32 - "a80121"+ // field 21, encoding 0, value 33 - "b00140"+ // field 22, encoding 0, value 64 - "b00141"+ // field 22, encoding 0, value 65 - "bd01a00c0000"+ // field 23, encoding 5, value 3232 - "bd01050d0000"+ // field 23, encoding 5, value 3333 - "c1014019000000000000"+ // field 24, encoding 1, value 6464 - "c101a519000000000000"+ // field 24, encoding 1, value 6565 - "c801a0dd13"+ // field 25, encoding 0, value 323232 - "c80195ac14"+ // field 25, encoding 0, value 333333 - "d001c0ba27"+ // field 26, encoding 0, value 646464 - "d001b58928"+ // field 26, encoding 0, value 656565 - "dd0100000042"+ // field 27, encoding 5, value 32.0 - "dd0100000442"+ // field 27, encoding 5, value 33.0 - "e1010000000000005040"+ // field 28, encoding 1, value 64.0 - "e1010000000000405040"+ // field 28, encoding 1, value 65.0 - "ea0105"+"68656c6c6f"+ // field 29, encoding 2, string "hello" - "ea0106"+"7361696c6f72"+ // field 29, encoding 2, string "sailor" - "c00201"+ // field 40, encoding 0, value 1 - "c80220"+ // field 41, encoding 0, value 32 - "d00240"+ // field 42, encoding 0, value 64 - "dd0240010000"+ // field 43, encoding 5, value 320 - "e1028002000000000000"+ // field 44, encoding 1, value 640 - "e8028019"+ // field 45, encoding 0, value 3200 - "f0028032"+ // field 46, encoding 0, value 6400 - "fd02e0659948"+ // field 47, encoding 5, value 314159.0 - "81030000000050971041"+ // field 48, encoding 1, value 271828.0 - "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n" - "b304"+ // start group field 70 level 1 - "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" - "b404"+ // end group field 70 level 1 - "8305"+ // start group field 80 level 1 - "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated" - "8405"+ // end group field 80 level 1 - "8305"+ // start group field 80 level 1 - "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated" - "8405"+ // end group field 80 level 1 - "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" - "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 - "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 - "ca0c03"+"626967"+ // field 201, encoding 2, string "big" - "ca0c04"+"6e6f7365"+ // field 201, encoding 2, string "nose" - "d00c40"+ // field 202, encoding 0, value 32 - "d00c3f"+ // field 202, encoding 0, value -32 - "d80c8001"+ // field 203, encoding 0, value 64 - "d80c7f"+ // field 203, encoding 0, value -64 - "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose" - "90193f"+ // field 402, encoding 0, value 63 - "98197f") // field 403, encoding 0, value 127 - -} - -// All required fields set, all packed repeated fields given two values. -func TestEncodeDecode6(t *testing.T) { - pb := initGoTest(false) - pb.F_BoolRepeatedPacked = []bool{false, true} - pb.F_Int32RepeatedPacked = []int32{32, 33} - pb.F_Int64RepeatedPacked = []int64{64, 65} - pb.F_Fixed32RepeatedPacked = []uint32{3232, 3333} - pb.F_Fixed64RepeatedPacked = []uint64{6464, 6565} - pb.F_Uint32RepeatedPacked = []uint32{323232, 333333} - pb.F_Uint64RepeatedPacked = []uint64{646464, 656565} - pb.F_FloatRepeatedPacked = []float32{32., 33.} - pb.F_DoubleRepeatedPacked = []float64{64., 65.} - pb.F_Sint32RepeatedPacked = []int32{32, -32} - pb.F_Sint64RepeatedPacked = []int64{64, -64} - - overify(t, pb, - "0807"+ // field 1, encoding 0, value 7 - "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) - "5001"+ // field 10, encoding 0, value 1 - "5803"+ // field 11, encoding 0, value 3 - "6006"+ // field 12, encoding 0, value 6 - "6d20000000"+ // field 13, encoding 5, value 32 - "714000000000000000"+ // field 14, encoding 1, value 64 - "78a019"+ // field 15, encoding 0, value 3232 - "8001c032"+ // field 16, encoding 0, value 6464 - "8d0100004a45"+ // field 17, encoding 5, value 3232.0 - "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 - "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" - "9203020001"+ // field 50, encoding 2, 2 bytes, value 0, value 1 - "9a03022021"+ // field 51, encoding 2, 2 bytes, value 32, value 33 - "a203024041"+ // field 52, encoding 2, 2 bytes, value 64, value 65 - "aa0308"+ // field 53, encoding 2, 8 bytes - "a00c0000050d0000"+ // value 3232, value 3333 - "b20310"+ // field 54, encoding 2, 16 bytes - "4019000000000000a519000000000000"+ // value 6464, value 6565 - "ba0306"+ // field 55, encoding 2, 6 bytes - "a0dd1395ac14"+ // value 323232, value 333333 - "c20306"+ // field 56, encoding 2, 6 bytes - "c0ba27b58928"+ // value 646464, value 656565 - "ca0308"+ // field 57, encoding 2, 8 bytes - "0000004200000442"+ // value 32.0, value 33.0 - "d20310"+ // field 58, encoding 2, 16 bytes - "00000000000050400000000000405040"+ // value 64.0, value 65.0 - "b304"+ // start group field 70 level 1 - "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" - "b404"+ // end group field 70 level 1 - "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" - "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 - "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 - "b21f02"+ // field 502, encoding 2, 2 bytes - "403f"+ // value 32, value -32 - "ba1f03"+ // field 503, encoding 2, 3 bytes - "80017f") // value 64, value -64 -} - -// Test that we can encode empty bytes fields. -func TestEncodeDecodeBytes1(t *testing.T) { - pb := initGoTest(false) - - // Create our bytes - pb.F_BytesRequired = []byte{} - pb.F_BytesRepeated = [][]byte{{}} - pb.F_BytesOptional = []byte{} - - d, err := Marshal(pb) - if err != nil { - t.Error(err) - } - - pbd := new(GoTest) - if err := Unmarshal(d, pbd); err != nil { - t.Error(err) - } - - if pbd.F_BytesRequired == nil || len(pbd.F_BytesRequired) != 0 { - t.Error("required empty bytes field is incorrect") - } - if pbd.F_BytesRepeated == nil || len(pbd.F_BytesRepeated) == 1 && pbd.F_BytesRepeated[0] == nil { - t.Error("repeated empty bytes field is incorrect") - } - if pbd.F_BytesOptional == nil || len(pbd.F_BytesOptional) != 0 { - t.Error("optional empty bytes field is incorrect") - } -} - -// Test that we encode nil-valued fields of a repeated bytes field correctly. -// Since entries in a repeated field cannot be nil, nil must mean empty value. -func TestEncodeDecodeBytes2(t *testing.T) { - pb := initGoTest(false) - - // Create our bytes - pb.F_BytesRepeated = [][]byte{nil} - - d, err := Marshal(pb) - if err != nil { - t.Error(err) - } - - pbd := new(GoTest) - if err := Unmarshal(d, pbd); err != nil { - t.Error(err) - } - - if len(pbd.F_BytesRepeated) != 1 || pbd.F_BytesRepeated[0] == nil { - t.Error("Unexpected value for repeated bytes field") - } -} - -// All required fields set, defaults provided, all repeated fields given two values. -func TestSkippingUnrecognizedFields(t *testing.T) { - o := old() - pb := initGoTestField() - - // Marshal it normally. - o.Marshal(pb) - - // Now new a GoSkipTest record. - skip := &GoSkipTest{ - SkipInt32: Int32(32), - SkipFixed32: Uint32(3232), - SkipFixed64: Uint64(6464), - SkipString: String("skipper"), - Skipgroup: &GoSkipTest_SkipGroup{ - GroupInt32: Int32(75), - GroupString: String("wxyz"), - }, - } - - // Marshal it into same buffer. - o.Marshal(skip) - - pbd := new(GoTestField) - o.Unmarshal(pbd) - - // The __unrecognized field should be a marshaling of GoSkipTest - skipd := new(GoSkipTest) - - o.SetBuf(pbd.XXX_unrecognized) - o.Unmarshal(skipd) - - if *skipd.SkipInt32 != *skip.SkipInt32 { - t.Error("skip int32", skipd.SkipInt32) - } - if *skipd.SkipFixed32 != *skip.SkipFixed32 { - t.Error("skip fixed32", skipd.SkipFixed32) - } - if *skipd.SkipFixed64 != *skip.SkipFixed64 { - t.Error("skip fixed64", skipd.SkipFixed64) - } - if *skipd.SkipString != *skip.SkipString { - t.Error("skip string", *skipd.SkipString) - } - if *skipd.Skipgroup.GroupInt32 != *skip.Skipgroup.GroupInt32 { - t.Error("skip group int32", skipd.Skipgroup.GroupInt32) - } - if *skipd.Skipgroup.GroupString != *skip.Skipgroup.GroupString { - t.Error("skip group string", *skipd.Skipgroup.GroupString) - } -} - -// Check that unrecognized fields of a submessage are preserved. -func TestSubmessageUnrecognizedFields(t *testing.T) { - nm := &NewMessage{ - Nested: &NewMessage_Nested{ - Name: String("Nigel"), - FoodGroup: String("carbs"), - }, - } - b, err := Marshal(nm) - if err != nil { - t.Fatalf("Marshal of NewMessage: %v", err) - } - - // Unmarshal into an OldMessage. - om := new(OldMessage) - if err := Unmarshal(b, om); err != nil { - t.Fatalf("Unmarshal to OldMessage: %v", err) - } - exp := &OldMessage{ - Nested: &OldMessage_Nested{ - Name: String("Nigel"), - // normal protocol buffer users should not do this - XXX_unrecognized: []byte("\x12\x05carbs"), - }, - } - if !Equal(om, exp) { - t.Errorf("om = %v, want %v", om, exp) - } - - // Clone the OldMessage. - om = Clone(om).(*OldMessage) - if !Equal(om, exp) { - t.Errorf("Clone(om) = %v, want %v", om, exp) - } - - // Marshal the OldMessage, then unmarshal it into an empty NewMessage. - if b, err = Marshal(om); err != nil { - t.Fatalf("Marshal of OldMessage: %v", err) - } - t.Logf("Marshal(%v) -> %q", om, b) - nm2 := new(NewMessage) - if err := Unmarshal(b, nm2); err != nil { - t.Fatalf("Unmarshal to NewMessage: %v", err) - } - if !Equal(nm, nm2) { - t.Errorf("NewMessage round-trip: %v => %v", nm, nm2) - } -} - -// Check that an int32 field can be upgraded to an int64 field. -func TestNegativeInt32(t *testing.T) { - om := &OldMessage{ - Num: Int32(-1), - } - b, err := Marshal(om) - if err != nil { - t.Fatalf("Marshal of OldMessage: %v", err) - } - - // Check the size. It should be 11 bytes; - // 1 for the field/wire type, and 10 for the negative number. - if len(b) != 11 { - t.Errorf("%v marshaled as %q, wanted 11 bytes", om, b) - } - - // Unmarshal into a NewMessage. - nm := new(NewMessage) - if err := Unmarshal(b, nm); err != nil { - t.Fatalf("Unmarshal to NewMessage: %v", err) - } - want := &NewMessage{ - Num: Int64(-1), - } - if !Equal(nm, want) { - t.Errorf("nm = %v, want %v", nm, want) - } -} - -// Check that we can grow an array (repeated field) to have many elements. -// This test doesn't depend only on our encoding; for variety, it makes sure -// we create, encode, and decode the correct contents explicitly. It's therefore -// a bit messier. -// This test also uses (and hence tests) the Marshal/Unmarshal functions -// instead of the methods. -func TestBigRepeated(t *testing.T) { - pb := initGoTest(true) - - // Create the arrays - const N = 50 // Internally the library starts much smaller. - pb.Repeatedgroup = make([]*GoTest_RepeatedGroup, N) - pb.F_Sint64Repeated = make([]int64, N) - pb.F_Sint32Repeated = make([]int32, N) - pb.F_BytesRepeated = make([][]byte, N) - pb.F_StringRepeated = make([]string, N) - pb.F_DoubleRepeated = make([]float64, N) - pb.F_FloatRepeated = make([]float32, N) - pb.F_Uint64Repeated = make([]uint64, N) - pb.F_Uint32Repeated = make([]uint32, N) - pb.F_Fixed64Repeated = make([]uint64, N) - pb.F_Fixed32Repeated = make([]uint32, N) - pb.F_Int64Repeated = make([]int64, N) - pb.F_Int32Repeated = make([]int32, N) - pb.F_BoolRepeated = make([]bool, N) - pb.RepeatedField = make([]*GoTestField, N) - - // Fill in the arrays with checkable values. - igtf := initGoTestField() - igtrg := initGoTest_RepeatedGroup() - for i := 0; i < N; i++ { - pb.Repeatedgroup[i] = igtrg - pb.F_Sint64Repeated[i] = int64(i) - pb.F_Sint32Repeated[i] = int32(i) - s := fmt.Sprint(i) - pb.F_BytesRepeated[i] = []byte(s) - pb.F_StringRepeated[i] = s - pb.F_DoubleRepeated[i] = float64(i) - pb.F_FloatRepeated[i] = float32(i) - pb.F_Uint64Repeated[i] = uint64(i) - pb.F_Uint32Repeated[i] = uint32(i) - pb.F_Fixed64Repeated[i] = uint64(i) - pb.F_Fixed32Repeated[i] = uint32(i) - pb.F_Int64Repeated[i] = int64(i) - pb.F_Int32Repeated[i] = int32(i) - pb.F_BoolRepeated[i] = i%2 == 0 - pb.RepeatedField[i] = igtf - } - - // Marshal. - buf, _ := Marshal(pb) - - // Now test Unmarshal by recreating the original buffer. - pbd := new(GoTest) - Unmarshal(buf, pbd) - - // Check the checkable values - for i := uint64(0); i < N; i++ { - if pbd.Repeatedgroup[i] == nil { // TODO: more checking? - t.Error("pbd.Repeatedgroup bad") - } - var x uint64 - x = uint64(pbd.F_Sint64Repeated[i]) - if x != i { - t.Error("pbd.F_Sint64Repeated bad", x, i) - } - x = uint64(pbd.F_Sint32Repeated[i]) - if x != i { - t.Error("pbd.F_Sint32Repeated bad", x, i) - } - s := fmt.Sprint(i) - equalbytes(pbd.F_BytesRepeated[i], []byte(s), t) - if pbd.F_StringRepeated[i] != s { - t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i) - } - x = uint64(pbd.F_DoubleRepeated[i]) - if x != i { - t.Error("pbd.F_DoubleRepeated bad", x, i) - } - x = uint64(pbd.F_FloatRepeated[i]) - if x != i { - t.Error("pbd.F_FloatRepeated bad", x, i) - } - x = pbd.F_Uint64Repeated[i] - if x != i { - t.Error("pbd.F_Uint64Repeated bad", x, i) - } - x = uint64(pbd.F_Uint32Repeated[i]) - if x != i { - t.Error("pbd.F_Uint32Repeated bad", x, i) - } - x = pbd.F_Fixed64Repeated[i] - if x != i { - t.Error("pbd.F_Fixed64Repeated bad", x, i) - } - x = uint64(pbd.F_Fixed32Repeated[i]) - if x != i { - t.Error("pbd.F_Fixed32Repeated bad", x, i) - } - x = uint64(pbd.F_Int64Repeated[i]) - if x != i { - t.Error("pbd.F_Int64Repeated bad", x, i) - } - x = uint64(pbd.F_Int32Repeated[i]) - if x != i { - t.Error("pbd.F_Int32Repeated bad", x, i) - } - if pbd.F_BoolRepeated[i] != (i%2 == 0) { - t.Error("pbd.F_BoolRepeated bad", x, i) - } - if pbd.RepeatedField[i] == nil { // TODO: more checking? - t.Error("pbd.RepeatedField bad") - } - } -} - -// Verify we give a useful message when decoding to the wrong structure type. -func TestTypeMismatch(t *testing.T) { - pb1 := initGoTest(true) - - // Marshal - o := old() - o.Marshal(pb1) - - // Now Unmarshal it to the wrong type. - pb2 := initGoTestField() - err := o.Unmarshal(pb2) - if err == nil { - t.Error("expected error, got no error") - } else if !strings.Contains(err.Error(), "bad wiretype") { - t.Error("expected bad wiretype error, got", err) - } -} - -func encodeDecode(t *testing.T, in, out Message, msg string) { - buf, err := Marshal(in) - if err != nil { - t.Fatalf("failed marshaling %v: %v", msg, err) - } - if err := Unmarshal(buf, out); err != nil { - t.Fatalf("failed unmarshaling %v: %v", msg, err) - } -} - -func TestPackedNonPackedDecoderSwitching(t *testing.T) { - np, p := new(NonPackedTest), new(PackedTest) - - // non-packed -> packed - np.A = []int32{0, 1, 1, 2, 3, 5} - encodeDecode(t, np, p, "non-packed -> packed") - if !reflect.DeepEqual(np.A, p.B) { - t.Errorf("failed non-packed -> packed; np.A=%+v, p.B=%+v", np.A, p.B) - } - - // packed -> non-packed - np.Reset() - p.B = []int32{3, 1, 4, 1, 5, 9} - encodeDecode(t, p, np, "packed -> non-packed") - if !reflect.DeepEqual(p.B, np.A) { - t.Errorf("failed packed -> non-packed; p.B=%+v, np.A=%+v", p.B, np.A) - } -} - -func TestProto1RepeatedGroup(t *testing.T) { - pb := &MessageList{ - Message: []*MessageList_Message{ - { - Name: String("blah"), - Count: Int32(7), - }, - // NOTE: pb.Message[1] is a nil - nil, - }, - } - - o := old() - err := o.Marshal(pb) - if err == nil || !strings.Contains(err.Error(), "repeated field Message has nil") { - t.Fatalf("unexpected or no error when marshaling: %v", err) - } -} - -// Test that enums work. Checks for a bug introduced by making enums -// named types instead of int32: newInt32FromUint64 would crash with -// a type mismatch in reflect.PointTo. -func TestEnum(t *testing.T) { - pb := new(GoEnum) - pb.Foo = FOO_FOO1.Enum() - o := old() - if err := o.Marshal(pb); err != nil { - t.Fatal("error encoding enum:", err) - } - pb1 := new(GoEnum) - if err := o.Unmarshal(pb1); err != nil { - t.Fatal("error decoding enum:", err) - } - if *pb1.Foo != FOO_FOO1 { - t.Error("expected 7 but got ", *pb1.Foo) - } -} - -// Enum types have String methods. Check that enum fields can be printed. -// We don't care what the value actually is, just as long as it doesn't crash. -func TestPrintingNilEnumFields(t *testing.T) { - pb := new(GoEnum) - fmt.Sprintf("%+v", pb) -} - -// Verify that absent required fields cause Marshal/Unmarshal to return errors. -func TestRequiredFieldEnforcement(t *testing.T) { - pb := new(GoTestField) - _, err := Marshal(pb) - if err == nil { - t.Error("marshal: expected error, got nil") - } else if strings.Index(err.Error(), "Label") < 0 { - t.Errorf("marshal: bad error type: %v", err) - } - - // A slightly sneaky, yet valid, proto. It encodes the same required field twice, - // so simply counting the required fields is insufficient. - // field 1, encoding 2, value "hi" - buf := []byte("\x0A\x02hi\x0A\x02hi") - err = Unmarshal(buf, pb) - if err == nil { - t.Error("unmarshal: expected error, got nil") - } else if strings.Index(err.Error(), "{Unknown}") < 0 { - t.Errorf("unmarshal: bad error type: %v", err) - } -} - -func TestTypedNilMarshal(t *testing.T) { - // A typed nil should return ErrNil and not crash. - _, err := Marshal((*GoEnum)(nil)) - if err != ErrNil { - t.Errorf("Marshal: got err %v, want ErrNil", err) - } -} - -// A type that implements the Marshaler interface, but is not nillable. -type nonNillableInt uint64 - -func (nni nonNillableInt) Marshal() ([]byte, error) { - return EncodeVarint(uint64(nni)), nil -} - -type NNIMessage struct { - nni nonNillableInt -} - -func (*NNIMessage) Reset() {} -func (*NNIMessage) String() string { return "" } -func (*NNIMessage) ProtoMessage() {} - -// A type that implements the Marshaler interface and is nillable. -type nillableMessage struct { - x uint64 -} - -func (nm *nillableMessage) Marshal() ([]byte, error) { - return EncodeVarint(nm.x), nil -} - -type NMMessage struct { - nm *nillableMessage -} - -func (*NMMessage) Reset() {} -func (*NMMessage) String() string { return "" } -func (*NMMessage) ProtoMessage() {} - -// Verify a type that uses the Marshaler interface, but has a nil pointer. -func TestNilMarshaler(t *testing.T) { - // Try a struct with a Marshaler field that is nil. - // It should be directly marshable. - nmm := new(NMMessage) - if _, err := Marshal(nmm); err != nil { - t.Error("unexpected error marshaling nmm: ", err) - } - - // Try a struct with a Marshaler field that is not nillable. - nnim := new(NNIMessage) - nnim.nni = 7 - var _ Marshaler = nnim.nni // verify it is truly a Marshaler - if _, err := Marshal(nnim); err != nil { - t.Error("unexpected error marshaling nnim: ", err) - } -} - -func TestAllSetDefaults(t *testing.T) { - // Exercise SetDefaults with all scalar field types. - m := &Defaults{ - // NaN != NaN, so override that here. - F_Nan: Float32(1.7), - } - expected := &Defaults{ - F_Bool: Bool(true), - F_Int32: Int32(32), - F_Int64: Int64(64), - F_Fixed32: Uint32(320), - F_Fixed64: Uint64(640), - F_Uint32: Uint32(3200), - F_Uint64: Uint64(6400), - F_Float: Float32(314159), - F_Double: Float64(271828), - F_String: String(`hello, "world!"` + "\n"), - F_Bytes: []byte("Bignose"), - F_Sint32: Int32(-32), - F_Sint64: Int64(-64), - F_Enum: Defaults_GREEN.Enum(), - F_Pinf: Float32(float32(math.Inf(1))), - F_Ninf: Float32(float32(math.Inf(-1))), - F_Nan: Float32(1.7), - StrZero: String(""), - } - SetDefaults(m) - if !Equal(m, expected) { - t.Errorf("SetDefaults failed\n got %v\nwant %v", m, expected) - } -} - -func TestSetDefaultsWithSetField(t *testing.T) { - // Check that a set value is not overridden. - m := &Defaults{ - F_Int32: Int32(12), - } - SetDefaults(m) - if v := m.GetF_Int32(); v != 12 { - t.Errorf("m.FInt32 = %v, want 12", v) - } -} - -func TestSetDefaultsWithSubMessage(t *testing.T) { - m := &OtherMessage{ - Key: Int64(123), - Inner: &InnerMessage{ - Host: String("gopher"), - }, - } - expected := &OtherMessage{ - Key: Int64(123), - Inner: &InnerMessage{ - Host: String("gopher"), - Port: Int32(4000), - }, - } - SetDefaults(m) - if !Equal(m, expected) { - t.Errorf("\n got %v\nwant %v", m, expected) - } -} - -func TestSetDefaultsWithRepeatedSubMessage(t *testing.T) { - m := &MyMessage{ - RepInner: []*InnerMessage{{}}, - } - expected := &MyMessage{ - RepInner: []*InnerMessage{{ - Port: Int32(4000), - }}, - } - SetDefaults(m) - if !Equal(m, expected) { - t.Errorf("\n got %v\nwant %v", m, expected) - } -} - -func TestSetDefaultWithRepeatedNonMessage(t *testing.T) { - m := &MyMessage{ - Pet: []string{"turtle", "wombat"}, - } - expected := Clone(m) - SetDefaults(m) - if !Equal(m, expected) { - t.Errorf("\n got %v\nwant %v", m, expected) - } -} - -func TestMaximumTagNumber(t *testing.T) { - m := &MaxTag{ - LastField: String("natural goat essence"), - } - buf, err := Marshal(m) - if err != nil { - t.Fatalf("proto.Marshal failed: %v", err) - } - m2 := new(MaxTag) - if err := Unmarshal(buf, m2); err != nil { - t.Fatalf("proto.Unmarshal failed: %v", err) - } - if got, want := m2.GetLastField(), *m.LastField; got != want { - t.Errorf("got %q, want %q", got, want) - } -} - -func TestJSON(t *testing.T) { - m := &MyMessage{ - Count: Int32(4), - Pet: []string{"bunny", "kitty"}, - Inner: &InnerMessage{ - Host: String("cauchy"), - }, - Bikeshed: MyMessage_GREEN.Enum(), - } - const expected = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":1}` - - b, err := json.Marshal(m) - if err != nil { - t.Fatalf("json.Marshal failed: %v", err) - } - s := string(b) - if s != expected { - t.Errorf("got %s\nwant %s", s, expected) - } - - received := new(MyMessage) - if err := json.Unmarshal(b, received); err != nil { - t.Fatalf("json.Unmarshal failed: %v", err) - } - if !Equal(received, m) { - t.Fatalf("got %s, want %s", received, m) - } - - // Test unmarshalling of JSON with symbolic enum name. - const old = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":"GREEN"}` - received.Reset() - if err := json.Unmarshal([]byte(old), received); err != nil { - t.Fatalf("json.Unmarshal failed: %v", err) - } - if !Equal(received, m) { - t.Fatalf("got %s, want %s", received, m) - } -} - -func TestBadWireType(t *testing.T) { - b := []byte{7<<3 | 6} // field 7, wire type 6 - pb := new(OtherMessage) - if err := Unmarshal(b, pb); err == nil { - t.Errorf("Unmarshal did not fail") - } else if !strings.Contains(err.Error(), "unknown wire type") { - t.Errorf("wrong error: %v", err) - } -} - -func TestBytesWithInvalidLength(t *testing.T) { - // If a byte sequence has an invalid (negative) length, Unmarshal should not panic. - b := []byte{2<<3 | WireBytes, 0xff, 0xff, 0xff, 0xff, 0xff, 0} - Unmarshal(b, new(MyMessage)) -} - -func TestLengthOverflow(t *testing.T) { - // Overflowing a length should not panic. - b := []byte{2<<3 | WireBytes, 1, 1, 3<<3 | WireBytes, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01} - Unmarshal(b, new(MyMessage)) -} - -func TestVarintOverflow(t *testing.T) { - // Overflowing a 64-bit length should not be allowed. - b := []byte{1<<3 | WireVarint, 0x01, 3<<3 | WireBytes, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01} - if err := Unmarshal(b, new(MyMessage)); err == nil { - t.Fatalf("Overflowed uint64 length without error") - } -} - -func TestUnmarshalFuzz(t *testing.T) { - const N = 1000 - seed := time.Now().UnixNano() - t.Logf("RNG seed is %d", seed) - rng := rand.New(rand.NewSource(seed)) - buf := make([]byte, 20) - for i := 0; i < N; i++ { - for j := range buf { - buf[j] = byte(rng.Intn(256)) - } - fuzzUnmarshal(t, buf) - } -} - -func TestMergeMessages(t *testing.T) { - pb := &MessageList{Message: []*MessageList_Message{{Name: String("x"), Count: Int32(1)}}} - data, err := Marshal(pb) - if err != nil { - t.Fatalf("Marshal: %v", err) - } - - pb1 := new(MessageList) - if err := Unmarshal(data, pb1); err != nil { - t.Fatalf("first Unmarshal: %v", err) - } - if err := Unmarshal(data, pb1); err != nil { - t.Fatalf("second Unmarshal: %v", err) - } - if len(pb1.Message) != 1 { - t.Errorf("two Unmarshals produced %d Messages, want 1", len(pb1.Message)) - } - - pb2 := new(MessageList) - if err := UnmarshalMerge(data, pb2); err != nil { - t.Fatalf("first UnmarshalMerge: %v", err) - } - if err := UnmarshalMerge(data, pb2); err != nil { - t.Fatalf("second UnmarshalMerge: %v", err) - } - if len(pb2.Message) != 2 { - t.Errorf("two UnmarshalMerges produced %d Messages, want 2", len(pb2.Message)) - } -} - -func TestExtensionMarshalOrder(t *testing.T) { - m := &MyMessage{Count: Int(123)} - if err := SetExtension(m, E_Ext_More, &Ext{Data: String("alpha")}); err != nil { - t.Fatalf("SetExtension: %v", err) - } - if err := SetExtension(m, E_Ext_Text, String("aleph")); err != nil { - t.Fatalf("SetExtension: %v", err) - } - if err := SetExtension(m, E_Ext_Number, Int32(1)); err != nil { - t.Fatalf("SetExtension: %v", err) - } - - // Serialize m several times, and check we get the same bytes each time. - var orig []byte - for i := 0; i < 100; i++ { - b, err := Marshal(m) - if err != nil { - t.Fatalf("Marshal: %v", err) - } - if i == 0 { - orig = b - continue - } - if !bytes.Equal(b, orig) { - t.Errorf("Bytes differ on attempt #%d", i) - } - } -} - -// Many extensions, because small maps might not iterate differently on each iteration. -var exts = []*ExtensionDesc{ - E_X201, - E_X202, - E_X203, - E_X204, - E_X205, - E_X206, - E_X207, - E_X208, - E_X209, - E_X210, - E_X211, - E_X212, - E_X213, - E_X214, - E_X215, - E_X216, - E_X217, - E_X218, - E_X219, - E_X220, - E_X221, - E_X222, - E_X223, - E_X224, - E_X225, - E_X226, - E_X227, - E_X228, - E_X229, - E_X230, - E_X231, - E_X232, - E_X233, - E_X234, - E_X235, - E_X236, - E_X237, - E_X238, - E_X239, - E_X240, - E_X241, - E_X242, - E_X243, - E_X244, - E_X245, - E_X246, - E_X247, - E_X248, - E_X249, - E_X250, -} - -func TestMessageSetMarshalOrder(t *testing.T) { - m := &MyMessageSet{} - for _, x := range exts { - if err := SetExtension(m, x, &Empty{}); err != nil { - t.Fatalf("SetExtension: %v", err) - } - } - - buf, err := Marshal(m) - if err != nil { - t.Fatalf("Marshal: %v", err) - } - - // Serialize m several times, and check we get the same bytes each time. - for i := 0; i < 10; i++ { - b1, err := Marshal(m) - if err != nil { - t.Fatalf("Marshal: %v", err) - } - if !bytes.Equal(b1, buf) { - t.Errorf("Bytes differ on re-Marshal #%d", i) - } - - m2 := &MyMessageSet{} - if err := Unmarshal(buf, m2); err != nil { - t.Errorf("Unmarshal: %v", err) - } - b2, err := Marshal(m2) - if err != nil { - t.Errorf("re-Marshal: %v", err) - } - if !bytes.Equal(b2, buf) { - t.Errorf("Bytes differ on round-trip #%d", i) - } - } -} - -func TestUnmarshalMergesMessages(t *testing.T) { - // If a nested message occurs twice in the input, - // the fields should be merged when decoding. - a := &OtherMessage{ - Key: Int64(123), - Inner: &InnerMessage{ - Host: String("polhode"), - Port: Int32(1234), - }, - } - aData, err := Marshal(a) - if err != nil { - t.Fatalf("Marshal(a): %v", err) - } - b := &OtherMessage{ - Weight: Float32(1.2), - Inner: &InnerMessage{ - Host: String("herpolhode"), - Connected: Bool(true), - }, - } - bData, err := Marshal(b) - if err != nil { - t.Fatalf("Marshal(b): %v", err) - } - want := &OtherMessage{ - Key: Int64(123), - Weight: Float32(1.2), - Inner: &InnerMessage{ - Host: String("herpolhode"), - Port: Int32(1234), - Connected: Bool(true), - }, - } - got := new(OtherMessage) - if err := Unmarshal(append(aData, bData...), got); err != nil { - t.Fatalf("Unmarshal: %v", err) - } - if !Equal(got, want) { - t.Errorf("\n got %v\nwant %v", got, want) - } -} - -func TestEncodingSizes(t *testing.T) { - tests := []struct { - m Message - n int - }{ - {&Defaults{F_Int32: Int32(math.MaxInt32)}, 6}, - {&Defaults{F_Int32: Int32(math.MinInt32)}, 11}, - {&Defaults{F_Uint32: Uint32(uint32(math.MaxInt32) + 1)}, 6}, - {&Defaults{F_Uint32: Uint32(math.MaxUint32)}, 6}, - } - for _, test := range tests { - b, err := Marshal(test.m) - if err != nil { - t.Errorf("Marshal(%v): %v", test.m, err) - continue - } - if len(b) != test.n { - t.Errorf("Marshal(%v) yielded %d bytes, want %d bytes", test.m, len(b), test.n) - } - } -} - -func TestRequiredNotSetError(t *testing.T) { - pb := initGoTest(false) - pb.RequiredField.Label = nil - pb.F_Int32Required = nil - pb.F_Int64Required = nil - - expected := "0807" + // field 1, encoding 0, value 7 - "2206" + "120474797065" + // field 4, encoding 2 (GoTestField) - "5001" + // field 10, encoding 0, value 1 - "6d20000000" + // field 13, encoding 5, value 0x20 - "714000000000000000" + // field 14, encoding 1, value 0x40 - "78a019" + // field 15, encoding 0, value 0xca0 = 3232 - "8001c032" + // field 16, encoding 0, value 0x1940 = 6464 - "8d0100004a45" + // field 17, encoding 5, value 3232.0 - "9101000000000040b940" + // field 18, encoding 1, value 6464.0 - "9a0106" + "737472696e67" + // field 19, encoding 2, string "string" - "b304" + // field 70, encoding 3, start group - "ba0408" + "7265717569726564" + // field 71, encoding 2, string "required" - "b404" + // field 70, encoding 4, end group - "aa0605" + "6279746573" + // field 101, encoding 2, string "bytes" - "b0063f" + // field 102, encoding 0, 0x3f zigzag32 - "b8067f" // field 103, encoding 0, 0x7f zigzag64 - - o := old() - bytes, err := Marshal(pb) - if _, ok := err.(*RequiredNotSetError); !ok { - fmt.Printf("marshal-1 err = %v, want *RequiredNotSetError", err) - o.DebugPrint("", bytes) - t.Fatalf("expected = %s", expected) - } - if strings.Index(err.Error(), "RequiredField.Label") < 0 { - t.Errorf("marshal-1 wrong err msg: %v", err) - } - if !equal(bytes, expected, t) { - o.DebugPrint("neq 1", bytes) - t.Fatalf("expected = %s", expected) - } - - // Now test Unmarshal by recreating the original buffer. - pbd := new(GoTest) - err = Unmarshal(bytes, pbd) - if _, ok := err.(*RequiredNotSetError); !ok { - t.Fatalf("unmarshal err = %v, want *RequiredNotSetError", err) - o.DebugPrint("", bytes) - t.Fatalf("string = %s", expected) - } - if strings.Index(err.Error(), "RequiredField.{Unknown}") < 0 { - t.Errorf("unmarshal wrong err msg: %v", err) - } - bytes, err = Marshal(pbd) - if _, ok := err.(*RequiredNotSetError); !ok { - t.Errorf("marshal-2 err = %v, want *RequiredNotSetError", err) - o.DebugPrint("", bytes) - t.Fatalf("string = %s", expected) - } - if strings.Index(err.Error(), "RequiredField.Label") < 0 { - t.Errorf("marshal-2 wrong err msg: %v", err) - } - if !equal(bytes, expected, t) { - o.DebugPrint("neq 2", bytes) - t.Fatalf("string = %s", expected) - } -} - -func fuzzUnmarshal(t *testing.T, data []byte) { - defer func() { - if e := recover(); e != nil { - t.Errorf("These bytes caused a panic: %+v", data) - t.Logf("Stack:\n%s", debug.Stack()) - t.FailNow() - } - }() - - pb := new(MyMessage) - Unmarshal(data, pb) -} - -func TestMapFieldMarshal(t *testing.T) { - m := &MessageWithMap{ - NameMapping: map[int32]string{ - 1: "Rob", - 4: "Ian", - 8: "Dave", - }, - } - b, err := Marshal(m) - if err != nil { - t.Fatalf("Marshal: %v", err) - } - - // b should be the concatenation of these three byte sequences in some order. - parts := []string{ - "\n\a\b\x01\x12\x03Rob", - "\n\a\b\x04\x12\x03Ian", - "\n\b\b\x08\x12\x04Dave", - } - ok := false - for i := range parts { - for j := range parts { - if j == i { - continue - } - for k := range parts { - if k == i || k == j { - continue - } - try := parts[i] + parts[j] + parts[k] - if bytes.Equal(b, []byte(try)) { - ok = true - break - } - } - } - } - if !ok { - t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2]) - } - t.Logf("FYI b: %q", b) - - (new(Buffer)).DebugPrint("Dump of b", b) -} - -func TestMapFieldRoundTrips(t *testing.T) { - m := &MessageWithMap{ - NameMapping: map[int32]string{ - 1: "Rob", - 4: "Ian", - 8: "Dave", - }, - MsgMapping: map[int64]*FloatingPoint{ - 0x7001: &FloatingPoint{F: Float64(2.0)}, - }, - ByteMapping: map[bool][]byte{ - false: []byte("that's not right!"), - true: []byte("aye, 'tis true!"), - }, - } - b, err := Marshal(m) - if err != nil { - t.Fatalf("Marshal: %v", err) - } - t.Logf("FYI b: %q", b) - m2 := new(MessageWithMap) - if err := Unmarshal(b, m2); err != nil { - t.Fatalf("Unmarshal: %v", err) - } - for _, pair := range [][2]interface{}{ - {m.NameMapping, m2.NameMapping}, - {m.MsgMapping, m2.MsgMapping}, - {m.ByteMapping, m2.ByteMapping}, - } { - if !reflect.DeepEqual(pair[0], pair[1]) { - t.Errorf("Map did not survive a round trip.\ninitial: %v\n final: %v", pair[0], pair[1]) - } - } -} - -func TestMapFieldWithNil(t *testing.T) { - m := &MessageWithMap{ - MsgMapping: map[int64]*FloatingPoint{ - 1: nil, - }, - } - b, err := Marshal(m) - if err == nil { - t.Fatalf("Marshal of bad map should have failed, got these bytes: %v", b) - } -} - -// Benchmarks - -func testMsg() *GoTest { - pb := initGoTest(true) - const N = 1000 // Internally the library starts much smaller. - pb.F_Int32Repeated = make([]int32, N) - pb.F_DoubleRepeated = make([]float64, N) - for i := 0; i < N; i++ { - pb.F_Int32Repeated[i] = int32(i) - pb.F_DoubleRepeated[i] = float64(i) - } - return pb -} - -func bytesMsg() *GoTest { - pb := initGoTest(true) - buf := make([]byte, 4000) - for i := range buf { - buf[i] = byte(i) - } - pb.F_BytesDefaulted = buf - return pb -} - -func benchmarkMarshal(b *testing.B, pb Message, marshal func(Message) ([]byte, error)) { - d, _ := marshal(pb) - b.SetBytes(int64(len(d))) - b.ResetTimer() - for i := 0; i < b.N; i++ { - marshal(pb) - } -} - -func benchmarkBufferMarshal(b *testing.B, pb Message) { - p := NewBuffer(nil) - benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) { - p.Reset() - err := p.Marshal(pb0) - return p.Bytes(), err - }) -} - -func benchmarkSize(b *testing.B, pb Message) { - benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) { - Size(pb) - return nil, nil - }) -} - -func newOf(pb Message) Message { - in := reflect.ValueOf(pb) - if in.IsNil() { - return pb - } - return reflect.New(in.Type().Elem()).Interface().(Message) -} - -func benchmarkUnmarshal(b *testing.B, pb Message, unmarshal func([]byte, Message) error) { - d, _ := Marshal(pb) - b.SetBytes(int64(len(d))) - pbd := newOf(pb) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - unmarshal(d, pbd) - } -} - -func benchmarkBufferUnmarshal(b *testing.B, pb Message) { - p := NewBuffer(nil) - benchmarkUnmarshal(b, pb, func(d []byte, pb0 Message) error { - p.SetBuf(d) - return p.Unmarshal(pb0) - }) -} - -// Benchmark{Marshal,BufferMarshal,Size,Unmarshal,BufferUnmarshal}{,Bytes} - -func BenchmarkMarshal(b *testing.B) { - benchmarkMarshal(b, testMsg(), Marshal) -} - -func BenchmarkBufferMarshal(b *testing.B) { - benchmarkBufferMarshal(b, testMsg()) -} - -func BenchmarkSize(b *testing.B) { - benchmarkSize(b, testMsg()) -} - -func BenchmarkUnmarshal(b *testing.B) { - benchmarkUnmarshal(b, testMsg(), Unmarshal) -} - -func BenchmarkBufferUnmarshal(b *testing.B) { - benchmarkBufferUnmarshal(b, testMsg()) -} - -func BenchmarkMarshalBytes(b *testing.B) { - benchmarkMarshal(b, bytesMsg(), Marshal) -} - -func BenchmarkBufferMarshalBytes(b *testing.B) { - benchmarkBufferMarshal(b, bytesMsg()) -} - -func BenchmarkSizeBytes(b *testing.B) { - benchmarkSize(b, bytesMsg()) -} - -func BenchmarkUnmarshalBytes(b *testing.B) { - benchmarkUnmarshal(b, bytesMsg(), Unmarshal) -} - -func BenchmarkBufferUnmarshalBytes(b *testing.B) { - benchmarkBufferUnmarshal(b, bytesMsg()) -} - -func BenchmarkUnmarshalUnrecognizedFields(b *testing.B) { - b.StopTimer() - pb := initGoTestField() - skip := &GoSkipTest{ - SkipInt32: Int32(32), - SkipFixed32: Uint32(3232), - SkipFixed64: Uint64(6464), - SkipString: String("skipper"), - Skipgroup: &GoSkipTest_SkipGroup{ - GroupInt32: Int32(75), - GroupString: String("wxyz"), - }, - } - - pbd := new(GoTestField) - p := NewBuffer(nil) - p.Marshal(pb) - p.Marshal(skip) - p2 := NewBuffer(nil) - - b.StartTimer() - for i := 0; i < b.N; i++ { - p2.SetBuf(p.Bytes()) - p2.Unmarshal(pbd) - } -} diff --git a/_third_party/github.com/golang/protobuf/proto/clone.go b/_third_party/github.com/golang/protobuf/proto/clone.go deleted file mode 100644 index 915a68b8..00000000 --- a/_third_party/github.com/golang/protobuf/proto/clone.go +++ /dev/null @@ -1,212 +0,0 @@ -// 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: MessageSet and RawMessage. - -package proto - -import ( - "log" - "reflect" - "strings" -) - -// Clone returns a deep copy of a protocol buffer. -func Clone(pb Message) Message { - in := reflect.ValueOf(pb) - if in.IsNil() { - return pb - } - - out := reflect.New(in.Type().Elem()) - // out is empty so a merge is a deep copy. - mergeStruct(out.Elem(), in.Elem()) - return out.Interface().(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) { - in := reflect.ValueOf(src) - out := reflect.ValueOf(dst) - if out.IsNil() { - panic("proto: nil destination") - } - if in.Type() != out.Type() { - // Explicit test prior to mergeStruct so that mistyped nils will fail - panic("proto: type mismatch") - } - if in.IsNil() { - // Merging nil into non-nil is a quiet no-op - 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, ok := in.Addr().Interface().(extendableProto); ok { - emOut := out.Addr().Interface().(extendableProto) - mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap()) - } - - 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.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/_third_party/github.com/golang/protobuf/proto/clone_test.go b/_third_party/github.com/golang/protobuf/proto/clone_test.go deleted file mode 100644 index 34dc62f4..00000000 --- a/_third_party/github.com/golang/protobuf/proto/clone_test.go +++ /dev/null @@ -1,245 +0,0 @@ -// 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. - -package proto_test - -import ( - "testing" - - "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" - - proto3pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/proto3_proto" - pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/testdata" -) - -var cloneTestMessage = &pb.MyMessage{ - Count: proto.Int32(42), - Name: proto.String("Dave"), - Pet: []string{"bunny", "kitty", "horsey"}, - Inner: &pb.InnerMessage{ - Host: proto.String("niles"), - Port: proto.Int32(9099), - Connected: proto.Bool(true), - }, - Others: []*pb.OtherMessage{ - { - Value: []byte("some bytes"), - }, - }, - Somegroup: &pb.MyMessage_SomeGroup{ - GroupField: proto.Int32(6), - }, - RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, -} - -func init() { - ext := &pb.Ext{ - Data: proto.String("extension"), - } - if err := proto.SetExtension(cloneTestMessage, pb.E_Ext_More, ext); err != nil { - panic("SetExtension: " + err.Error()) - } -} - -func TestClone(t *testing.T) { - m := proto.Clone(cloneTestMessage).(*pb.MyMessage) - if !proto.Equal(m, cloneTestMessage) { - t.Errorf("Clone(%v) = %v", cloneTestMessage, m) - } - - // Verify it was a deep copy. - *m.Inner.Port++ - if proto.Equal(m, cloneTestMessage) { - t.Error("Mutating clone changed the original") - } - // Byte fields and repeated fields should be copied. - if &m.Pet[0] == &cloneTestMessage.Pet[0] { - t.Error("Pet: repeated field not copied") - } - if &m.Others[0] == &cloneTestMessage.Others[0] { - t.Error("Others: repeated field not copied") - } - if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] { - t.Error("Others[0].Value: bytes field not copied") - } - if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] { - t.Error("RepBytes: repeated field not copied") - } - if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] { - t.Error("RepBytes[0]: bytes field not copied") - } -} - -func TestCloneNil(t *testing.T) { - var m *pb.MyMessage - if c := proto.Clone(m); !proto.Equal(m, c) { - t.Errorf("Clone(%v) = %v", m, c) - } -} - -var mergeTests = []struct { - src, dst, want proto.Message -}{ - { - src: &pb.MyMessage{ - Count: proto.Int32(42), - }, - dst: &pb.MyMessage{ - Name: proto.String("Dave"), - }, - want: &pb.MyMessage{ - Count: proto.Int32(42), - Name: proto.String("Dave"), - }, - }, - { - src: &pb.MyMessage{ - Inner: &pb.InnerMessage{ - Host: proto.String("hey"), - Connected: proto.Bool(true), - }, - Pet: []string{"horsey"}, - Others: []*pb.OtherMessage{ - { - Value: []byte("some bytes"), - }, - }, - }, - dst: &pb.MyMessage{ - Inner: &pb.InnerMessage{ - Host: proto.String("niles"), - Port: proto.Int32(9099), - }, - Pet: []string{"bunny", "kitty"}, - Others: []*pb.OtherMessage{ - { - Key: proto.Int64(31415926535), - }, - { - // Explicitly test a src=nil field - Inner: nil, - }, - }, - }, - want: &pb.MyMessage{ - Inner: &pb.InnerMessage{ - Host: proto.String("hey"), - Connected: proto.Bool(true), - Port: proto.Int32(9099), - }, - Pet: []string{"bunny", "kitty", "horsey"}, - Others: []*pb.OtherMessage{ - { - Key: proto.Int64(31415926535), - }, - {}, - { - Value: []byte("some bytes"), - }, - }, - }, - }, - { - src: &pb.MyMessage{ - RepBytes: [][]byte{[]byte("wow")}, - }, - dst: &pb.MyMessage{ - Somegroup: &pb.MyMessage_SomeGroup{ - GroupField: proto.Int32(6), - }, - RepBytes: [][]byte{[]byte("sham")}, - }, - want: &pb.MyMessage{ - Somegroup: &pb.MyMessage_SomeGroup{ - GroupField: proto.Int32(6), - }, - RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, - }, - }, - // Check that a scalar bytes field replaces rather than appends. - { - src: &pb.OtherMessage{Value: []byte("foo")}, - dst: &pb.OtherMessage{Value: []byte("bar")}, - want: &pb.OtherMessage{Value: []byte("foo")}, - }, - { - src: &pb.MessageWithMap{ - NameMapping: map[int32]string{6: "Nigel"}, - MsgMapping: map[int64]*pb.FloatingPoint{ - 0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)}, - }, - ByteMapping: map[bool][]byte{true: []byte("wowsa")}, - }, - dst: &pb.MessageWithMap{ - NameMapping: map[int32]string{ - 6: "Bruce", // should be overwritten - 7: "Andrew", - }, - }, - want: &pb.MessageWithMap{ - NameMapping: map[int32]string{ - 6: "Nigel", - 7: "Andrew", - }, - MsgMapping: map[int64]*pb.FloatingPoint{ - 0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)}, - }, - ByteMapping: map[bool][]byte{true: []byte("wowsa")}, - }, - }, - // proto3 shouldn't merge zero values, - // in the same way that proto2 shouldn't merge nils. - { - src: &proto3pb.Message{ - Name: "Aaron", - Data: []byte(""), // zero value, but not nil - }, - dst: &proto3pb.Message{ - HeightInCm: 176, - Data: []byte("texas!"), - }, - want: &proto3pb.Message{ - Name: "Aaron", - HeightInCm: 176, - Data: []byte("texas!"), - }, - }, -} - -func TestMerge(t *testing.T) { - for _, m := range mergeTests { - got := proto.Clone(m.dst) - proto.Merge(got, m.src) - if !proto.Equal(got, m.want) { - t.Errorf("Merge(%v, %v)\n got %v\nwant %v\n", m.dst, m.src, got, m.want) - } - } -} diff --git a/_third_party/github.com/golang/protobuf/proto/decode.go b/_third_party/github.com/golang/protobuf/proto/decode.go deleted file mode 100644 index 312e6043..00000000 --- a/_third_party/github.com/golang/protobuf/proto/decode.go +++ /dev/null @@ -1,827 +0,0 @@ -// 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" - "os" - "reflect" -) - -// errOverflow is returned when an integer is too large to be represented. -var errOverflow = errors.New("proto: integer overflow") - -// The fundamental decoders that interpret bytes on the wire. -// Those that take integer types all return uint64 and are -// therefore of type valueDecoder. - -// 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) { - // x, n already 0 - 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 -} - -// 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) { - // x, err already 0 - - 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 -} - -// 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 -} - -// These are not ValueDecoders: they produce an array of bytes or a string. -// bytes, embedded messages - -// 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 -} - -// Skip the next item in the buffer. Its wire type is decoded and presented as an argument. -// If the protocol buffer has extensions, and the field matches, add it as an extension. -// Otherwise, if the XXX_unrecognized field exists, append the skipped data there. -func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error { - oi := o.index - - err := o.skip(t, tag, wire) - if err != nil { - return err - } - - if !unrecField.IsValid() { - return nil - } - - ptr := structPointer_Bytes(base, unrecField) - - // Add the skipped field to struct field - obuf := o.buf - - o.buf = *ptr - o.EncodeVarint(uint64(tag<<3 | wire)) - *ptr = append(o.buf, obuf[oi:o.index]...) - - o.buf = obuf - - return nil -} - -// Skip the next item in the buffer. Its wire type is decoded and presented as an argument. -func (o *Buffer) skip(t reflect.Type, tag, wire int) error { - - var u uint64 - var err error - - switch wire { - case WireVarint: - _, err = o.DecodeVarint() - case WireFixed64: - _, err = o.DecodeFixed64() - case WireBytes: - _, err = o.DecodeRawBytes(false) - case WireFixed32: - _, err = o.DecodeFixed32() - case WireStartGroup: - for { - u, err = o.DecodeVarint() - if err != nil { - break - } - fwire := int(u & 0x7) - if fwire == WireEndGroup { - break - } - ftag := int(u >> 3) - err = o.skip(t, ftag, fwire) - if err != nil { - break - } - } - default: - err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t) - } - return err -} - -// Unmarshaler is the interface representing objects that can -// unmarshal themselves. The method should reset the receiver before -// decoding starts. The argument points to data that may be -// overwritten, so implementations should not keep references to the -// buffer. -type Unmarshaler interface { - 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() - return UnmarshalMerge(buf, 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 the object can unmarshal itself, let it. - if u, ok := pb.(Unmarshaler); ok { - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// 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. -func (p *Buffer) Unmarshal(pb Message) error { - // If the object can unmarshal itself, let it. - if u, ok := pb.(Unmarshaler); ok { - err := u.Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - - typ, base, err := getbase(pb) - if err != nil { - return err - } - - err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base) - - if collectStats { - stats.Decode++ - } - - return err -} - -// unmarshalType does the work of unmarshaling a structure. -func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error { - var state errorState - required, reqFields := prop.reqCount, uint64(0) - - var err error - for err == nil && o.index < len(o.buf) { - oi := o.index - var u uint64 - u, err = o.DecodeVarint() - if err != nil { - break - } - wire := int(u & 0x7) - if wire == WireEndGroup { - if is_group { - return nil // input is satisfied - } - return fmt.Errorf("proto: %s: wiretype end group for non-group", st) - } - tag := int(u >> 3) - if tag <= 0 { - return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire) - } - fieldnum, ok := prop.decoderTags.get(tag) - if !ok { - // Maybe it's an extension? - if prop.extendable { - if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) { - if err = o.skip(st, tag, wire); err == nil { - ext := e.ExtensionMap()[int32(tag)] // may be missing - ext.enc = append(ext.enc, o.buf[oi:o.index]...) - e.ExtensionMap()[int32(tag)] = ext - } - continue - } - } - err = o.skipAndSave(st, tag, wire, base, prop.unrecField) - continue - } - p := prop.Prop[fieldnum] - - if p.dec == nil { - fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name) - continue - } - dec := p.dec - if wire != WireStartGroup && wire != p.WireType { - if wire == WireBytes && p.packedDec != nil { - // a packable field - dec = p.packedDec - } else { - err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType) - continue - } - } - decErr := dec(o, p, base) - if decErr != nil && !state.shouldContinue(decErr, p) { - err = decErr - } - if err == nil && p.Required { - // Successfully decoded a required field. - if tag <= 64 { - // use bitmap for fields 1-64 to catch field reuse. - var mask uint64 = 1 << uint64(tag-1) - if reqFields&mask == 0 { - // new required field - reqFields |= mask - required-- - } - } else { - // This is imprecise. It can be fooled by a required field - // with a tag > 64 that is encoded twice; that's very rare. - // A fully correct implementation would require allocating - // a data structure, which we would like to avoid. - required-- - } - } - } - if err == nil { - if is_group { - return io.ErrUnexpectedEOF - } - if state.err != nil { - return state.err - } - if required > 0 { - // Not enough information to determine the exact field. If we use extra - // CPU, we could determine the field only if the missing required field - // has a tag <= 64 and we check reqFields. - return &RequiredNotSetError{"{Unknown}"} - } - } - return err -} - -// Individual type decoders -// For each, -// u is the decoded value, -// v is a pointer to the field (pointer) in the struct - -// Sizes of the pools to allocate inside the Buffer. -// The goal is modest amortization and allocation -// on at least 16-byte boundaries. -const ( - boolPoolSize = 16 - uint32PoolSize = 8 - uint64PoolSize = 4 -) - -// Decode a bool. -func (o *Buffer) dec_bool(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - if len(o.bools) == 0 { - o.bools = make([]bool, boolPoolSize) - } - o.bools[0] = u != 0 - *structPointer_Bool(base, p.field) = &o.bools[0] - o.bools = o.bools[1:] - return nil -} - -func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - *structPointer_BoolVal(base, p.field) = u != 0 - return nil -} - -// Decode an int32. -func (o *Buffer) dec_int32(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - word32_Set(structPointer_Word32(base, p.field), o, uint32(u)) - return nil -} - -func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u)) - return nil -} - -// Decode an int64. -func (o *Buffer) dec_int64(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - word64_Set(structPointer_Word64(base, p.field), o, u) - return nil -} - -func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - word64Val_Set(structPointer_Word64Val(base, p.field), o, u) - return nil -} - -// Decode a string. -func (o *Buffer) dec_string(p *Properties, base structPointer) error { - s, err := o.DecodeStringBytes() - if err != nil { - return err - } - *structPointer_String(base, p.field) = &s - return nil -} - -func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error { - s, err := o.DecodeStringBytes() - if err != nil { - return err - } - *structPointer_StringVal(base, p.field) = s - return nil -} - -// Decode a slice of bytes ([]byte). -func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error { - b, err := o.DecodeRawBytes(true) - if err != nil { - return err - } - *structPointer_Bytes(base, p.field) = b - return nil -} - -// Decode a slice of bools ([]bool). -func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - v := structPointer_BoolSlice(base, p.field) - *v = append(*v, u != 0) - return nil -} - -// Decode a slice of bools ([]bool) in packed format. -func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error { - v := structPointer_BoolSlice(base, p.field) - - nn, err := o.DecodeVarint() - if err != nil { - return err - } - nb := int(nn) // number of bytes of encoded bools - - y := *v - for i := 0; i < nb; i++ { - u, err := p.valDec(o) - if err != nil { - return err - } - y = append(y, u != 0) - } - - *v = y - return nil -} - -// Decode a slice of int32s ([]int32). -func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - structPointer_Word32Slice(base, p.field).Append(uint32(u)) - return nil -} - -// Decode a slice of int32s ([]int32) in packed format. -func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error { - v := structPointer_Word32Slice(base, p.field) - - nn, err := o.DecodeVarint() - if err != nil { - return err - } - nb := int(nn) // number of bytes of encoded int32s - - fin := o.index + nb - if fin < o.index { - return errOverflow - } - for o.index < fin { - u, err := p.valDec(o) - if err != nil { - return err - } - v.Append(uint32(u)) - } - return nil -} - -// Decode a slice of int64s ([]int64). -func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error { - u, err := p.valDec(o) - if err != nil { - return err - } - - structPointer_Word64Slice(base, p.field).Append(u) - return nil -} - -// Decode a slice of int64s ([]int64) in packed format. -func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error { - v := structPointer_Word64Slice(base, p.field) - - nn, err := o.DecodeVarint() - if err != nil { - return err - } - nb := int(nn) // number of bytes of encoded int64s - - fin := o.index + nb - if fin < o.index { - return errOverflow - } - for o.index < fin { - u, err := p.valDec(o) - if err != nil { - return err - } - v.Append(u) - } - return nil -} - -// Decode a slice of strings ([]string). -func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error { - s, err := o.DecodeStringBytes() - if err != nil { - return err - } - v := structPointer_StringSlice(base, p.field) - *v = append(*v, s) - return nil -} - -// Decode a slice of slice of bytes ([][]byte). -func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error { - b, err := o.DecodeRawBytes(true) - if err != nil { - return err - } - v := structPointer_BytesSlice(base, p.field) - *v = append(*v, b) - return nil -} - -// Decode a map field. -func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { - raw, err := o.DecodeRawBytes(false) - if err != nil { - return err - } - oi := o.index // index at the end of this map entry - o.index -= len(raw) // move buffer back to start of map entry - - mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V - if mptr.Elem().IsNil() { - mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem())) - } - v := mptr.Elem() // map[K]V - - // Prepare addressable doubly-indirect placeholders for the key and value types. - // See enc_new_map for why. - keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K - keybase := toStructPointer(keyptr.Addr()) // **K - - var valbase structPointer - var valptr reflect.Value - switch p.mtype.Elem().Kind() { - case reflect.Slice: - // []byte - var dummy []byte - valptr = reflect.ValueOf(&dummy) // *[]byte - valbase = toStructPointer(valptr) // *[]byte - case reflect.Ptr: - // message; valptr is **Msg; need to allocate the intermediate pointer - valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V - valptr.Set(reflect.New(valptr.Type().Elem())) - valbase = toStructPointer(valptr) - default: - // everything else - valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V - valbase = toStructPointer(valptr.Addr()) // **V - } - - // Decode. - // This parses a restricted wire format, namely the encoding of a message - // with two fields. See enc_new_map for the format. - for o.index < oi { - // tagcode for key and value properties are always a single byte - // because they have tags 1 and 2. - tagcode := o.buf[o.index] - o.index++ - switch tagcode { - case p.mkeyprop.tagcode[0]: - if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil { - return err - } - case p.mvalprop.tagcode[0]: - if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil { - return err - } - default: - // TODO: Should we silently skip this instead? - return fmt.Errorf("proto: bad map data tag %d", raw[0]) - } - } - keyelem, valelem := keyptr.Elem(), valptr.Elem() - if !keyelem.IsValid() || !valelem.IsValid() { - // We did not decode the key or the value in the map entry. - // Either way, it's an invalid map entry. - return fmt.Errorf("proto: bad map data: missing key/val") - } - - v.SetMapIndex(keyelem, valelem) - return nil -} - -// Decode a group. -func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error { - bas := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(bas) { - // allocate new nested message - bas = toStructPointer(reflect.New(p.stype)) - structPointer_SetStructPointer(base, p.field, bas) - } - return o.unmarshalType(p.stype, p.sprop, true, bas) -} - -// Decode an embedded message. -func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) { - raw, e := o.DecodeRawBytes(false) - if e != nil { - return e - } - - bas := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(bas) { - // allocate new nested message - bas = toStructPointer(reflect.New(p.stype)) - structPointer_SetStructPointer(base, p.field, bas) - } - - // If the object can unmarshal itself, let it. - if p.isUnmarshaler { - iv := structPointer_Interface(bas, p.stype) - return iv.(Unmarshaler).Unmarshal(raw) - } - - obuf := o.buf - oi := o.index - o.buf = raw - o.index = 0 - - err = o.unmarshalType(p.stype, p.sprop, false, bas) - o.buf = obuf - o.index = oi - - return err -} - -// Decode a slice of embedded messages. -func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error { - return o.dec_slice_struct(p, false, base) -} - -// Decode a slice of embedded groups. -func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error { - return o.dec_slice_struct(p, true, base) -} - -// Decode a slice of structs ([]*struct). -func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error { - v := reflect.New(p.stype) - bas := toStructPointer(v) - structPointer_StructPointerSlice(base, p.field).Append(bas) - - if is_group { - err := o.unmarshalType(p.stype, p.sprop, is_group, bas) - return err - } - - raw, err := o.DecodeRawBytes(false) - if err != nil { - return err - } - - // If the object can unmarshal itself, let it. - if p.isUnmarshaler { - iv := v.Interface() - return iv.(Unmarshaler).Unmarshal(raw) - } - - obuf := o.buf - oi := o.index - o.buf = raw - o.index = 0 - - err = o.unmarshalType(p.stype, p.sprop, is_group, bas) - - o.buf = obuf - o.index = oi - - return err -} diff --git a/_third_party/github.com/golang/protobuf/proto/encode.go b/_third_party/github.com/golang/protobuf/proto/encode.go deleted file mode 100644 index b46f7606..00000000 --- a/_third_party/github.com/golang/protobuf/proto/encode.go +++ /dev/null @@ -1,1293 +0,0 @@ -// 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" - "fmt" - "reflect" - "sort" -) - -// RequiredNotSetError is the error returned if Marshal is called with -// a protocol buffer struct whose required fields have not -// all been initialized. It is also the error returned if Unmarshal is -// called with an encoded protocol buffer that does not include all the -// required fields. -// -// When printed, RequiredNotSetError reports the first unset required field in a -// message. If the field cannot be precisely determined, it is reported as -// "{Unknown}". -type RequiredNotSetError struct { - field string -} - -func (e *RequiredNotSetError) Error() string { - return fmt.Sprintf("proto: required field %q not set", e.field) -} - -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") - - // ErrNil is the error returned if Marshal is called with nil. - ErrNil = errors.New("proto: Marshal called with nil") -) - -// 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 -} - -func sizeVarint(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} - -// 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 -} - -func sizeFixed64(x uint64) int { - return 8 -} - -// 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 -} - -func sizeFixed32(x uint64) int { - return 4 -} - -// 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)))) -} - -func sizeZigzag64(x uint64) int { - return sizeVarint(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)))) -} - -func sizeZigzag32(x uint64) int { - return sizeVarint(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 -} - -func sizeRawBytes(b []byte) int { - return sizeVarint(uint64(len(b))) + - len(b) -} - -// 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 -} - -func sizeStringBytes(s string) int { - return sizeVarint(uint64(len(s))) + - len(s) -} - -// Marshaler is the interface representing objects that can marshal themselves. -type Marshaler interface { - Marshal() ([]byte, error) -} - -// Marshal takes the protocol buffer -// and encodes it into the wire format, returning the data. -func Marshal(pb Message) ([]byte, error) { - // Can the object marshal itself? - if m, ok := pb.(Marshaler); ok { - return m.Marshal() - } - p := NewBuffer(nil) - err := p.Marshal(pb) - var state errorState - if err != nil && !state.shouldContinue(err, nil) { - return nil, err - } - if p.buf == nil && err == nil { - // Return a non-nil slice on success. - return []byte{}, nil - } - return p.buf, err -} - -// Marshal takes the protocol buffer -// and encodes it into the wire format, writing the result to the -// Buffer. -func (p *Buffer) Marshal(pb Message) error { - // Can the object marshal itself? - if m, ok := pb.(Marshaler); ok { - data, err := m.Marshal() - if err != nil { - return err - } - p.buf = append(p.buf, data...) - return nil - } - - t, base, err := getbase(pb) - if structPointer_IsNil(base) { - return ErrNil - } - if err == nil { - err = p.enc_struct(GetProperties(t.Elem()), base) - } - - if collectStats { - stats.Encode++ - } - - return err -} - -// Size returns the encoded size of a protocol buffer. -func Size(pb Message) (n int) { - // Can the object marshal itself? If so, Size is slow. - // TODO: add Size to Marshaler, or add a Sizer interface. - if m, ok := pb.(Marshaler); ok { - b, _ := m.Marshal() - return len(b) - } - - t, base, err := getbase(pb) - if structPointer_IsNil(base) { - return 0 - } - if err == nil { - n = size_struct(GetProperties(t.Elem()), base) - } - - if collectStats { - stats.Size++ - } - - return -} - -// Individual type encoders. - -// Encode a bool. -func (o *Buffer) enc_bool(p *Properties, base structPointer) error { - v := *structPointer_Bool(base, p.field) - if v == nil { - return ErrNil - } - x := 0 - if *v { - x = 1 - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error { - v := *structPointer_BoolVal(base, p.field) - if !v { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, 1) - return nil -} - -func size_bool(p *Properties, base structPointer) int { - v := *structPointer_Bool(base, p.field) - if v == nil { - return 0 - } - return len(p.tagcode) + 1 // each bool takes exactly one byte -} - -func size_proto3_bool(p *Properties, base structPointer) int { - v := *structPointer_BoolVal(base, p.field) - if !v { - return 0 - } - return len(p.tagcode) + 1 // each bool takes exactly one byte -} - -// Encode an int32. -func (o *Buffer) enc_int32(p *Properties, base structPointer) error { - v := structPointer_Word32(base, p.field) - if word32_IsNil(v) { - return ErrNil - } - x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error { - v := structPointer_Word32Val(base, p.field) - x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range - if x == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func size_int32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32(base, p.field) - if word32_IsNil(v) { - return 0 - } - x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -func size_proto3_int32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32Val(base, p.field) - x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range - if x == 0 { - return 0 - } - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -// Encode a uint32. -// Exactly the same as int32, except for no sign extension. -func (o *Buffer) enc_uint32(p *Properties, base structPointer) error { - v := structPointer_Word32(base, p.field) - if word32_IsNil(v) { - return ErrNil - } - x := word32_Get(v) - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error { - v := structPointer_Word32Val(base, p.field) - x := word32Val_Get(v) - if x == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, uint64(x)) - return nil -} - -func size_uint32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32(base, p.field) - if word32_IsNil(v) { - return 0 - } - x := word32_Get(v) - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -func size_proto3_uint32(p *Properties, base structPointer) (n int) { - v := structPointer_Word32Val(base, p.field) - x := word32Val_Get(v) - if x == 0 { - return 0 - } - n += len(p.tagcode) - n += p.valSize(uint64(x)) - return -} - -// Encode an int64. -func (o *Buffer) enc_int64(p *Properties, base structPointer) error { - v := structPointer_Word64(base, p.field) - if word64_IsNil(v) { - return ErrNil - } - x := word64_Get(v) - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, x) - return nil -} - -func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error { - v := structPointer_Word64Val(base, p.field) - x := word64Val_Get(v) - if x == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, x) - return nil -} - -func size_int64(p *Properties, base structPointer) (n int) { - v := structPointer_Word64(base, p.field) - if word64_IsNil(v) { - return 0 - } - x := word64_Get(v) - n += len(p.tagcode) - n += p.valSize(x) - return -} - -func size_proto3_int64(p *Properties, base structPointer) (n int) { - v := structPointer_Word64Val(base, p.field) - x := word64Val_Get(v) - if x == 0 { - return 0 - } - n += len(p.tagcode) - n += p.valSize(x) - return -} - -// Encode a string. -func (o *Buffer) enc_string(p *Properties, base structPointer) error { - v := *structPointer_String(base, p.field) - if v == nil { - return ErrNil - } - x := *v - o.buf = append(o.buf, p.tagcode...) - o.EncodeStringBytes(x) - return nil -} - -func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error { - v := *structPointer_StringVal(base, p.field) - if v == "" { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeStringBytes(v) - return nil -} - -func size_string(p *Properties, base structPointer) (n int) { - v := *structPointer_String(base, p.field) - if v == nil { - return 0 - } - x := *v - n += len(p.tagcode) - n += sizeStringBytes(x) - return -} - -func size_proto3_string(p *Properties, base structPointer) (n int) { - v := *structPointer_StringVal(base, p.field) - if v == "" { - return 0 - } - n += len(p.tagcode) - n += sizeStringBytes(v) - return -} - -// 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 -} - -// Encode a message struct. -func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error { - var state errorState - structp := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return ErrNil - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, err := m.Marshal() - if err != nil && !state.shouldContinue(err, nil) { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - return nil - } - - o.buf = append(o.buf, p.tagcode...) - return o.enc_len_struct(p.sprop, structp, &state) -} - -func size_struct_message(p *Properties, base structPointer) int { - structp := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(structp) { - return 0 - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, _ := m.Marshal() - n0 := len(p.tagcode) - n1 := sizeRawBytes(data) - return n0 + n1 - } - - n0 := len(p.tagcode) - n1 := size_struct(p.sprop, structp) - n2 := sizeVarint(uint64(n1)) // size of encoded length - return n0 + n1 + n2 -} - -// Encode a group struct. -func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error { - var state errorState - b := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(b) { - return ErrNil - } - - o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) - err := o.enc_struct(p.sprop, b) - if err != nil && !state.shouldContinue(err, nil) { - return err - } - o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) - return state.err -} - -func size_struct_group(p *Properties, base structPointer) (n int) { - b := structPointer_GetStructPointer(base, p.field) - if structPointer_IsNil(b) { - return 0 - } - - n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup)) - n += size_struct(p.sprop, b) - n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup)) - return -} - -// Encode a slice of bools ([]bool). -func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error { - s := *structPointer_BoolSlice(base, p.field) - l := len(s) - if l == 0 { - return ErrNil - } - for _, x := range s { - o.buf = append(o.buf, p.tagcode...) - v := uint64(0) - if x { - v = 1 - } - p.valEnc(o, v) - } - return nil -} - -func size_slice_bool(p *Properties, base structPointer) int { - s := *structPointer_BoolSlice(base, p.field) - l := len(s) - if l == 0 { - return 0 - } - return l * (len(p.tagcode) + 1) // each bool takes exactly one byte -} - -// Encode a slice of bools ([]bool) in packed format. -func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error { - s := *structPointer_BoolSlice(base, p.field) - l := len(s) - if l == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeVarint(uint64(l)) // each bool takes exactly one byte - for _, x := range s { - v := uint64(0) - if x { - v = 1 - } - p.valEnc(o, v) - } - return nil -} - -func size_slice_packed_bool(p *Properties, base structPointer) (n int) { - s := *structPointer_BoolSlice(base, p.field) - l := len(s) - if l == 0 { - return 0 - } - n += len(p.tagcode) - n += sizeVarint(uint64(l)) - n += l // each bool takes exactly one byte - return -} - -// Encode a slice of bytes ([]byte). -func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error { - s := *structPointer_Bytes(base, p.field) - if s == nil { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(s) - return nil -} - -func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error { - s := *structPointer_Bytes(base, p.field) - if len(s) == 0 { - return ErrNil - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(s) - return nil -} - -func size_slice_byte(p *Properties, base structPointer) (n int) { - s := *structPointer_Bytes(base, p.field) - if s == nil { - return 0 - } - n += len(p.tagcode) - n += sizeRawBytes(s) - return -} - -func size_proto3_slice_byte(p *Properties, base structPointer) (n int) { - s := *structPointer_Bytes(base, p.field) - if len(s) == 0 { - return 0 - } - n += len(p.tagcode) - n += sizeRawBytes(s) - return -} - -// Encode a slice of int32s ([]int32). -func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - x := int32(s.Index(i)) // permit sign extension to use full 64-bit range - p.valEnc(o, uint64(x)) - } - return nil -} - -func size_slice_int32(p *Properties, base structPointer) (n int) { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - for i := 0; i < l; i++ { - n += len(p.tagcode) - x := int32(s.Index(i)) // permit sign extension to use full 64-bit range - n += p.valSize(uint64(x)) - } - return -} - -// Encode a slice of int32s ([]int32) in packed format. -func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - // TODO: Reuse a Buffer. - buf := NewBuffer(nil) - for i := 0; i < l; i++ { - x := int32(s.Index(i)) // permit sign extension to use full 64-bit range - p.valEnc(buf, uint64(x)) - } - - o.buf = append(o.buf, p.tagcode...) - o.EncodeVarint(uint64(len(buf.buf))) - o.buf = append(o.buf, buf.buf...) - return nil -} - -func size_slice_packed_int32(p *Properties, base structPointer) (n int) { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - var bufSize int - for i := 0; i < l; i++ { - x := int32(s.Index(i)) // permit sign extension to use full 64-bit range - bufSize += p.valSize(uint64(x)) - } - - n += len(p.tagcode) - n += sizeVarint(uint64(bufSize)) - n += bufSize - return -} - -// Encode a slice of uint32s ([]uint32). -// Exactly the same as int32, except for no sign extension. -func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - x := s.Index(i) - p.valEnc(o, uint64(x)) - } - return nil -} - -func size_slice_uint32(p *Properties, base structPointer) (n int) { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - for i := 0; i < l; i++ { - n += len(p.tagcode) - x := s.Index(i) - n += p.valSize(uint64(x)) - } - return -} - -// Encode a slice of uint32s ([]uint32) in packed format. -// Exactly the same as int32, except for no sign extension. -func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - // TODO: Reuse a Buffer. - buf := NewBuffer(nil) - for i := 0; i < l; i++ { - p.valEnc(buf, uint64(s.Index(i))) - } - - o.buf = append(o.buf, p.tagcode...) - o.EncodeVarint(uint64(len(buf.buf))) - o.buf = append(o.buf, buf.buf...) - return nil -} - -func size_slice_packed_uint32(p *Properties, base structPointer) (n int) { - s := structPointer_Word32Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - var bufSize int - for i := 0; i < l; i++ { - bufSize += p.valSize(uint64(s.Index(i))) - } - - n += len(p.tagcode) - n += sizeVarint(uint64(bufSize)) - n += bufSize - return -} - -// Encode a slice of int64s ([]int64). -func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error { - s := structPointer_Word64Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - p.valEnc(o, s.Index(i)) - } - return nil -} - -func size_slice_int64(p *Properties, base structPointer) (n int) { - s := structPointer_Word64Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - for i := 0; i < l; i++ { - n += len(p.tagcode) - n += p.valSize(s.Index(i)) - } - return -} - -// Encode a slice of int64s ([]int64) in packed format. -func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error { - s := structPointer_Word64Slice(base, p.field) - l := s.Len() - if l == 0 { - return ErrNil - } - // TODO: Reuse a Buffer. - buf := NewBuffer(nil) - for i := 0; i < l; i++ { - p.valEnc(buf, s.Index(i)) - } - - o.buf = append(o.buf, p.tagcode...) - o.EncodeVarint(uint64(len(buf.buf))) - o.buf = append(o.buf, buf.buf...) - return nil -} - -func size_slice_packed_int64(p *Properties, base structPointer) (n int) { - s := structPointer_Word64Slice(base, p.field) - l := s.Len() - if l == 0 { - return 0 - } - var bufSize int - for i := 0; i < l; i++ { - bufSize += p.valSize(s.Index(i)) - } - - n += len(p.tagcode) - n += sizeVarint(uint64(bufSize)) - n += bufSize - return -} - -// Encode a slice of slice of bytes ([][]byte). -func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error { - ss := *structPointer_BytesSlice(base, p.field) - l := len(ss) - if l == 0 { - return ErrNil - } - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(ss[i]) - } - return nil -} - -func size_slice_slice_byte(p *Properties, base structPointer) (n int) { - ss := *structPointer_BytesSlice(base, p.field) - l := len(ss) - if l == 0 { - return 0 - } - n += l * len(p.tagcode) - for i := 0; i < l; i++ { - n += sizeRawBytes(ss[i]) - } - return -} - -// Encode a slice of strings ([]string). -func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error { - ss := *structPointer_StringSlice(base, p.field) - l := len(ss) - for i := 0; i < l; i++ { - o.buf = append(o.buf, p.tagcode...) - o.EncodeStringBytes(ss[i]) - } - return nil -} - -func size_slice_string(p *Properties, base structPointer) (n int) { - ss := *structPointer_StringSlice(base, p.field) - l := len(ss) - n += l * len(p.tagcode) - for i := 0; i < l; i++ { - n += sizeStringBytes(ss[i]) - } - return -} - -// Encode a slice of message structs ([]*struct). -func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error { - var state errorState - s := structPointer_StructPointerSlice(base, p.field) - l := s.Len() - - for i := 0; i < l; i++ { - structp := s.Index(i) - if structPointer_IsNil(structp) { - return errRepeatedHasNil - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, err := m.Marshal() - if err != nil && !state.shouldContinue(err, nil) { - return err - } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(data) - continue - } - - o.buf = append(o.buf, p.tagcode...) - err := o.enc_len_struct(p.sprop, structp, &state) - if err != nil && !state.shouldContinue(err, nil) { - if err == ErrNil { - return errRepeatedHasNil - } - return err - } - } - return state.err -} - -func size_slice_struct_message(p *Properties, base structPointer) (n int) { - s := structPointer_StructPointerSlice(base, p.field) - l := s.Len() - n += l * len(p.tagcode) - for i := 0; i < l; i++ { - structp := s.Index(i) - if structPointer_IsNil(structp) { - return // return the size up to this point - } - - // Can the object marshal itself? - if p.isMarshaler { - m := structPointer_Interface(structp, p.stype).(Marshaler) - data, _ := m.Marshal() - n += len(p.tagcode) - n += sizeRawBytes(data) - continue - } - - n0 := size_struct(p.sprop, structp) - n1 := sizeVarint(uint64(n0)) // size of encoded length - n += n0 + n1 - } - return -} - -// Encode a slice of group structs ([]*struct). -func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error { - var state errorState - s := structPointer_StructPointerSlice(base, p.field) - l := s.Len() - - for i := 0; i < l; i++ { - b := s.Index(i) - if structPointer_IsNil(b) { - return errRepeatedHasNil - } - - o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) - - err := o.enc_struct(p.sprop, b) - - if err != nil && !state.shouldContinue(err, nil) { - if err == ErrNil { - return errRepeatedHasNil - } - return err - } - - o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) - } - return state.err -} - -func size_slice_struct_group(p *Properties, base structPointer) (n int) { - s := structPointer_StructPointerSlice(base, p.field) - l := s.Len() - - n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup)) - n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup)) - for i := 0; i < l; i++ { - b := s.Index(i) - if structPointer_IsNil(b) { - return // return size up to this point - } - - n += size_struct(p.sprop, b) - } - return -} - -// Encode an extension map. -func (o *Buffer) enc_map(p *Properties, base structPointer) error { - v := *structPointer_ExtMap(base, p.field) - if err := encodeExtensionMap(v); err != nil { - return err - } - // Fast-path for common cases: zero or one extensions. - if len(v) <= 1 { - for _, e := range v { - o.buf = append(o.buf, e.enc...) - } - return nil - } - - // Sort keys to provide a deterministic encoding. - keys := make([]int, 0, len(v)) - for k := range v { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, k := range keys { - o.buf = append(o.buf, v[int32(k)].enc...) - } - return nil -} - -func size_map(p *Properties, base structPointer) int { - v := *structPointer_ExtMap(base, p.field) - return sizeExtensionMap(v) -} - -// Encode a map field. -func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { - var state errorState // XXX: or do we need to plumb this through? - - /* - A map defined as - map map_field = N; - is encoded in the same way as - message MapFieldEntry { - key_type key = 1; - value_type value = 2; - } - repeated MapFieldEntry map_field = N; - */ - - v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V - if v.Len() == 0 { - return nil - } - - keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) - - enc := func() error { - if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil { - return err - } - if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil { - return err - } - return nil - } - - keys := v.MapKeys() - sort.Sort(mapKeys(keys)) - for _, key := range keys { - val := v.MapIndex(key) - - // The only illegal map entry values are nil message pointers. - if val.Kind() == reflect.Ptr && val.IsNil() { - return errors.New("proto: map has nil element") - } - - keycopy.Set(key) - valcopy.Set(val) - - o.buf = append(o.buf, p.tagcode...) - if err := o.enc_len_thing(enc, &state); err != nil { - return err - } - } - return nil -} - -func size_new_map(p *Properties, base structPointer) int { - v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V - - keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) - - n := 0 - for _, key := range v.MapKeys() { - val := v.MapIndex(key) - keycopy.Set(key) - valcopy.Set(val) - - // Tag codes for key and val are the responsibility of the sub-sizer. - keysize := p.mkeyprop.size(p.mkeyprop, keybase) - valsize := p.mvalprop.size(p.mvalprop, valbase) - entry := keysize + valsize - // Add on tag code and length of map entry itself. - n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry - } - return n -} - -// mapEncodeScratch returns a new reflect.Value matching the map's value type, -// and a structPointer suitable for passing to an encoder or sizer. -func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) { - // Prepare addressable doubly-indirect placeholders for the key and value types. - // This is needed because the element-type encoders expect **T, but the map iteration produces T. - - keycopy = reflect.New(mapType.Key()).Elem() // addressable K - keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K - keyptr.Set(keycopy.Addr()) // - keybase = toStructPointer(keyptr.Addr()) // **K - - // Value types are more varied and require special handling. - switch mapType.Elem().Kind() { - case reflect.Slice: - // []byte - var dummy []byte - valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte - valbase = toStructPointer(valcopy.Addr()) - case reflect.Ptr: - // message; the generated field type is map[K]*Msg (so V is *Msg), - // so we only need one level of indirection. - valcopy = reflect.New(mapType.Elem()).Elem() // addressable V - valbase = toStructPointer(valcopy.Addr()) - default: - // everything else - valcopy = reflect.New(mapType.Elem()).Elem() // addressable V - valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V - valptr.Set(valcopy.Addr()) // - valbase = toStructPointer(valptr.Addr()) // **V - } - return -} - -// Encode a struct. -func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { - var state errorState - // Encode fields in tag order so that decoders may use optimizations - // that depend on the ordering. - // https://developers.google.com/protocol-buffers/docs/encoding#order - for _, i := range prop.order { - p := prop.Prop[i] - if p.enc != nil { - err := p.enc(o, p, base) - if err != nil { - if err == ErrNil { - if p.Required && state.err == nil { - state.err = &RequiredNotSetError{p.Name} - } - } else if err == errRepeatedHasNil { - // Give more context to nil values in repeated fields. - return errors.New("repeated field " + p.OrigName + " has nil element") - } else if !state.shouldContinue(err, p) { - return err - } - } - } - } - - // Add unrecognized fields at the end. - if prop.unrecField.IsValid() { - v := *structPointer_Bytes(base, prop.unrecField) - if len(v) > 0 { - o.buf = append(o.buf, v...) - } - } - - return state.err -} - -func size_struct(prop *StructProperties, base structPointer) (n int) { - for _, i := range prop.order { - p := prop.Prop[i] - if p.size != nil { - n += p.size(p, base) - } - } - - // Add unrecognized fields at the end. - if prop.unrecField.IsValid() { - v := *structPointer_Bytes(base, prop.unrecField) - n += len(v) - } - - return -} - -var zeroes [20]byte // longer than any conceivable sizeVarint - -// Encode a struct, preceded by its encoded length (as a varint). -func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error { - return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state) -} - -// Encode something, preceded by its encoded length (as a varint). -func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error { - iLen := len(o.buf) - o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length - iMsg := len(o.buf) - err := enc() - if err != nil && !state.shouldContinue(err, nil) { - return err - } - lMsg := len(o.buf) - iMsg - lLen := sizeVarint(uint64(lMsg)) - switch x := lLen - (iMsg - iLen); { - case x > 0: // actual length is x bytes larger than the space we reserved - // Move msg x bytes right. - o.buf = append(o.buf, zeroes[:x]...) - copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) - case x < 0: // actual length is x bytes smaller than the space we reserved - // Move msg x bytes left. - copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) - o.buf = o.buf[:len(o.buf)+x] // x is negative - } - // Encode the length in the reserved space. - o.buf = o.buf[:iLen] - o.EncodeVarint(uint64(lMsg)) - o.buf = o.buf[:len(o.buf)+lMsg] - return state.err -} - -// errorState maintains the first error that occurs and updates that error -// with additional context. -type errorState struct { - err error -} - -// shouldContinue reports whether encoding should continue upon encountering the -// given error. If the error is RequiredNotSetError, shouldContinue returns true -// and, if this is the first appearance of that error, remembers it for future -// reporting. -// -// If prop is not nil, it may update any error with additional context about the -// field with the error. -func (s *errorState) shouldContinue(err error, prop *Properties) bool { - // Ignore unset required fields. - reqNotSet, ok := err.(*RequiredNotSetError) - if !ok { - return false - } - if s.err == nil { - if prop != nil { - err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field} - } - s.err = err - } - return true -} diff --git a/_third_party/github.com/golang/protobuf/proto/equal.go b/_third_party/github.com/golang/protobuf/proto/equal.go deleted file mode 100644 index d8673a3e..00000000 --- a/_third_party/github.com/golang/protobuf/proto/equal.go +++ /dev/null @@ -1,256 +0,0 @@ -// 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. -// TODO: MessageSet. - -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. - - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal (a "bytes" field, - although represented by []byte, is not a repeated field) - - 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. - - 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 { - 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 - } - b1, ok := f1.Interface().(raw) - if ok { - b2 := f2.Interface().(raw) - // RawMessage - if !bytes.Equal(b1.Bytes(), b2.Bytes()) { - return false - } - continue - } - f1, f2 = f1.Elem(), f2.Elem() - } - if !equalAny(f1, f2) { - return false - } - } - - if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_extensions") - if !equalExtensions(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() - if !bytes.Equal(u1, u2) { - return false - } - - return true -} - -// v1 and v2 are known to have the same type. -func equalAny(v1, v2 reflect.Value) 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.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) { - return false - } - } - return true - case reflect.Ptr: - return equalAny(v1.Elem(), v2.Elem()) - case reflect.Slice: - if v1.Type().Elem().Kind() == reflect.Uint8 { - // short circuit: []byte - 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)) { - 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. -// em1 and em2 are extension maps. -func equalExtensions(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 are unencoded. - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) { - 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 { - log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) - continue - } - 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)) { - return false - } - } - - return true -} diff --git a/_third_party/github.com/golang/protobuf/proto/equal_test.go b/_third_party/github.com/golang/protobuf/proto/equal_test.go deleted file mode 100644 index c59458fa..00000000 --- a/_third_party/github.com/golang/protobuf/proto/equal_test.go +++ /dev/null @@ -1,191 +0,0 @@ -// 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. - -package proto_test - -import ( - "testing" - - . "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" - pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/testdata" -) - -// Four identical base messages. -// The init function adds extensions to some of them. -var messageWithoutExtension = &pb.MyMessage{Count: Int32(7)} -var messageWithExtension1a = &pb.MyMessage{Count: Int32(7)} -var messageWithExtension1b = &pb.MyMessage{Count: Int32(7)} -var messageWithExtension2 = &pb.MyMessage{Count: Int32(7)} - -// Two messages with non-message extensions. -var messageWithInt32Extension1 = &pb.MyMessage{Count: Int32(8)} -var messageWithInt32Extension2 = &pb.MyMessage{Count: Int32(8)} - -func init() { - ext1 := &pb.Ext{Data: String("Kirk")} - ext2 := &pb.Ext{Data: String("Picard")} - - // messageWithExtension1a has ext1, but never marshals it. - if err := SetExtension(messageWithExtension1a, pb.E_Ext_More, ext1); err != nil { - panic("SetExtension on 1a failed: " + err.Error()) - } - - // messageWithExtension1b is the unmarshaled form of messageWithExtension1a. - if err := SetExtension(messageWithExtension1b, pb.E_Ext_More, ext1); err != nil { - panic("SetExtension on 1b failed: " + err.Error()) - } - buf, err := Marshal(messageWithExtension1b) - if err != nil { - panic("Marshal of 1b failed: " + err.Error()) - } - messageWithExtension1b.Reset() - if err := Unmarshal(buf, messageWithExtension1b); err != nil { - panic("Unmarshal of 1b failed: " + err.Error()) - } - - // messageWithExtension2 has ext2. - if err := SetExtension(messageWithExtension2, pb.E_Ext_More, ext2); err != nil { - panic("SetExtension on 2 failed: " + err.Error()) - } - - if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(23)); err != nil { - panic("SetExtension on Int32-1 failed: " + err.Error()) - } - if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(24)); err != nil { - panic("SetExtension on Int32-2 failed: " + err.Error()) - } -} - -var EqualTests = []struct { - desc string - a, b Message - exp bool -}{ - {"different types", &pb.GoEnum{}, &pb.GoTestField{}, false}, - {"equal empty", &pb.GoEnum{}, &pb.GoEnum{}, true}, - {"nil vs nil", nil, nil, true}, - {"typed nil vs typed nil", (*pb.GoEnum)(nil), (*pb.GoEnum)(nil), true}, - {"typed nil vs empty", (*pb.GoEnum)(nil), &pb.GoEnum{}, false}, - {"different typed nil", (*pb.GoEnum)(nil), (*pb.GoTestField)(nil), false}, - - {"one set field, one unset field", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{}, false}, - {"one set field zero, one unset field", &pb.GoTest{Param: Int32(0)}, &pb.GoTest{}, false}, - {"different set fields", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("bar")}, false}, - {"equal set", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("foo")}, true}, - - {"repeated, one set", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{}, false}, - {"repeated, different length", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{F_Int32Repeated: []int32{2}}, false}, - {"repeated, different value", &pb.GoTest{F_Int32Repeated: []int32{2}}, &pb.GoTest{F_Int32Repeated: []int32{3}}, false}, - {"repeated, equal", &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, true}, - {"repeated, nil equal nil", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: nil}, true}, - {"repeated, nil equal empty", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: []int32{}}, true}, - {"repeated, empty equal nil", &pb.GoTest{F_Int32Repeated: []int32{}}, &pb.GoTest{F_Int32Repeated: nil}, true}, - - { - "nested, different", - &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("foo")}}, - &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("bar")}}, - false, - }, - { - "nested, equal", - &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}}, - &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}}, - true, - }, - - {"bytes", &pb.OtherMessage{Value: []byte("foo")}, &pb.OtherMessage{Value: []byte("foo")}, true}, - {"bytes, empty", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: []byte{}}, true}, - {"bytes, empty vs nil", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: nil}, false}, - { - "repeated bytes", - &pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, - &pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, - true, - }, - - {"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false}, - {"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true}, - {"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false}, - - {"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true}, - {"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false}, - - { - "message with group", - &pb.MyMessage{ - Count: Int32(1), - Somegroup: &pb.MyMessage_SomeGroup{ - GroupField: Int32(5), - }, - }, - &pb.MyMessage{ - Count: Int32(1), - Somegroup: &pb.MyMessage_SomeGroup{ - GroupField: Int32(5), - }, - }, - true, - }, - - { - "map same", - &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, - &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, - true, - }, - { - "map different entry", - &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, - &pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}}, - false, - }, - { - "map different key only", - &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, - &pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}}, - false, - }, - { - "map different value only", - &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, - &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}}, - false, - }, -} - -func TestEqual(t *testing.T) { - for _, tc := range EqualTests { - if res := Equal(tc.a, tc.b); res != tc.exp { - t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp) - } - } -} diff --git a/_third_party/github.com/golang/protobuf/proto/extensions.go b/_third_party/github.com/golang/protobuf/proto/extensions.go deleted file mode 100644 index e591ccef..00000000 --- a/_third_party/github.com/golang/protobuf/proto/extensions.go +++ /dev/null @@ -1,400 +0,0 @@ -// 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" - "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 that may be extended. -type extendableProto interface { - Message - ExtensionRangeArray() []ExtensionRange - ExtensionMap() map[int32]Extension -} - -var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem() - -// 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 -} - -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 extendableProto, id int32, b []byte) { - base.ExtensionMap()[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 { - // Check the extended type. - if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b { - return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String()) - } - // 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 -} - -// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m. -func encodeExtensionMap(m map[int32]Extension) error { - for k, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - 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. - - et := reflect.TypeOf(e.desc.ExtensionType) - props := extensionProperties(e.desc) - - p := NewBuffer(nil) - // If e.value has type T, the encoder expects a *struct{ X T }. - // Pass a *T with a zero field and hope it all works out. - x := reflect.New(et) - x.Elem().Set(reflect.ValueOf(e.value)) - if err := props.enc(p, props, toStructPointer(x)); err != nil { - return err - } - e.enc = p.buf - m[k] = e - } - return nil -} - -func sizeExtensionMap(m map[int32]Extension) (n int) { - 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. - - et := reflect.TypeOf(e.desc.ExtensionType) - props := extensionProperties(e.desc) - - // If e.value has type T, the encoder expects a *struct{ X T }. - // Pass a *T with a zero field and hope it all works out. - x := reflect.New(et) - x.Elem().Set(reflect.ValueOf(e.value)) - n += props.size(props, toStructPointer(x)) - } - return -} - -// HasExtension returns whether the given extension is present in pb. -func HasExtension(pb extendableProto, extension *ExtensionDesc) bool { - // TODO: Check types, field numbers, etc.? - _, ok := pb.ExtensionMap()[extension.Field] - return ok -} - -// ClearExtension removes the given extension from pb. -func ClearExtension(pb extendableProto, extension *ExtensionDesc) { - // TODO: Check types, field numbers, etc.? - delete(pb.ExtensionMap(), extension.Field) -} - -// GetExtension parses and returns the given extension of pb. -// If the extension is not present and has no default value it returns ErrMissingExtension. -func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { - if err := checkExtensionTypes(pb, extension); err != nil { - return nil, err - } - - emap := pb.ExtensionMap() - 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 - } - - 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) { - 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) { - o := NewBuffer(b) - - t := reflect.TypeOf(extension.ExtensionType) - rep := extension.repeated() - - props := extensionProperties(extension) - - // t is a pointer to a struct, pointer to basic type or a slice. - // Allocate a "field" to store the pointer/slice itself; the - // pointer/slice will be stored here. We pass - // the address of this field to props.dec. - // This passes a zero field and a *t and lets props.dec - // interpret it as a *struct{ x t }. - value := reflect.New(t).Elem() - - for { - // Discard wire type and field number varint. It isn't needed. - if _, err := o.DecodeVarint(); err != nil { - return nil, err - } - - if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil { - return nil, err - } - - if !rep || o.index >= len(o.buf) { - 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, ok := pb.(extendableProto) - if !ok { - err = errors.New("proto: not an extendable proto") - return - } - 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 -} - -// SetExtension sets the specified extension of pb to the specified value. -func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error { - if err := checkExtensionTypes(pb, 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) - } - - pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} - return nil -} - -// 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/_third_party/github.com/golang/protobuf/proto/extensions_test.go b/_third_party/github.com/golang/protobuf/proto/extensions_test.go deleted file mode 100644 index 3df7f13c..00000000 --- a/_third_party/github.com/golang/protobuf/proto/extensions_test.go +++ /dev/null @@ -1,292 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2014 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_test - -import ( - "fmt" - "reflect" - "testing" - - "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" - pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/testdata" -) - -func TestGetExtensionsWithMissingExtensions(t *testing.T) { - msg := &pb.MyMessage{} - ext1 := &pb.Ext{} - if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { - t.Fatalf("Could not set ext1: %s", ext1) - } - exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{ - pb.E_Ext_More, - pb.E_Ext_Text, - }) - if err != nil { - t.Fatalf("GetExtensions() failed: %s", err) - } - if exts[0] != ext1 { - t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0]) - } - if exts[1] != nil { - t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1]) - } -} - -func TestGetExtensionStability(t *testing.T) { - check := func(m *pb.MyMessage) bool { - ext1, err := proto.GetExtension(m, pb.E_Ext_More) - if err != nil { - t.Fatalf("GetExtension() failed: %s", err) - } - ext2, err := proto.GetExtension(m, pb.E_Ext_More) - if err != nil { - t.Fatalf("GetExtension() failed: %s", err) - } - return ext1 == ext2 - } - msg := &pb.MyMessage{Count: proto.Int32(4)} - ext0 := &pb.Ext{} - if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil { - t.Fatalf("Could not set ext1: %s", ext0) - } - if !check(msg) { - t.Errorf("GetExtension() not stable before marshaling") - } - bb, err := proto.Marshal(msg) - if err != nil { - t.Fatalf("Marshal() failed: %s", err) - } - msg1 := &pb.MyMessage{} - err = proto.Unmarshal(bb, msg1) - if err != nil { - t.Fatalf("Unmarshal() failed: %s", err) - } - if !check(msg1) { - t.Errorf("GetExtension() not stable after unmarshaling") - } -} - -func TestGetExtensionDefaults(t *testing.T) { - var setFloat64 float64 = 1 - var setFloat32 float32 = 2 - var setInt32 int32 = 3 - var setInt64 int64 = 4 - var setUint32 uint32 = 5 - var setUint64 uint64 = 6 - var setBool = true - var setBool2 = false - var setString = "Goodnight string" - var setBytes = []byte("Goodnight bytes") - var setEnum = pb.DefaultsMessage_TWO - - type testcase struct { - ext *proto.ExtensionDesc // Extension we are testing. - want interface{} // Expected value of extension, or nil (meaning that GetExtension will fail). - def interface{} // Expected value of extension after ClearExtension(). - } - tests := []testcase{ - {pb.E_NoDefaultDouble, setFloat64, nil}, - {pb.E_NoDefaultFloat, setFloat32, nil}, - {pb.E_NoDefaultInt32, setInt32, nil}, - {pb.E_NoDefaultInt64, setInt64, nil}, - {pb.E_NoDefaultUint32, setUint32, nil}, - {pb.E_NoDefaultUint64, setUint64, nil}, - {pb.E_NoDefaultSint32, setInt32, nil}, - {pb.E_NoDefaultSint64, setInt64, nil}, - {pb.E_NoDefaultFixed32, setUint32, nil}, - {pb.E_NoDefaultFixed64, setUint64, nil}, - {pb.E_NoDefaultSfixed32, setInt32, nil}, - {pb.E_NoDefaultSfixed64, setInt64, nil}, - {pb.E_NoDefaultBool, setBool, nil}, - {pb.E_NoDefaultBool, setBool2, nil}, - {pb.E_NoDefaultString, setString, nil}, - {pb.E_NoDefaultBytes, setBytes, nil}, - {pb.E_NoDefaultEnum, setEnum, nil}, - {pb.E_DefaultDouble, setFloat64, float64(3.1415)}, - {pb.E_DefaultFloat, setFloat32, float32(3.14)}, - {pb.E_DefaultInt32, setInt32, int32(42)}, - {pb.E_DefaultInt64, setInt64, int64(43)}, - {pb.E_DefaultUint32, setUint32, uint32(44)}, - {pb.E_DefaultUint64, setUint64, uint64(45)}, - {pb.E_DefaultSint32, setInt32, int32(46)}, - {pb.E_DefaultSint64, setInt64, int64(47)}, - {pb.E_DefaultFixed32, setUint32, uint32(48)}, - {pb.E_DefaultFixed64, setUint64, uint64(49)}, - {pb.E_DefaultSfixed32, setInt32, int32(50)}, - {pb.E_DefaultSfixed64, setInt64, int64(51)}, - {pb.E_DefaultBool, setBool, true}, - {pb.E_DefaultBool, setBool2, true}, - {pb.E_DefaultString, setString, "Hello, string"}, - {pb.E_DefaultBytes, setBytes, []byte("Hello, bytes")}, - {pb.E_DefaultEnum, setEnum, pb.DefaultsMessage_ONE}, - } - - checkVal := func(test testcase, msg *pb.DefaultsMessage, valWant interface{}) error { - val, err := proto.GetExtension(msg, test.ext) - if err != nil { - if valWant != nil { - return fmt.Errorf("GetExtension(): %s", err) - } - if want := proto.ErrMissingExtension; err != want { - return fmt.Errorf("Unexpected error: got %v, want %v", err, want) - } - return nil - } - - // All proto2 extension values are either a pointer to a value or a slice of values. - ty := reflect.TypeOf(val) - tyWant := reflect.TypeOf(test.ext.ExtensionType) - if got, want := ty, tyWant; got != want { - return fmt.Errorf("unexpected reflect.TypeOf(): got %v want %v", got, want) - } - tye := ty.Elem() - tyeWant := tyWant.Elem() - if got, want := tye, tyeWant; got != want { - return fmt.Errorf("unexpected reflect.TypeOf().Elem(): got %v want %v", got, want) - } - - // Check the name of the type of the value. - // If it is an enum it will be type int32 with the name of the enum. - if got, want := tye.Name(), tye.Name(); got != want { - return fmt.Errorf("unexpected reflect.TypeOf().Elem().Name(): got %v want %v", got, want) - } - - // Check that value is what we expect. - // If we have a pointer in val, get the value it points to. - valExp := val - if ty.Kind() == reflect.Ptr { - valExp = reflect.ValueOf(val).Elem().Interface() - } - if got, want := valExp, valWant; !reflect.DeepEqual(got, want) { - return fmt.Errorf("unexpected reflect.DeepEqual(): got %v want %v", got, want) - } - - return nil - } - - setTo := func(test testcase) interface{} { - setTo := reflect.ValueOf(test.want) - if typ := reflect.TypeOf(test.ext.ExtensionType); typ.Kind() == reflect.Ptr { - setTo = reflect.New(typ).Elem() - setTo.Set(reflect.New(setTo.Type().Elem())) - setTo.Elem().Set(reflect.ValueOf(test.want)) - } - return setTo.Interface() - } - - for _, test := range tests { - msg := &pb.DefaultsMessage{} - name := test.ext.Name - - // Check the initial value. - if err := checkVal(test, msg, test.def); err != nil { - t.Errorf("%s: %v", name, err) - } - - // Set the per-type value and check value. - name = fmt.Sprintf("%s (set to %T %v)", name, test.want, test.want) - if err := proto.SetExtension(msg, test.ext, setTo(test)); err != nil { - t.Errorf("%s: SetExtension(): %v", name, err) - continue - } - if err := checkVal(test, msg, test.want); err != nil { - t.Errorf("%s: %v", name, err) - continue - } - - // Set and check the value. - name += " (cleared)" - proto.ClearExtension(msg, test.ext) - if err := checkVal(test, msg, test.def); err != nil { - t.Errorf("%s: %v", name, err) - } - } -} - -func TestExtensionsRoundTrip(t *testing.T) { - msg := &pb.MyMessage{} - ext1 := &pb.Ext{ - Data: proto.String("hi"), - } - ext2 := &pb.Ext{ - Data: proto.String("there"), - } - exists := proto.HasExtension(msg, pb.E_Ext_More) - if exists { - t.Error("Extension More present unexpectedly") - } - if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { - t.Error(err) - } - if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil { - t.Error(err) - } - e, err := proto.GetExtension(msg, pb.E_Ext_More) - if err != nil { - t.Error(err) - } - x, ok := e.(*pb.Ext) - if !ok { - t.Errorf("e has type %T, expected testdata.Ext", e) - } else if *x.Data != "there" { - t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x) - } - proto.ClearExtension(msg, pb.E_Ext_More) - if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension { - t.Errorf("got %v, expected ErrMissingExtension", e) - } - if _, err := proto.GetExtension(msg, pb.E_X215); err == nil { - t.Error("expected bad extension error, got nil") - } - if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil { - t.Error("expected extension err") - } - if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil { - t.Error("expected some sort of type mismatch error, got nil") - } -} - -func TestNilExtension(t *testing.T) { - msg := &pb.MyMessage{ - Count: proto.Int32(1), - } - if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil { - t.Fatal(err) - } - if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil { - t.Error("expected SetExtension to fail due to a nil extension") - } else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want { - t.Errorf("expected error %v, got %v", want, err) - } - // Note: if the behavior of Marshal is ever changed to ignore nil extensions, update - // this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal. -} diff --git a/_third_party/github.com/golang/protobuf/proto/lib.go b/_third_party/github.com/golang/protobuf/proto/lib.go deleted file mode 100644 index 0b28b086..00000000 --- a/_third_party/github.com/golang/protobuf/proto/lib.go +++ /dev/null @@ -1,813 +0,0 @@ -// 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. - - Marshal and Unmarshal are functions to encode and decode the wire format. - -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; - } - } - -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"` - XXX_unrecognized []byte `json:"-"` - } - func (m *Test) Reset() { *m = Test{} } - func (m *Test) String() string { return proto.CompactTextString(m) } - func (*Test) ProtoMessage() {} - 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 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), - Optionalgroup: &pb.Test_OptionalGroup{ - RequiredField: proto.String("good bye"), - }, - } - 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()) - } - // etc. - } -*/ -package proto - -import ( - "encoding/json" - "fmt" - "log" - "reflect" - "strconv" - "sync" -) - -// 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 // write point - - // pools of basic types to amortize allocation. - bools []bool - uint32s []uint32 - uint64s []uint64 - - // extra pools, only used with pointer_reflect.go - int32s []int32 - int64s []int64 - float32s []float32 - float64s []float64 -} - -// 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 } - -/* - * 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) - break - - 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: - if err != nil { - fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d start\n", index, tag) - depth++ - - case WireEndGroup: - depth-- - if err != nil { - fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err) - break out - } - 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 -} - -// Map fields may have key types of non-float scalars, strings and enums. -// The easiest way to sort them in some deterministic order is to use fmt. -// If this turns out to be inefficient we can always consider other options, -// such as doing a Schwartzian transform. - -type mapKeys []reflect.Value - -func (s mapKeys) Len() int { return len(s) } -func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s mapKeys) Less(i, j int) bool { - return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) -} - -// 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 -} diff --git a/_third_party/github.com/golang/protobuf/proto/message_set.go b/_third_party/github.com/golang/protobuf/proto/message_set.go deleted file mode 100644 index 9d912bce..00000000 --- a/_third_party/github.com/golang/protobuf/proto/message_set.go +++ /dev/null @@ -1,287 +0,0 @@ -// 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" -) - -// 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. -// -// When a proto1 proto has a field that looks like: -// optional message info = 3; -// the protocol compiler produces a field in the generated struct that looks like: -// Info *_proto_.MessageSet `protobuf:"bytes,3,opt,name=info"` -// The package is automatically inserted so there is no need for that proto file to -// import 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 { - if ms.find(pb) != nil { - return true - } - return false -} - -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(m map[int32]Extension) ([]byte, error) { - if err := encodeExtensionMap(m); err != nil { - return nil, err - } - - // Sort extension IDs to provide a deterministic encoding. - // See also enc_map in encode.go. - ids := make([]int, 0, len(m)) - for id := range m { - ids = append(ids, int(id)) - } - sort.Ints(ids) - - ms := &MessageSet{Item: make([]*_MessageSet_Item, 0, len(m))} - for _, id := range ids { - e := m[int32(id)] - // Remove the wire type and field number varint, as well as the length varint. - msg := skipVarint(skipVarint(e.enc)) - - ms.Item = append(ms.Item, &_MessageSet_Item{ - TypeId: Int32(int32(id)), - Message: msg, - }) - } - return Marshal(ms) -} - -// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. -// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error { - 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(m map[int32]Extension) ([]byte, error) { - 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] - if i > 0 { - b.WriteByte(',') - } - - msd, ok := messageSetMap[id] - if !ok { - // Unknown type; we can't render it, so skip it. - continue - } - 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, m map[int32]Extension) 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/_third_party/github.com/golang/protobuf/proto/message_set_test.go b/_third_party/github.com/golang/protobuf/proto/message_set_test.go deleted file mode 100644 index 7c29bccf..00000000 --- a/_third_party/github.com/golang/protobuf/proto/message_set_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2014 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 ( - "bytes" - "testing" -) - -func TestUnmarshalMessageSetWithDuplicate(t *testing.T) { - // Check that a repeated message set entry will be concatenated. - in := &MessageSet{ - Item: []*_MessageSet_Item{ - {TypeId: Int32(12345), Message: []byte("hoo")}, - {TypeId: Int32(12345), Message: []byte("hah")}, - }, - } - b, err := Marshal(in) - if err != nil { - t.Fatalf("Marshal: %v", err) - } - t.Logf("Marshaled bytes: %q", b) - - m := make(map[int32]Extension) - if err := UnmarshalMessageSet(b, m); err != nil { - t.Fatalf("UnmarshalMessageSet: %v", err) - } - ext, ok := m[12345] - if !ok { - t.Fatalf("Didn't retrieve extension 12345; map is %v", m) - } - // Skip wire type/field number and length varints. - got := skipVarint(skipVarint(ext.enc)) - if want := []byte("hoohah"); !bytes.Equal(got, want) { - t.Errorf("Combined extension is %q, want %q", got, want) - } -} diff --git a/_third_party/github.com/golang/protobuf/proto/pointer_reflect.go b/_third_party/github.com/golang/protobuf/proto/pointer_reflect.go deleted file mode 100644 index c68b1252..00000000 --- a/_third_party/github.com/golang/protobuf/proto/pointer_reflect.go +++ /dev/null @@ -1,479 +0,0 @@ -// 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 appengine - -// 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 ( - "math" - "reflect" -) - -// A structPointer is a pointer to a struct. -type structPointer struct { - v reflect.Value -} - -// toStructPointer returns a structPointer equivalent to the given reflect value. -// The reflect value must itself be a pointer to a struct. -func toStructPointer(v reflect.Value) structPointer { - return structPointer{v} -} - -// IsNil reports whether p is nil. -func structPointer_IsNil(p structPointer) bool { - return p.v.IsNil() -} - -// Interface returns the struct pointer as an interface value. -func structPointer_Interface(p structPointer, _ reflect.Type) interface{} { - return p.v.Interface() -} - -// A field identifies a field in a struct, accessible from a structPointer. -// 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) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { return f != nil } - -// field returns the given field in the struct as a reflect value. -func structPointer_field(p structPointer, f field) reflect.Value { - // Special case: an extension map entry with a value of type T - // passes a *T to the struct-handling code with a zero field, - // expecting that it will be treated as equivalent to *struct{ X T }, - // which has the same memory layout. We have to handle that case - // specially, because reflect will panic if we call FieldByIndex on a - // non-struct. - if f == nil { - return p.v.Elem() - } - - return p.v.Elem().FieldByIndex(f) -} - -// ifield returns the given field in the struct as an interface value. -func structPointer_ifield(p structPointer, f field) interface{} { - return structPointer_field(p, f).Addr().Interface() -} - -// Bytes returns the address of a []byte field in the struct. -func structPointer_Bytes(p structPointer, f field) *[]byte { - return structPointer_ifield(p, f).(*[]byte) -} - -// BytesSlice returns the address of a [][]byte field in the struct. -func structPointer_BytesSlice(p structPointer, f field) *[][]byte { - return structPointer_ifield(p, f).(*[][]byte) -} - -// Bool returns the address of a *bool field in the struct. -func structPointer_Bool(p structPointer, f field) **bool { - return structPointer_ifield(p, f).(**bool) -} - -// BoolVal returns the address of a bool field in the struct. -func structPointer_BoolVal(p structPointer, f field) *bool { - return structPointer_ifield(p, f).(*bool) -} - -// BoolSlice returns the address of a []bool field in the struct. -func structPointer_BoolSlice(p structPointer, f field) *[]bool { - return structPointer_ifield(p, f).(*[]bool) -} - -// String returns the address of a *string field in the struct. -func structPointer_String(p structPointer, f field) **string { - return structPointer_ifield(p, f).(**string) -} - -// StringVal returns the address of a string field in the struct. -func structPointer_StringVal(p structPointer, f field) *string { - return structPointer_ifield(p, f).(*string) -} - -// StringSlice returns the address of a []string field in the struct. -func structPointer_StringSlice(p structPointer, f field) *[]string { - return structPointer_ifield(p, f).(*[]string) -} - -// ExtMap returns the address of an extension map field in the struct. -func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { - return structPointer_ifield(p, f).(*map[int32]Extension) -} - -// Map returns the reflect.Value for the address of a map field in the struct. -func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value { - return structPointer_field(p, f).Addr() -} - -// SetStructPointer writes a *struct field in the struct. -func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { - structPointer_field(p, f).Set(q.v) -} - -// GetStructPointer reads a *struct field in the struct. -func structPointer_GetStructPointer(p structPointer, f field) structPointer { - return structPointer{structPointer_field(p, f)} -} - -// StructPointerSlice the address of a []*struct field in the struct. -func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice { - return structPointerSlice{structPointer_field(p, f)} -} - -// A structPointerSlice represents the address of a slice of pointers to structs -// (themselves messages or groups). That is, v.Type() is *[]*struct{...}. -type structPointerSlice struct { - v reflect.Value -} - -func (p structPointerSlice) Len() int { return p.v.Len() } -func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} } -func (p structPointerSlice) Append(q structPointer) { - p.v.Set(reflect.Append(p.v, q.v)) -} - -var ( - int32Type = reflect.TypeOf(int32(0)) - uint32Type = reflect.TypeOf(uint32(0)) - float32Type = reflect.TypeOf(float32(0)) - int64Type = reflect.TypeOf(int64(0)) - uint64Type = reflect.TypeOf(uint64(0)) - float64Type = reflect.TypeOf(float64(0)) -) - -// A word32 represents a field of type *int32, *uint32, *float32, or *enum. -// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable. -type word32 struct { - v reflect.Value -} - -// IsNil reports whether p is nil. -func word32_IsNil(p word32) bool { - return p.v.IsNil() -} - -// Set sets p to point at a newly allocated word with bits set to x. -func word32_Set(p word32, o *Buffer, x uint32) { - t := p.v.Type().Elem() - switch t { - case int32Type: - if len(o.int32s) == 0 { - o.int32s = make([]int32, uint32PoolSize) - } - o.int32s[0] = int32(x) - p.v.Set(reflect.ValueOf(&o.int32s[0])) - o.int32s = o.int32s[1:] - return - case uint32Type: - if len(o.uint32s) == 0 { - o.uint32s = make([]uint32, uint32PoolSize) - } - o.uint32s[0] = x - p.v.Set(reflect.ValueOf(&o.uint32s[0])) - o.uint32s = o.uint32s[1:] - return - case float32Type: - if len(o.float32s) == 0 { - o.float32s = make([]float32, uint32PoolSize) - } - o.float32s[0] = math.Float32frombits(x) - p.v.Set(reflect.ValueOf(&o.float32s[0])) - o.float32s = o.float32s[1:] - return - } - - // must be enum - p.v.Set(reflect.New(t)) - p.v.Elem().SetInt(int64(int32(x))) -} - -// Get gets the bits pointed at by p, as a uint32. -func word32_Get(p word32) uint32 { - elem := p.v.Elem() - switch elem.Kind() { - case reflect.Int32: - return uint32(elem.Int()) - case reflect.Uint32: - return uint32(elem.Uint()) - case reflect.Float32: - return math.Float32bits(float32(elem.Float())) - } - panic("unreachable") -} - -// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct. -func structPointer_Word32(p structPointer, f field) word32 { - return word32{structPointer_field(p, f)} -} - -// A word32Val represents a field of type int32, uint32, float32, or enum. -// That is, v.Type() is int32, uint32, float32, or enum and v is assignable. -type word32Val struct { - v reflect.Value -} - -// Set sets *p to x. -func word32Val_Set(p word32Val, x uint32) { - switch p.v.Type() { - case int32Type: - p.v.SetInt(int64(x)) - return - case uint32Type: - p.v.SetUint(uint64(x)) - return - case float32Type: - p.v.SetFloat(float64(math.Float32frombits(x))) - return - } - - // must be enum - p.v.SetInt(int64(int32(x))) -} - -// Get gets the bits pointed at by p, as a uint32. -func word32Val_Get(p word32Val) uint32 { - elem := p.v - switch elem.Kind() { - case reflect.Int32: - return uint32(elem.Int()) - case reflect.Uint32: - return uint32(elem.Uint()) - case reflect.Float32: - return math.Float32bits(float32(elem.Float())) - } - panic("unreachable") -} - -// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct. -func structPointer_Word32Val(p structPointer, f field) word32Val { - return word32Val{structPointer_field(p, f)} -} - -// A word32Slice is a slice of 32-bit values. -// That is, v.Type() is []int32, []uint32, []float32, or []enum. -type word32Slice struct { - v reflect.Value -} - -func (p word32Slice) Append(x uint32) { - n, m := p.v.Len(), p.v.Cap() - if n < m { - p.v.SetLen(n + 1) - } else { - t := p.v.Type().Elem() - p.v.Set(reflect.Append(p.v, reflect.Zero(t))) - } - elem := p.v.Index(n) - switch elem.Kind() { - case reflect.Int32: - elem.SetInt(int64(int32(x))) - case reflect.Uint32: - elem.SetUint(uint64(x)) - case reflect.Float32: - elem.SetFloat(float64(math.Float32frombits(x))) - } -} - -func (p word32Slice) Len() int { - return p.v.Len() -} - -func (p word32Slice) Index(i int) uint32 { - elem := p.v.Index(i) - switch elem.Kind() { - case reflect.Int32: - return uint32(elem.Int()) - case reflect.Uint32: - return uint32(elem.Uint()) - case reflect.Float32: - return math.Float32bits(float32(elem.Float())) - } - panic("unreachable") -} - -// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct. -func structPointer_Word32Slice(p structPointer, f field) word32Slice { - return word32Slice{structPointer_field(p, f)} -} - -// word64 is like word32 but for 64-bit values. -type word64 struct { - v reflect.Value -} - -func word64_Set(p word64, o *Buffer, x uint64) { - t := p.v.Type().Elem() - switch t { - case int64Type: - if len(o.int64s) == 0 { - o.int64s = make([]int64, uint64PoolSize) - } - o.int64s[0] = int64(x) - p.v.Set(reflect.ValueOf(&o.int64s[0])) - o.int64s = o.int64s[1:] - return - case uint64Type: - if len(o.uint64s) == 0 { - o.uint64s = make([]uint64, uint64PoolSize) - } - o.uint64s[0] = x - p.v.Set(reflect.ValueOf(&o.uint64s[0])) - o.uint64s = o.uint64s[1:] - return - case float64Type: - if len(o.float64s) == 0 { - o.float64s = make([]float64, uint64PoolSize) - } - o.float64s[0] = math.Float64frombits(x) - p.v.Set(reflect.ValueOf(&o.float64s[0])) - o.float64s = o.float64s[1:] - return - } - panic("unreachable") -} - -func word64_IsNil(p word64) bool { - return p.v.IsNil() -} - -func word64_Get(p word64) uint64 { - elem := p.v.Elem() - switch elem.Kind() { - case reflect.Int64: - return uint64(elem.Int()) - case reflect.Uint64: - return elem.Uint() - case reflect.Float64: - return math.Float64bits(elem.Float()) - } - panic("unreachable") -} - -func structPointer_Word64(p structPointer, f field) word64 { - return word64{structPointer_field(p, f)} -} - -// word64Val is like word32Val but for 64-bit values. -type word64Val struct { - v reflect.Value -} - -func word64Val_Set(p word64Val, o *Buffer, x uint64) { - switch p.v.Type() { - case int64Type: - p.v.SetInt(int64(x)) - return - case uint64Type: - p.v.SetUint(x) - return - case float64Type: - p.v.SetFloat(math.Float64frombits(x)) - return - } - panic("unreachable") -} - -func word64Val_Get(p word64Val) uint64 { - elem := p.v - switch elem.Kind() { - case reflect.Int64: - return uint64(elem.Int()) - case reflect.Uint64: - return elem.Uint() - case reflect.Float64: - return math.Float64bits(elem.Float()) - } - panic("unreachable") -} - -func structPointer_Word64Val(p structPointer, f field) word64Val { - return word64Val{structPointer_field(p, f)} -} - -type word64Slice struct { - v reflect.Value -} - -func (p word64Slice) Append(x uint64) { - n, m := p.v.Len(), p.v.Cap() - if n < m { - p.v.SetLen(n + 1) - } else { - t := p.v.Type().Elem() - p.v.Set(reflect.Append(p.v, reflect.Zero(t))) - } - elem := p.v.Index(n) - switch elem.Kind() { - case reflect.Int64: - elem.SetInt(int64(int64(x))) - case reflect.Uint64: - elem.SetUint(uint64(x)) - case reflect.Float64: - elem.SetFloat(float64(math.Float64frombits(x))) - } -} - -func (p word64Slice) Len() int { - return p.v.Len() -} - -func (p word64Slice) Index(i int) uint64 { - elem := p.v.Index(i) - switch elem.Kind() { - case reflect.Int64: - return uint64(elem.Int()) - case reflect.Uint64: - return uint64(elem.Uint()) - case reflect.Float64: - return math.Float64bits(float64(elem.Float())) - } - panic("unreachable") -} - -func structPointer_Word64Slice(p structPointer, f field) word64Slice { - return word64Slice{structPointer_field(p, f)} -} diff --git a/_third_party/github.com/golang/protobuf/proto/pointer_unsafe.go b/_third_party/github.com/golang/protobuf/proto/pointer_unsafe.go deleted file mode 100644 index 48bc0fa4..00000000 --- a/_third_party/github.com/golang/protobuf/proto/pointer_unsafe.go +++ /dev/null @@ -1,266 +0,0 @@ -// 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 !appengine - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "unsafe" -) - -// NOTE: These type_Foo functions would more idiomatically be methods, -// but Go does not allow methods on pointer types, and we must preserve -// some pointer type for the garbage collector. We use these -// funcs with clunky names as our poor approximation to methods. -// -// An alternative would be -// type structPointer struct { p unsafe.Pointer } -// but that does not registerize as well. - -// A structPointer is a pointer to a struct. -type structPointer unsafe.Pointer - -// toStructPointer returns a structPointer equivalent to the given reflect value. -func toStructPointer(v reflect.Value) structPointer { - return structPointer(unsafe.Pointer(v.Pointer())) -} - -// IsNil reports whether p is nil. -func structPointer_IsNil(p structPointer) bool { - return p == nil -} - -// Interface returns the struct pointer, assumed to have element type t, -// as an interface value. -func structPointer_Interface(p structPointer, t reflect.Type) interface{} { - return reflect.NewAt(t, unsafe.Pointer(p)).Interface() -} - -// A field identifies a field in a struct, accessible from a structPointer. -// 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) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { - return f != ^field(0) -} - -// Bytes returns the address of a []byte field in the struct. -func structPointer_Bytes(p structPointer, f field) *[]byte { - return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// BytesSlice returns the address of a [][]byte field in the struct. -func structPointer_BytesSlice(p structPointer, f field) *[][]byte { - return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// Bool returns the address of a *bool field in the struct. -func structPointer_Bool(p structPointer, f field) **bool { - return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// BoolVal returns the address of a bool field in the struct. -func structPointer_BoolVal(p structPointer, f field) *bool { - return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// BoolSlice returns the address of a []bool field in the struct. -func structPointer_BoolSlice(p structPointer, f field) *[]bool { - return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// String returns the address of a *string field in the struct. -func structPointer_String(p structPointer, f field) **string { - return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// StringVal returns the address of a string field in the struct. -func structPointer_StringVal(p structPointer, f field) *string { - return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// StringSlice returns the address of a []string field in the struct. -func structPointer_StringSlice(p structPointer, f field) *[]string { - return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// ExtMap returns the address of an extension map field in the struct. -func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { - return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// Map returns the reflect.Value for the address of a map field in the struct. -func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value { - return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f))) -} - -// SetStructPointer writes a *struct field in the struct. -func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { - *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q -} - -// GetStructPointer reads a *struct field in the struct. -func structPointer_GetStructPointer(p structPointer, f field) structPointer { - return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// StructPointerSlice the address of a []*struct field in the struct. -func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice { - return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups). -type structPointerSlice []structPointer - -func (v *structPointerSlice) Len() int { return len(*v) } -func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] } -func (v *structPointerSlice) Append(p structPointer) { *v = append(*v, p) } - -// A word32 is the address of a "pointer to 32-bit value" field. -type word32 **uint32 - -// IsNil reports whether *v is nil. -func word32_IsNil(p word32) bool { - return *p == nil -} - -// Set sets *v to point at a newly allocated word set to x. -func word32_Set(p word32, o *Buffer, x uint32) { - if len(o.uint32s) == 0 { - o.uint32s = make([]uint32, uint32PoolSize) - } - o.uint32s[0] = x - *p = &o.uint32s[0] - o.uint32s = o.uint32s[1:] -} - -// Get gets the value pointed at by *v. -func word32_Get(p word32) uint32 { - return **p -} - -// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct. -func structPointer_Word32(p structPointer, f field) word32 { - return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -// A word32Val is the address of a 32-bit value field. -type word32Val *uint32 - -// Set sets *p to x. -func word32Val_Set(p word32Val, x uint32) { - *p = x -} - -// Get gets the value pointed at by p. -func word32Val_Get(p word32Val) uint32 { - return *p -} - -// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct. -func structPointer_Word32Val(p structPointer, f field) word32Val { - return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -// A word32Slice is a slice of 32-bit values. -type word32Slice []uint32 - -func (v *word32Slice) Append(x uint32) { *v = append(*v, x) } -func (v *word32Slice) Len() int { return len(*v) } -func (v *word32Slice) Index(i int) uint32 { return (*v)[i] } - -// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct. -func structPointer_Word32Slice(p structPointer, f field) *word32Slice { - return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} - -// word64 is like word32 but for 64-bit values. -type word64 **uint64 - -func word64_Set(p word64, o *Buffer, x uint64) { - if len(o.uint64s) == 0 { - o.uint64s = make([]uint64, uint64PoolSize) - } - o.uint64s[0] = x - *p = &o.uint64s[0] - o.uint64s = o.uint64s[1:] -} - -func word64_IsNil(p word64) bool { - return *p == nil -} - -func word64_Get(p word64) uint64 { - return **p -} - -func structPointer_Word64(p structPointer, f field) word64 { - return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -// word64Val is like word32Val but for 64-bit values. -type word64Val *uint64 - -func word64Val_Set(p word64Val, o *Buffer, x uint64) { - *p = x -} - -func word64Val_Get(p word64Val) uint64 { - return *p -} - -func structPointer_Word64Val(p structPointer, f field) word64Val { - return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) -} - -// word64Slice is like word32Slice but for 64-bit values. -type word64Slice []uint64 - -func (v *word64Slice) Append(x uint64) { *v = append(*v, x) } -func (v *word64Slice) Len() int { return len(*v) } -func (v *word64Slice) Index(i int) uint64 { return (*v)[i] } - -func structPointer_Word64Slice(p structPointer, f field) *word64Slice { - return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) -} diff --git a/_third_party/github.com/golang/protobuf/proto/properties.go b/_third_party/github.com/golang/protobuf/proto/properties.go deleted file mode 100644 index d74844ab..00000000 --- a/_third_party/github.com/golang/protobuf/proto/properties.go +++ /dev/null @@ -1,742 +0,0 @@ -// 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" - "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 -) - -const startSize = 10 // initial slice/string sizes - -// Encoders are defined in encode.go -// An encoder outputs the full representation of a field, including its -// tag and encoder type. -type encoder func(p *Buffer, prop *Properties, base structPointer) error - -// A valueEncoder encodes a single integer in a particular encoding. -type valueEncoder func(o *Buffer, x uint64) error - -// Sizers are defined in encode.go -// A sizer returns the encoded size of a field, including its tag and encoder -// type. -type sizer func(prop *Properties, base structPointer) int - -// A valueSizer returns the encoded size of a single integer in a particular -// encoding. -type valueSizer func(x uint64) int - -// Decoders are defined in decode.go -// A decoder creates a value from its wire representation. -// Unrecognized subelements are saved in unrec. -type decoder func(p *Buffer, prop *Properties, base structPointer) error - -// A valueDecoder decodes a single integer in a particular encoding. -type valueDecoder func(o *Buffer) (x uint64, err error) - -// 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 - unrecField field // field id of the XXX_unrecognized []byte field - extendable bool // is this an extendable proto -} - -// 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) - 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; set for []byte only - - Default string // default value - HasDefault bool // whether an explicit default was provided - def_uint64 uint64 - - enc encoder - valEnc valueEncoder // set for bool and numeric types only - field field - tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType) - tagbuf [8]byte - stype reflect.Type // set for struct types only - sprop *StructProperties // set for struct types only - isMarshaler bool - isUnmarshaler bool - - mtype reflect.Type // set for map types only - mkeyprop *Properties // set for map types only - mvalprop *Properties // set for map types only - - size sizer - valSize valueSizer // set for bool and numeric types only - - dec decoder - valDec valueDecoder // set for bool and numeric types only - - // If this is a packable field, this will be the decoder for the packed version of the field. - packedDec decoder -} - -// 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" - } - if p.OrigName != p.Name { - s += ",name=" + p.OrigName - } - if p.proto3 { - s += ",proto3" - } - 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 - p.valEnc = (*Buffer).EncodeVarint - p.valDec = (*Buffer).DecodeVarint - p.valSize = sizeVarint - case "fixed32": - p.WireType = WireFixed32 - p.valEnc = (*Buffer).EncodeFixed32 - p.valDec = (*Buffer).DecodeFixed32 - p.valSize = sizeFixed32 - case "fixed64": - p.WireType = WireFixed64 - p.valEnc = (*Buffer).EncodeFixed64 - p.valDec = (*Buffer).DecodeFixed64 - p.valSize = sizeFixed64 - case "zigzag32": - p.WireType = WireVarint - p.valEnc = (*Buffer).EncodeZigzag32 - p.valDec = (*Buffer).DecodeZigzag32 - p.valSize = sizeZigzag32 - case "zigzag64": - p.WireType = WireVarint - p.valEnc = (*Buffer).EncodeZigzag64 - p.valDec = (*Buffer).DecodeZigzag64 - p.valSize = sizeZigzag64 - 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 - } - - 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, "enum="): - p.Enum = f[5:] - case f == "proto3": - p.proto3 = 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 - } - } - } -} - -func logNoSliceEnc(t1, t2 reflect.Type) { - fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2) -} - -var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() - -// Initialize the fields for encoding and decoding. -func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { - p.enc = nil - p.dec = nil - p.size = nil - - switch t1 := typ; t1.Kind() { - default: - fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1) - - // proto3 scalar types - - case reflect.Bool: - p.enc = (*Buffer).enc_proto3_bool - p.dec = (*Buffer).dec_proto3_bool - p.size = size_proto3_bool - case reflect.Int32: - p.enc = (*Buffer).enc_proto3_int32 - p.dec = (*Buffer).dec_proto3_int32 - p.size = size_proto3_int32 - case reflect.Uint32: - p.enc = (*Buffer).enc_proto3_uint32 - p.dec = (*Buffer).dec_proto3_int32 // can reuse - p.size = size_proto3_uint32 - case reflect.Int64, reflect.Uint64: - p.enc = (*Buffer).enc_proto3_int64 - p.dec = (*Buffer).dec_proto3_int64 - p.size = size_proto3_int64 - case reflect.Float32: - p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits - p.dec = (*Buffer).dec_proto3_int32 - p.size = size_proto3_uint32 - case reflect.Float64: - p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits - p.dec = (*Buffer).dec_proto3_int64 - p.size = size_proto3_int64 - case reflect.String: - p.enc = (*Buffer).enc_proto3_string - p.dec = (*Buffer).dec_proto3_string - p.size = size_proto3_string - - case reflect.Ptr: - switch t2 := t1.Elem(); t2.Kind() { - default: - fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2) - break - case reflect.Bool: - p.enc = (*Buffer).enc_bool - p.dec = (*Buffer).dec_bool - p.size = size_bool - case reflect.Int32: - p.enc = (*Buffer).enc_int32 - p.dec = (*Buffer).dec_int32 - p.size = size_int32 - case reflect.Uint32: - p.enc = (*Buffer).enc_uint32 - p.dec = (*Buffer).dec_int32 // can reuse - p.size = size_uint32 - case reflect.Int64, reflect.Uint64: - p.enc = (*Buffer).enc_int64 - p.dec = (*Buffer).dec_int64 - p.size = size_int64 - case reflect.Float32: - p.enc = (*Buffer).enc_uint32 // can just treat them as bits - p.dec = (*Buffer).dec_int32 - p.size = size_uint32 - case reflect.Float64: - p.enc = (*Buffer).enc_int64 // can just treat them as bits - p.dec = (*Buffer).dec_int64 - p.size = size_int64 - case reflect.String: - p.enc = (*Buffer).enc_string - p.dec = (*Buffer).dec_string - p.size = size_string - case reflect.Struct: - p.stype = t1.Elem() - p.isMarshaler = isMarshaler(t1) - p.isUnmarshaler = isUnmarshaler(t1) - if p.Wire == "bytes" { - p.enc = (*Buffer).enc_struct_message - p.dec = (*Buffer).dec_struct_message - p.size = size_struct_message - } else { - p.enc = (*Buffer).enc_struct_group - p.dec = (*Buffer).dec_struct_group - p.size = size_struct_group - } - } - - case reflect.Slice: - switch t2 := t1.Elem(); t2.Kind() { - default: - logNoSliceEnc(t1, t2) - break - case reflect.Bool: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_bool - p.size = size_slice_packed_bool - } else { - p.enc = (*Buffer).enc_slice_bool - p.size = size_slice_bool - } - p.dec = (*Buffer).dec_slice_bool - p.packedDec = (*Buffer).dec_slice_packed_bool - case reflect.Int32: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int32 - p.size = size_slice_packed_int32 - } else { - p.enc = (*Buffer).enc_slice_int32 - p.size = size_slice_int32 - } - p.dec = (*Buffer).dec_slice_int32 - p.packedDec = (*Buffer).dec_slice_packed_int32 - case reflect.Uint32: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_uint32 - p.size = size_slice_packed_uint32 - } else { - p.enc = (*Buffer).enc_slice_uint32 - p.size = size_slice_uint32 - } - p.dec = (*Buffer).dec_slice_int32 - p.packedDec = (*Buffer).dec_slice_packed_int32 - case reflect.Int64, reflect.Uint64: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int64 - p.size = size_slice_packed_int64 - } else { - p.enc = (*Buffer).enc_slice_int64 - p.size = size_slice_int64 - } - p.dec = (*Buffer).dec_slice_int64 - p.packedDec = (*Buffer).dec_slice_packed_int64 - case reflect.Uint8: - p.enc = (*Buffer).enc_slice_byte - p.dec = (*Buffer).dec_slice_byte - p.size = size_slice_byte - // This is a []byte, which is either a bytes field, - // or the value of a map field. In the latter case, - // we always encode an empty []byte, so we should not - // use the proto3 enc/size funcs. - // f == nil iff this is the key/value of a map field. - if p.proto3 && f != nil { - p.enc = (*Buffer).enc_proto3_slice_byte - p.size = size_proto3_slice_byte - } - case reflect.Float32, reflect.Float64: - switch t2.Bits() { - case 32: - // can just treat them as bits - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_uint32 - p.size = size_slice_packed_uint32 - } else { - p.enc = (*Buffer).enc_slice_uint32 - p.size = size_slice_uint32 - } - p.dec = (*Buffer).dec_slice_int32 - p.packedDec = (*Buffer).dec_slice_packed_int32 - case 64: - // can just treat them as bits - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int64 - p.size = size_slice_packed_int64 - } else { - p.enc = (*Buffer).enc_slice_int64 - p.size = size_slice_int64 - } - p.dec = (*Buffer).dec_slice_int64 - p.packedDec = (*Buffer).dec_slice_packed_int64 - default: - logNoSliceEnc(t1, t2) - break - } - case reflect.String: - p.enc = (*Buffer).enc_slice_string - p.dec = (*Buffer).dec_slice_string - p.size = size_slice_string - case reflect.Ptr: - switch t3 := t2.Elem(); t3.Kind() { - default: - fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3) - break - case reflect.Struct: - p.stype = t2.Elem() - p.isMarshaler = isMarshaler(t2) - p.isUnmarshaler = isUnmarshaler(t2) - if p.Wire == "bytes" { - p.enc = (*Buffer).enc_slice_struct_message - p.dec = (*Buffer).dec_slice_struct_message - p.size = size_slice_struct_message - } else { - p.enc = (*Buffer).enc_slice_struct_group - p.dec = (*Buffer).dec_slice_struct_group - p.size = size_slice_struct_group - } - } - case reflect.Slice: - switch t2.Elem().Kind() { - default: - fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem()) - break - case reflect.Uint8: - p.enc = (*Buffer).enc_slice_slice_byte - p.dec = (*Buffer).dec_slice_slice_byte - p.size = size_slice_slice_byte - } - } - - case reflect.Map: - p.enc = (*Buffer).enc_new_map - p.dec = (*Buffer).dec_new_map - p.size = size_new_map - - p.mtype = t1 - p.mkeyprop = &Properties{} - p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) - p.mvalprop = &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.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) - } - - // precalculate tag code - wire := p.WireType - if p.Packed { - wire = WireBytes - } - x := uint32(p.Tag)<<3 | uint32(wire) - i := 0 - for i = 0; x > 127; i++ { - p.tagbuf[i] = 0x80 | uint8(x&0x7F) - x >>= 7 - } - p.tagbuf[i] = uint8(x) - p.tagcode = p.tagbuf[0 : i+1] - - if p.stype != nil { - if lockGetProp { - p.sprop = GetProperties(p.stype) - } else { - p.sprop = getPropertiesLocked(p.stype) - } - } -} - -var ( - marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() - unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() -) - -// isMarshaler reports whether type t implements Marshaler. -func isMarshaler(t reflect.Type) bool { - // We're checking for (likely) pointer-receiver methods - // so if t is not a pointer, something is very wrong. - // The calls above only invoke isMarshaler on pointer types. - if t.Kind() != reflect.Ptr { - panic("proto: misuse of isMarshaler") - } - return t.Implements(marshalerType) -} - -// isUnmarshaler reports whether type t implements Unmarshaler. -func isUnmarshaler(t reflect.Type) bool { - // We're checking for (likely) pointer-receiver methods - // so if t is not a pointer, something is very wrong. - // The calls above only invoke isUnmarshaler on pointer types. - if t.Kind() != reflect.Ptr { - panic("proto: misuse of isUnmarshaler") - } - return t.Implements(unmarshalerType) -} - -// 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 f != nil { - p.field = toField(f) - } - if tag == "" { - return - } - p.Parse(tag) - p.setEncAndDec(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.extendable = reflect.PtrTo(t).Implements(extendableProtoType) - prop.unrecField = invalidField - 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) - - if f.Name == "XXX_extensions" { // special case - p.enc = (*Buffer).enc_map - p.dec = nil // not needed - p.size = size_map - } - if f.Name == "XXX_unrecognized" { // special case - prop.unrecField = toField(&f) - } - 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") - } - if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") { - fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") - } - } - - // Re-order prop.order. - sort.Sort(prop) - - // 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 -} - -// Return the Properties object for the x[0]'th field of the structure. -func propByIndex(t reflect.Type, x []int) *Properties { - if len(x) != 1 { - fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t) - return nil - } - prop := GetProperties(t) - return prop.Prop[x[0]] -} - -// Get the address and type of a pointer to a struct from an interface. -func getbase(pb Message) (t reflect.Type, b structPointer, err error) { - if pb == nil { - err = ErrNil - return - } - // get the reflect type of the pointer to the struct. - t = reflect.TypeOf(pb) - // get the address of the struct. - value := reflect.ValueOf(pb) - b = toStructPointer(value) - return -} - -// 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 -} diff --git a/_third_party/github.com/golang/protobuf/proto/proto3_test.go b/_third_party/github.com/golang/protobuf/proto/proto3_test.go deleted file mode 100644 index 393d5550..00000000 --- a/_third_party/github.com/golang/protobuf/proto/proto3_test.go +++ /dev/null @@ -1,125 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2014 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_test - -import ( - "testing" - - "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" - pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/proto3_proto" - tpb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/testdata" -) - -func TestProto3ZeroValues(t *testing.T) { - tests := []struct { - desc string - m proto.Message - }{ - {"zero message", &pb.Message{}}, - {"empty bytes field", &pb.Message{Data: []byte{}}}, - } - for _, test := range tests { - b, err := proto.Marshal(test.m) - if err != nil { - t.Errorf("%s: proto.Marshal: %v", test.desc, err) - continue - } - if len(b) > 0 { - t.Errorf("%s: Encoding is non-empty: %q", test.desc, b) - } - } -} - -func TestRoundTripProto3(t *testing.T) { - m := &pb.Message{ - Name: "David", // (2 | 1<<3): 0x0a 0x05 "David" - Hilarity: pb.Message_PUNS, // (0 | 2<<3): 0x10 0x01 - HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01 - Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto" - ResultCount: 47, // (0 | 7<<3): 0x38 0x2f - TrueScotsman: true, // (0 | 8<<3): 0x40 0x01 - Score: 8.1, // (5 | 9<<3): 0x4d <8.1> - - Key: []uint64{1, 0xdeadbeef}, - Nested: &pb.Nested{ - Bunny: "Monty", - }, - } - t.Logf(" m: %v", m) - - b, err := proto.Marshal(m) - if err != nil { - t.Fatalf("proto.Marshal: %v", err) - } - t.Logf(" b: %q", b) - - m2 := new(pb.Message) - if err := proto.Unmarshal(b, m2); err != nil { - t.Fatalf("proto.Unmarshal: %v", err) - } - t.Logf("m2: %v", m2) - - if !proto.Equal(m, m2) { - t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2) - } -} - -func TestProto3SetDefaults(t *testing.T) { - in := &pb.Message{ - Terrain: map[string]*pb.Nested{ - "meadow": new(pb.Nested), - }, - Proto2Field: new(tpb.SubDefaults), - Proto2Value: map[string]*tpb.SubDefaults{ - "badlands": new(tpb.SubDefaults), - }, - } - - got := proto.Clone(in).(*pb.Message) - proto.SetDefaults(got) - - // There are no defaults in proto3. Everything should be the zero value, but - // we need to remember to set defaults for nested proto2 messages. - want := &pb.Message{ - Terrain: map[string]*pb.Nested{ - "meadow": new(pb.Nested), - }, - Proto2Field: &tpb.SubDefaults{N: proto.Int64(7)}, - Proto2Value: map[string]*tpb.SubDefaults{ - "badlands": &tpb.SubDefaults{N: proto.Int64(7)}, - }, - } - - if !proto.Equal(got, want) { - t.Errorf("with in = %v\nproto.SetDefaults(in) =>\ngot %v\nwant %v", in, got, want) - } -} diff --git a/_third_party/github.com/golang/protobuf/proto/size2_test.go b/_third_party/github.com/golang/protobuf/proto/size2_test.go deleted file mode 100644 index a2729c39..00000000 --- a/_third_party/github.com/golang/protobuf/proto/size2_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// 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. - -package proto - -import ( - "testing" -) - -// This is a separate file and package from size_test.go because that one uses -// generated messages and thus may not be in package proto without having a circular -// dependency, whereas this file tests unexported details of size.go. - -func TestVarintSize(t *testing.T) { - // Check the edge cases carefully. - testCases := []struct { - n uint64 - size int - }{ - {0, 1}, - {1, 1}, - {127, 1}, - {128, 2}, - {16383, 2}, - {16384, 3}, - {1<<63 - 1, 9}, - {1 << 63, 10}, - } - for _, tc := range testCases { - size := sizeVarint(tc.n) - if size != tc.size { - t.Errorf("sizeVarint(%d) = %d, want %d", tc.n, size, tc.size) - } - } -} diff --git a/_third_party/github.com/golang/protobuf/proto/size_test.go b/_third_party/github.com/golang/protobuf/proto/size_test.go deleted file mode 100644 index 6e8de01d..00000000 --- a/_third_party/github.com/golang/protobuf/proto/size_test.go +++ /dev/null @@ -1,142 +0,0 @@ -// 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. - -package proto_test - -import ( - "log" - "strings" - "testing" - - . "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" - proto3pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/proto3_proto" - pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/testdata" -) - -var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)} - -// messageWithExtension2 is in equal_test.go. -var messageWithExtension3 = &pb.MyMessage{Count: Int32(8)} - -func init() { - if err := SetExtension(messageWithExtension1, pb.E_Ext_More, &pb.Ext{Data: String("Abbott")}); err != nil { - log.Panicf("SetExtension: %v", err) - } - if err := SetExtension(messageWithExtension3, pb.E_Ext_More, &pb.Ext{Data: String("Costello")}); err != nil { - log.Panicf("SetExtension: %v", err) - } - - // Force messageWithExtension3 to have the extension encoded. - Marshal(messageWithExtension3) - -} - -var SizeTests = []struct { - desc string - pb Message -}{ - {"empty", &pb.OtherMessage{}}, - // Basic types. - {"bool", &pb.Defaults{F_Bool: Bool(true)}}, - {"int32", &pb.Defaults{F_Int32: Int32(12)}}, - {"negative int32", &pb.Defaults{F_Int32: Int32(-1)}}, - {"small int64", &pb.Defaults{F_Int64: Int64(1)}}, - {"big int64", &pb.Defaults{F_Int64: Int64(1 << 20)}}, - {"negative int64", &pb.Defaults{F_Int64: Int64(-1)}}, - {"fixed32", &pb.Defaults{F_Fixed32: Uint32(71)}}, - {"fixed64", &pb.Defaults{F_Fixed64: Uint64(72)}}, - {"uint32", &pb.Defaults{F_Uint32: Uint32(123)}}, - {"uint64", &pb.Defaults{F_Uint64: Uint64(124)}}, - {"float", &pb.Defaults{F_Float: Float32(12.6)}}, - {"double", &pb.Defaults{F_Double: Float64(13.9)}}, - {"string", &pb.Defaults{F_String: String("niles")}}, - {"bytes", &pb.Defaults{F_Bytes: []byte("wowsa")}}, - {"bytes, empty", &pb.Defaults{F_Bytes: []byte{}}}, - {"sint32", &pb.Defaults{F_Sint32: Int32(65)}}, - {"sint64", &pb.Defaults{F_Sint64: Int64(67)}}, - {"enum", &pb.Defaults{F_Enum: pb.Defaults_BLUE.Enum()}}, - // Repeated. - {"empty repeated bool", &pb.MoreRepeated{Bools: []bool{}}}, - {"repeated bool", &pb.MoreRepeated{Bools: []bool{false, true, true, false}}}, - {"packed repeated bool", &pb.MoreRepeated{BoolsPacked: []bool{false, true, true, false, true, true, true}}}, - {"repeated int32", &pb.MoreRepeated{Ints: []int32{1, 12203, 1729, -1}}}, - {"repeated int32 packed", &pb.MoreRepeated{IntsPacked: []int32{1, 12203, 1729}}}, - {"repeated int64 packed", &pb.MoreRepeated{Int64SPacked: []int64{ - // Need enough large numbers to verify that the header is counting the number of bytes - // for the field, not the number of elements. - 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, - 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, - }}}, - {"repeated string", &pb.MoreRepeated{Strings: []string{"r", "ken", "gri"}}}, - {"repeated fixed", &pb.MoreRepeated{Fixeds: []uint32{1, 2, 3, 4}}}, - // Nested. - {"nested", &pb.OldMessage{Nested: &pb.OldMessage_Nested{Name: String("whatever")}}}, - {"group", &pb.GroupOld{G: &pb.GroupOld_G{X: Int32(12345)}}}, - // Other things. - {"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}}, - {"extension (unencoded)", messageWithExtension1}, - {"extension (encoded)", messageWithExtension3}, - // proto3 message - {"proto3 empty", &proto3pb.Message{}}, - {"proto3 bool", &proto3pb.Message{TrueScotsman: true}}, - {"proto3 int64", &proto3pb.Message{ResultCount: 1}}, - {"proto3 uint32", &proto3pb.Message{HeightInCm: 123}}, - {"proto3 float", &proto3pb.Message{Score: 12.6}}, - {"proto3 string", &proto3pb.Message{Name: "Snezana"}}, - {"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}}, - {"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}}, - {"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}}, - {"proto3 map field with empty bytes", &proto3pb.MessageWithMap{ByteMapping: map[bool][]byte{false: []byte{}}}}, - - {"map field", &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}}, - {"map field with message", &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{0x7001: &pb.FloatingPoint{F: Float64(2.0)}}}}, - {"map field with bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}}, - {"map field with empty bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte{}}}}, - - {"map field with big entry", &pb.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}}, - {"map field with big key and val", &pb.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}}, - {"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}}, -} - -func TestSize(t *testing.T) { - for _, tc := range SizeTests { - size := Size(tc.pb) - b, err := Marshal(tc.pb) - if err != nil { - t.Errorf("%v: Marshal failed: %v", tc.desc, err) - continue - } - if size != len(b) { - t.Errorf("%v: Size(%v) = %d, want %d", tc.desc, tc.pb, size, len(b)) - t.Logf("%v: bytes: %#v", tc.desc, b) - } - } -} diff --git a/_third_party/github.com/golang/protobuf/proto/text.go b/_third_party/github.com/golang/protobuf/proto/text.go deleted file mode 100644 index f7dc58a3..00000000 --- a/_third_party/github.com/golang/protobuf/proto/text.go +++ /dev/null @@ -1,769 +0,0 @@ -// 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" - "fmt" - "io" - "log" - "math" - "reflect" - "sort" - "strings" -) - -var ( - newline = []byte("\n") - spaces = []byte(" ") - gtNewline = []byte(">\n") - 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.Printf("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 -} - -var ( - messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem() -) - -// raw is the interface satisfied by RawMessage. -type raw interface { - Bytes() []byte -} - -func writeStruct(w *textWriter, sv reflect.Value) error { - if sv.Type() == messageSetType { - return writeMessageSet(w, sv.Addr().Interface().(*MessageSet)) - } - - 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 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 := 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() // TODO: should we sort these for deterministic output? - 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 := writeAny(w, key, props.mkeyprop); 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 := writeAny(w, val, props.mvalprop); 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 err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if b, ok := fv.Interface().(raw); ok { - if err := writeRaw(w, b.Bytes()); err != nil { - return err - } - continue - } - - // Enums have a String method, so writeAny will work fine. - if err := 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 pv.Type().Implements(extendableProtoType) { - if err := writeExtensions(w, pv); err != nil { - return err - } - } - - return nil -} - -// writeRaw writes an uninterpreted raw message. -func writeRaw(w *textWriter, b []byte) error { - if err := w.WriteByte('<'); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - if err := writeUnknownStruct(w, b); err != nil { - return err - } - w.unindent() - if err := w.WriteByte('>'); err != nil { - return err - } - return nil -} - -// writeAny writes an arbitrary field. -func 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.Interface().([]byte))); 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 tm, ok := v.Interface().(encoding.TextMarshaler); ok { - text, err := tm.MarshalText() - if err != nil { - return err - } - if _, err = w.Write(text); err != nil { - return err - } - } else if err := 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 writeMessageSet(w *textWriter, ms *MessageSet) error { - for _, item := range ms.Item { - id := *item.TypeId - if msd, ok := messageSetMap[id]; ok { - // Known message set type. - if _, err := fmt.Fprintf(w, "[%s]: <\n", msd.name); err != nil { - return err - } - w.indent() - - pb := reflect.New(msd.t.Elem()) - if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil { - if _, err := fmt.Fprintf(w, "/* bad message: %v */\n", err); err != nil { - return err - } - } else { - if err := writeStruct(w, pb.Elem()); err != nil { - return err - } - } - } else { - // Unknown type. - if _, err := fmt.Fprintf(w, "[%d]: <\n", id); err != nil { - return err - } - w.indent() - if err := writeUnknownStruct(w, item.Message); err != nil { - return err - } - } - w.unindent() - if _, err := w.Write(gtNewline); err != nil { - return err - } - } - return nil -} - -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 writeExtensions(w *textWriter, pv reflect.Value) error { - emap := extensionMaps[pv.Type().Elem()] - ep := pv.Interface().(extendableProto) - - // Order the extensions by ID. - // This isn't strictly necessary, but it will give us - // canonical output, which will also make testing easier. - m := ep.ExtensionMap() - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) - - 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 := writeExtension(w, desc.Name, pb); err != nil { - return err - } - } else { - v := reflect.ValueOf(pb) - for i := 0; i < v.Len(); i++ { - if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { - return err - } - } - } - } - return nil -} - -func 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 := 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 -} - -func marshalText(w io.Writer, pb Message, compact bool) 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: compact, - } - - if tm, ok := pb.(encoding.TextMarshaler); ok { - text, err := tm.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 := writeStruct(aw, v); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil -} - -// 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 marshalText(w, pb, false) -} - -// MarshalTextString is the same as MarshalText, but returns the string directly. -func MarshalTextString(pb Message) string { - var buf bytes.Buffer - marshalText(&buf, pb, false) - return buf.String() -} - -// CompactText writes a given protocol buffer in compact text format (one line). -func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) } - -// CompactTextString is the same as CompactText, but returns the string directly. -func CompactTextString(pb Message) string { - var buf bytes.Buffer - marshalText(&buf, pb, true) - return buf.String() -} diff --git a/_third_party/github.com/golang/protobuf/proto/text_parser.go b/_third_party/github.com/golang/protobuf/proto/text_parser.go deleted file mode 100644 index 7d0c7571..00000000 --- a/_third_party/github.com/golang/protobuf/proto/text_parser.go +++ /dev/null @@ -1,772 +0,0 @@ -// 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" -) - -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 (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") - errBadHex = errors.New("proto: bad hexadecimal") -) - -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', 'x', 'X': - if len(s) < 2 { - return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) - } - base := 8 - ss := s[:2] - s = s[2:] - if r == 'x' || r == 'X' { - base = 16 - } else { - ss = string(r) + ss - } - i, err := strconv.ParseUint(ss, base, 8) - if err != nil { - return "", "", err - } - return string([]byte{byte(i)}), s, nil - case 'u', 'U': - n := 4 - if r == 'U' { - n = 8 - } - if len(s) < n { - return "", "", fmt.Errorf(`\%c requires %d digits`, r, n) - } - - bs := make([]byte, n/2) - for i := 0; i < n; i += 2 { - a, ok1 := unhex(s[i]) - b, ok2 := unhex(s[i+1]) - if !ok1 || !ok2 { - return "", "", errBadHex - } - bs[i/2] = a<<4 | b - } - s = s[n:] - return string(bs), s, nil - } - return "", "", fmt.Errorf(`unknown escape \%c`, r) -} - -// Adapted from src/pkg/strconv/quote.go. -func unhex(b byte) (v byte, ok bool) { - switch { - case '0' <= b && b <= '9': - return b - '0', true - case 'a' <= b && b <= 'f': - return b - 'a' + 10, true - case 'A' <= b && b <= 'F': - return b - 'A' + 10, true - } - return 0, false -} - -// 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 && p.cur.value[0] == '"' { - // Look for multiple quoted strings separated by whitespace, - // and concatenate them. - cat := p.cur - for { - p.skipWhitespace() - if p.done || 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(st reflect.Type, name string) (int, *Properties, bool) { - sprops := GetProperties(st) - 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() - reqCount := GetProperties(st).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]". - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - if tok.value == "[" { - // Looks like an extension. - // - // TODO: Check whether we need to handle - // namespace rooted names (e.g. ".something.Foo"). - tok = p.next() - if tok.err != nil { - return tok.err - } - 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 == tok.value { - desc = d - break - } - } - if desc == nil { - return p.errorf("unrecognized extension %q", tok.value) - } - // Check the extension terminator. - tok = p.next() - if tok.err != nil { - return tok.err - } - if tok.value != "]" { - return p.errorf("unrecognized extension terminator %q", tok.value) - } - - 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().(extendableProto) - 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()) - } - } else { - // This is a normal, non-extension field. - name := tok.value - fi, props, ok := structFieldByName(st, name) - if !ok { - return p.errorf("unknown field name %q in %v", name, st) - } - - dst := sv.Field(fi) - - 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 > - // Technically the "key" and "value" could come in any order, - // but in practice they won't. - - tok := p.next() - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - if err := p.consumeToken("key"); err != nil { - return err - } - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.mkeyprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - if err := p.consumeToken("value"); err != nil { - return err - } - if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { - return err - } - if err := p.readAny(val, props.mvalprop); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - if err := p.consumeToken(terminator); err != nil { - return err - } - - 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, st.Field(fi).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 - } else if props.Required { - reqCount-- - } - } - - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - - } - - if reqCount > 0 { - return p.missingRequiredFieldError(sv) - } - return reqFieldErr -} - -// 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. May already exist. - flen := fv.Len() - if flen == fv.Cap() { - nav := reflect.MakeSlice(at, flen, 2*flen+1) - reflect.Copy(nav, fv) - fv.Set(nav) - } - fv.SetLen(flen + 1) - - // Read one. - p.back() - return p.readAny(fv.Index(flen), props) - case reflect.Bool: - // Either "true", "false", 1 or 0. - switch tok.value { - case "true", "1": - fv.SetBool(true) - return nil - case "false", "0": - 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 { - err := um.UnmarshalText([]byte(s)) - return err - } - pb.Reset() - v := reflect.ValueOf(pb) - if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { - return pe - } - return nil -} diff --git a/_third_party/github.com/golang/protobuf/proto/text_parser_test.go b/_third_party/github.com/golang/protobuf/proto/text_parser_test.go deleted file mode 100644 index be9efd36..00000000 --- a/_third_party/github.com/golang/protobuf/proto/text_parser_test.go +++ /dev/null @@ -1,511 +0,0 @@ -// 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_test - -import ( - "math" - "reflect" - "testing" - - . "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" - proto3pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/proto3_proto" - . "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/testdata" -) - -type UnmarshalTextTest struct { - in string - err string // if "", no error expected - out *MyMessage -} - -func buildExtStructTest(text string) UnmarshalTextTest { - msg := &MyMessage{ - Count: Int32(42), - } - SetExtension(msg, E_Ext_More, &Ext{ - Data: String("Hello, world!"), - }) - return UnmarshalTextTest{in: text, out: msg} -} - -func buildExtDataTest(text string) UnmarshalTextTest { - msg := &MyMessage{ - Count: Int32(42), - } - SetExtension(msg, E_Ext_Text, String("Hello, world!")) - SetExtension(msg, E_Ext_Number, Int32(1729)) - return UnmarshalTextTest{in: text, out: msg} -} - -func buildExtRepStringTest(text string) UnmarshalTextTest { - msg := &MyMessage{ - Count: Int32(42), - } - if err := SetExtension(msg, E_Greeting, []string{"bula", "hola"}); err != nil { - panic(err) - } - return UnmarshalTextTest{in: text, out: msg} -} - -var unMarshalTextTests = []UnmarshalTextTest{ - // Basic - { - in: " count:42\n name:\"Dave\" ", - out: &MyMessage{ - Count: Int32(42), - Name: String("Dave"), - }, - }, - - // Empty quoted string - { - in: `count:42 name:""`, - out: &MyMessage{ - Count: Int32(42), - Name: String(""), - }, - }, - - // Quoted string concatenation - { - in: `count:42 name: "My name is "` + "\n" + `"elsewhere"`, - out: &MyMessage{ - Count: Int32(42), - Name: String("My name is elsewhere"), - }, - }, - - // Quoted string with escaped apostrophe - { - in: `count:42 name: "HOLIDAY - New Year\'s Day"`, - out: &MyMessage{ - Count: Int32(42), - Name: String("HOLIDAY - New Year's Day"), - }, - }, - - // Quoted string with single quote - { - in: `count:42 name: 'Roger "The Ramster" Ramjet'`, - out: &MyMessage{ - Count: Int32(42), - Name: String(`Roger "The Ramster" Ramjet`), - }, - }, - - // Quoted string with all the accepted special characters from the C++ test - { - in: `count:42 name: ` + "\"\\\"A string with \\' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"", - out: &MyMessage{ - Count: Int32(42), - Name: String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces"), - }, - }, - - // Quoted string with quoted backslash - { - in: `count:42 name: "\\'xyz"`, - out: &MyMessage{ - Count: Int32(42), - Name: String(`\'xyz`), - }, - }, - - // Quoted string with UTF-8 bytes. - { - in: "count:42 name: '\303\277\302\201\xAB'", - out: &MyMessage{ - Count: Int32(42), - Name: String("\303\277\302\201\xAB"), - }, - }, - - // Bad quoted string - { - in: `inner: < host: "\0" >` + "\n", - err: `line 1.15: invalid quoted string "\0": \0 requires 2 following digits`, - }, - - // Number too large for int64 - { - in: "count: 1 others { key: 123456789012345678901 }", - err: "line 1.23: invalid int64: 123456789012345678901", - }, - - // Number too large for int32 - { - in: "count: 1234567890123", - err: "line 1.7: invalid int32: 1234567890123", - }, - - // Number in hexadecimal - { - in: "count: 0x2beef", - out: &MyMessage{ - Count: Int32(0x2beef), - }, - }, - - // Number in octal - { - in: "count: 024601", - out: &MyMessage{ - Count: Int32(024601), - }, - }, - - // Floating point number with "f" suffix - { - in: "count: 4 others:< weight: 17.0f >", - out: &MyMessage{ - Count: Int32(4), - Others: []*OtherMessage{ - { - Weight: Float32(17), - }, - }, - }, - }, - - // Floating point positive infinity - { - in: "count: 4 bigfloat: inf", - out: &MyMessage{ - Count: Int32(4), - Bigfloat: Float64(math.Inf(1)), - }, - }, - - // Floating point negative infinity - { - in: "count: 4 bigfloat: -inf", - out: &MyMessage{ - Count: Int32(4), - Bigfloat: Float64(math.Inf(-1)), - }, - }, - - // Number too large for float32 - { - in: "others:< weight: 12345678901234567890123456789012345678901234567890 >", - err: "line 1.17: invalid float32: 12345678901234567890123456789012345678901234567890", - }, - - // Number posing as a quoted string - { - in: `inner: < host: 12 >` + "\n", - err: `line 1.15: invalid string: 12`, - }, - - // Quoted string posing as int32 - { - in: `count: "12"`, - err: `line 1.7: invalid int32: "12"`, - }, - - // Quoted string posing a float32 - { - in: `others:< weight: "17.4" >`, - err: `line 1.17: invalid float32: "17.4"`, - }, - - // Enum - { - in: `count:42 bikeshed: BLUE`, - out: &MyMessage{ - Count: Int32(42), - Bikeshed: MyMessage_BLUE.Enum(), - }, - }, - - // Repeated field - { - in: `count:42 pet: "horsey" pet:"bunny"`, - out: &MyMessage{ - Count: Int32(42), - Pet: []string{"horsey", "bunny"}, - }, - }, - - // Repeated message with/without colon and <>/{} - { - in: `count:42 others:{} others{} others:<> others:{}`, - out: &MyMessage{ - Count: Int32(42), - Others: []*OtherMessage{ - {}, - {}, - {}, - {}, - }, - }, - }, - - // Missing colon for inner message - { - in: `count:42 inner < host: "cauchy.syd" >`, - out: &MyMessage{ - Count: Int32(42), - Inner: &InnerMessage{ - Host: String("cauchy.syd"), - }, - }, - }, - - // Missing colon for string field - { - in: `name "Dave"`, - err: `line 1.5: expected ':', found "\"Dave\""`, - }, - - // Missing colon for int32 field - { - in: `count 42`, - err: `line 1.6: expected ':', found "42"`, - }, - - // Missing required field - { - in: `name: "Pawel"`, - err: `proto: required field "testdata.MyMessage.count" not set`, - out: &MyMessage{ - Name: String("Pawel"), - }, - }, - - // Repeated non-repeated field - { - in: `name: "Rob" name: "Russ"`, - err: `line 1.12: non-repeated field "name" was repeated`, - }, - - // Group - { - in: `count: 17 SomeGroup { group_field: 12 }`, - out: &MyMessage{ - Count: Int32(17), - Somegroup: &MyMessage_SomeGroup{ - GroupField: Int32(12), - }, - }, - }, - - // Semicolon between fields - { - in: `count:3;name:"Calvin"`, - out: &MyMessage{ - Count: Int32(3), - Name: String("Calvin"), - }, - }, - // Comma between fields - { - in: `count:4,name:"Ezekiel"`, - out: &MyMessage{ - Count: Int32(4), - Name: String("Ezekiel"), - }, - }, - - // Extension - buildExtStructTest(`count: 42 [testdata.Ext.more]:`), - buildExtStructTest(`count: 42 [testdata.Ext.more] {data:"Hello, world!"}`), - buildExtDataTest(`count: 42 [testdata.Ext.text]:"Hello, world!" [testdata.Ext.number]:1729`), - buildExtRepStringTest(`count: 42 [testdata.greeting]:"bula" [testdata.greeting]:"hola"`), - - // Big all-in-one - { - in: "count:42 # Meaning\n" + - `name:"Dave" ` + - `quote:"\"I didn't want to go.\"" ` + - `pet:"bunny" ` + - `pet:"kitty" ` + - `pet:"horsey" ` + - `inner:<` + - ` host:"footrest.syd" ` + - ` port:7001 ` + - ` connected:true ` + - `> ` + - `others:<` + - ` key:3735928559 ` + - ` value:"\x01A\a\f" ` + - `> ` + - `others:<` + - " weight:58.9 # Atomic weight of Co\n" + - ` inner:<` + - ` host:"lesha.mtv" ` + - ` port:8002 ` + - ` >` + - `>`, - out: &MyMessage{ - Count: Int32(42), - Name: String("Dave"), - Quote: String(`"I didn't want to go."`), - Pet: []string{"bunny", "kitty", "horsey"}, - Inner: &InnerMessage{ - Host: String("footrest.syd"), - Port: Int32(7001), - Connected: Bool(true), - }, - Others: []*OtherMessage{ - { - Key: Int64(3735928559), - Value: []byte{0x1, 'A', '\a', '\f'}, - }, - { - Weight: Float32(58.9), - Inner: &InnerMessage{ - Host: String("lesha.mtv"), - Port: Int32(8002), - }, - }, - }, - }, - }, -} - -func TestUnmarshalText(t *testing.T) { - for i, test := range unMarshalTextTests { - pb := new(MyMessage) - err := UnmarshalText(test.in, pb) - if test.err == "" { - // We don't expect failure. - if err != nil { - t.Errorf("Test %d: Unexpected error: %v", i, err) - } else if !reflect.DeepEqual(pb, test.out) { - t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v", - i, pb, test.out) - } - } else { - // We do expect failure. - if err == nil { - t.Errorf("Test %d: Didn't get expected error: %v", i, test.err) - } else if err.Error() != test.err { - t.Errorf("Test %d: Incorrect error.\nHave: %v\nWant: %v", - i, err.Error(), test.err) - } else if _, ok := err.(*RequiredNotSetError); ok && test.out != nil && !reflect.DeepEqual(pb, test.out) { - t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v", - i, pb, test.out) - } - } - } -} - -func TestUnmarshalTextCustomMessage(t *testing.T) { - msg := &textMessage{} - if err := UnmarshalText("custom", msg); err != nil { - t.Errorf("Unexpected error from custom unmarshal: %v", err) - } - if UnmarshalText("not custom", msg) == nil { - t.Errorf("Didn't get expected error from custom unmarshal") - } -} - -// Regression test; this caused a panic. -func TestRepeatedEnum(t *testing.T) { - pb := new(RepeatedEnum) - if err := UnmarshalText("color: RED", pb); err != nil { - t.Fatal(err) - } - exp := &RepeatedEnum{ - Color: []RepeatedEnum_Color{RepeatedEnum_RED}, - } - if !Equal(pb, exp) { - t.Errorf("Incorrect populated \nHave: %v\nWant: %v", pb, exp) - } -} - -func TestProto3TextParsing(t *testing.T) { - m := new(proto3pb.Message) - const in = `name: "Wallace" true_scotsman: true` - want := &proto3pb.Message{ - Name: "Wallace", - TrueScotsman: true, - } - if err := UnmarshalText(in, m); err != nil { - t.Fatal(err) - } - if !Equal(m, want) { - t.Errorf("\n got %v\nwant %v", m, want) - } -} - -func TestMapParsing(t *testing.T) { - m := new(MessageWithMap) - const in = `name_mapping: name_mapping:` + - `msg_mapping:,>` + // separating commas are okay - `msg_mapping>` + // no colon after "value" - `byte_mapping:` - want := &MessageWithMap{ - NameMapping: map[int32]string{ - 1: "Beatles", - 1234: "Feist", - }, - MsgMapping: map[int64]*FloatingPoint{ - -4: {F: Float64(2.0)}, - -2: {F: Float64(4.0)}, - }, - ByteMapping: map[bool][]byte{ - true: []byte("so be it"), - }, - } - if err := UnmarshalText(in, m); err != nil { - t.Fatal(err) - } - if !Equal(m, want) { - t.Errorf("\n got %v\nwant %v", m, want) - } -} - -var benchInput string - -func init() { - benchInput = "count: 4\n" - for i := 0; i < 1000; i++ { - benchInput += "pet: \"fido\"\n" - } - - // Check it is valid input. - pb := new(MyMessage) - err := UnmarshalText(benchInput, pb) - if err != nil { - panic("Bad benchmark input: " + err.Error()) - } -} - -func BenchmarkUnmarshalText(b *testing.B) { - pb := new(MyMessage) - for i := 0; i < b.N; i++ { - UnmarshalText(benchInput, pb) - } - b.SetBytes(int64(len(benchInput))) -} diff --git a/_third_party/github.com/golang/protobuf/proto/text_test.go b/_third_party/github.com/golang/protobuf/proto/text_test.go deleted file mode 100644 index f46ade07..00000000 --- a/_third_party/github.com/golang/protobuf/proto/text_test.go +++ /dev/null @@ -1,441 +0,0 @@ -// 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_test - -import ( - "bytes" - "errors" - "io/ioutil" - "math" - "strings" - "testing" - - "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" - - proto3pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/proto3_proto" - pb "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto/testdata" -) - -// textMessage implements the methods that allow it to marshal and unmarshal -// itself as text. -type textMessage struct { -} - -func (*textMessage) MarshalText() ([]byte, error) { - return []byte("custom"), nil -} - -func (*textMessage) UnmarshalText(bytes []byte) error { - if string(bytes) != "custom" { - return errors.New("expected 'custom'") - } - return nil -} - -func (*textMessage) Reset() {} -func (*textMessage) String() string { return "" } -func (*textMessage) ProtoMessage() {} - -func newTestMessage() *pb.MyMessage { - msg := &pb.MyMessage{ - Count: proto.Int32(42), - Name: proto.String("Dave"), - Quote: proto.String(`"I didn't want to go."`), - Pet: []string{"bunny", "kitty", "horsey"}, - Inner: &pb.InnerMessage{ - Host: proto.String("footrest.syd"), - Port: proto.Int32(7001), - Connected: proto.Bool(true), - }, - Others: []*pb.OtherMessage{ - { - Key: proto.Int64(0xdeadbeef), - Value: []byte{1, 65, 7, 12}, - }, - { - Weight: proto.Float32(6.022), - Inner: &pb.InnerMessage{ - Host: proto.String("lesha.mtv"), - Port: proto.Int32(8002), - }, - }, - }, - Bikeshed: pb.MyMessage_BLUE.Enum(), - Somegroup: &pb.MyMessage_SomeGroup{ - GroupField: proto.Int32(8), - }, - // One normally wouldn't do this. - // This is an undeclared tag 13, as a varint (wire type 0) with value 4. - XXX_unrecognized: []byte{13<<3 | 0, 4}, - } - ext := &pb.Ext{ - Data: proto.String("Big gobs for big rats"), - } - if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil { - panic(err) - } - greetings := []string{"adg", "easy", "cow"} - if err := proto.SetExtension(msg, pb.E_Greeting, greetings); err != nil { - panic(err) - } - - // Add an unknown extension. We marshal a pb.Ext, and fake the ID. - b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")}) - if err != nil { - panic(err) - } - b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...) - proto.SetRawExtension(msg, 201, b) - - // Extensions can be plain fields, too, so let's test that. - b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19) - proto.SetRawExtension(msg, 202, b) - - return msg -} - -const text = `count: 42 -name: "Dave" -quote: "\"I didn't want to go.\"" -pet: "bunny" -pet: "kitty" -pet: "horsey" -inner: < - host: "footrest.syd" - port: 7001 - connected: true -> -others: < - key: 3735928559 - value: "\001A\007\014" -> -others: < - weight: 6.022 - inner: < - host: "lesha.mtv" - port: 8002 - > -> -bikeshed: BLUE -SomeGroup { - group_field: 8 -} -/* 2 unknown bytes */ -13: 4 -[testdata.Ext.more]: < - data: "Big gobs for big rats" -> -[testdata.greeting]: "adg" -[testdata.greeting]: "easy" -[testdata.greeting]: "cow" -/* 13 unknown bytes */ -201: "\t3G skiing" -/* 3 unknown bytes */ -202: 19 -` - -func TestMarshalText(t *testing.T) { - buf := new(bytes.Buffer) - if err := proto.MarshalText(buf, newTestMessage()); err != nil { - t.Fatalf("proto.MarshalText: %v", err) - } - s := buf.String() - if s != text { - t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, text) - } -} - -func TestMarshalTextCustomMessage(t *testing.T) { - buf := new(bytes.Buffer) - if err := proto.MarshalText(buf, &textMessage{}); err != nil { - t.Fatalf("proto.MarshalText: %v", err) - } - s := buf.String() - if s != "custom" { - t.Errorf("Got %q, expected %q", s, "custom") - } -} -func TestMarshalTextNil(t *testing.T) { - want := "" - tests := []proto.Message{nil, (*pb.MyMessage)(nil)} - for i, test := range tests { - buf := new(bytes.Buffer) - if err := proto.MarshalText(buf, test); err != nil { - t.Fatal(err) - } - if got := buf.String(); got != want { - t.Errorf("%d: got %q want %q", i, got, want) - } - } -} - -func TestMarshalTextUnknownEnum(t *testing.T) { - // The Color enum only specifies values 0-2. - m := &pb.MyMessage{Bikeshed: pb.MyMessage_Color(3).Enum()} - got := m.String() - const want = `bikeshed:3 ` - if got != want { - t.Errorf("\n got %q\nwant %q", got, want) - } -} - -func BenchmarkMarshalTextBuffered(b *testing.B) { - buf := new(bytes.Buffer) - m := newTestMessage() - for i := 0; i < b.N; i++ { - buf.Reset() - proto.MarshalText(buf, m) - } -} - -func BenchmarkMarshalTextUnbuffered(b *testing.B) { - w := ioutil.Discard - m := newTestMessage() - for i := 0; i < b.N; i++ { - proto.MarshalText(w, m) - } -} - -func compact(src string) string { - // s/[ \n]+/ /g; s/ $//; - dst := make([]byte, len(src)) - space, comment := false, false - j := 0 - for i := 0; i < len(src); i++ { - if strings.HasPrefix(src[i:], "/*") { - comment = true - i++ - continue - } - if comment && strings.HasPrefix(src[i:], "*/") { - comment = false - i++ - continue - } - if comment { - continue - } - c := src[i] - if c == ' ' || c == '\n' { - space = true - continue - } - if j > 0 && (dst[j-1] == ':' || dst[j-1] == '<' || dst[j-1] == '{') { - space = false - } - if c == '{' { - space = false - } - if space { - dst[j] = ' ' - j++ - space = false - } - dst[j] = c - j++ - } - if space { - dst[j] = ' ' - j++ - } - return string(dst[0:j]) -} - -var compactText = compact(text) - -func TestCompactText(t *testing.T) { - s := proto.CompactTextString(newTestMessage()) - if s != compactText { - t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v\n===\n", s, compactText) - } -} - -func TestStringEscaping(t *testing.T) { - testCases := []struct { - in *pb.Strings - out string - }{ - { - // Test data from C++ test (TextFormatTest.StringEscape). - // Single divergence: we don't escape apostrophes. - &pb.Strings{StringField: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces")}, - "string_field: \"\\\"A string with ' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"\n", - }, - { - // Test data from the same C++ test. - &pb.Strings{StringField: proto.String("\350\260\267\346\255\214")}, - "string_field: \"\\350\\260\\267\\346\\255\\214\"\n", - }, - { - // Some UTF-8. - &pb.Strings{StringField: proto.String("\x00\x01\xff\x81")}, - `string_field: "\000\001\377\201"` + "\n", - }, - } - - for i, tc := range testCases { - var buf bytes.Buffer - if err := proto.MarshalText(&buf, tc.in); err != nil { - t.Errorf("proto.MarsalText: %v", err) - continue - } - s := buf.String() - if s != tc.out { - t.Errorf("#%d: Got:\n%s\nExpected:\n%s\n", i, s, tc.out) - continue - } - - // Check round-trip. - pb := new(pb.Strings) - if err := proto.UnmarshalText(s, pb); err != nil { - t.Errorf("#%d: UnmarshalText: %v", i, err) - continue - } - if !proto.Equal(pb, tc.in) { - t.Errorf("#%d: Round-trip failed:\nstart: %v\n end: %v", i, tc.in, pb) - } - } -} - -// A limitedWriter accepts some output before it fails. -// This is a proxy for something like a nearly-full or imminently-failing disk, -// or a network connection that is about to die. -type limitedWriter struct { - b bytes.Buffer - limit int -} - -var outOfSpace = errors.New("proto: insufficient space") - -func (w *limitedWriter) Write(p []byte) (n int, err error) { - var avail = w.limit - w.b.Len() - if avail <= 0 { - return 0, outOfSpace - } - if len(p) <= avail { - return w.b.Write(p) - } - n, _ = w.b.Write(p[:avail]) - return n, outOfSpace -} - -func TestMarshalTextFailing(t *testing.T) { - // Try lots of different sizes to exercise more error code-paths. - for lim := 0; lim < len(text); lim++ { - buf := new(limitedWriter) - buf.limit = lim - err := proto.MarshalText(buf, newTestMessage()) - // We expect a certain error, but also some partial results in the buffer. - if err != outOfSpace { - t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", err, outOfSpace) - } - s := buf.b.String() - x := text[:buf.limit] - if s != x { - t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, x) - } - } -} - -func TestFloats(t *testing.T) { - tests := []struct { - f float64 - want string - }{ - {0, "0"}, - {4.7, "4.7"}, - {math.Inf(1), "inf"}, - {math.Inf(-1), "-inf"}, - {math.NaN(), "nan"}, - } - for _, test := range tests { - msg := &pb.FloatingPoint{F: &test.f} - got := strings.TrimSpace(msg.String()) - want := `f:` + test.want - if got != want { - t.Errorf("f=%f: got %q, want %q", test.f, got, want) - } - } -} - -func TestRepeatedNilText(t *testing.T) { - m := &pb.MessageList{ - Message: []*pb.MessageList_Message{ - nil, - &pb.MessageList_Message{ - Name: proto.String("Horse"), - }, - nil, - }, - } - want := `Message -Message { - name: "Horse" -} -Message -` - if s := proto.MarshalTextString(m); s != want { - t.Errorf(" got: %s\nwant: %s", s, want) - } -} - -func TestProto3Text(t *testing.T) { - tests := []struct { - m proto.Message - want string - }{ - // zero message - {&proto3pb.Message{}, ``}, - // zero message except for an empty byte slice - {&proto3pb.Message{Data: []byte{}}, ``}, - // trivial case - {&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`}, - // empty map - {&pb.MessageWithMap{}, ``}, - // non-empty map; current map format is the same as a repeated struct - { - &pb.MessageWithMap{NameMapping: map[int32]string{1234: "Feist"}}, - `name_mapping:`, - }, - // map with nil value; not well-defined, but we shouldn't crash - { - &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{7: nil}}, - `msg_mapping:`, - }, - } - for _, test := range tests { - got := strings.TrimSpace(test.m.String()) - if got != test.want { - t.Errorf("\n got %s\nwant %s", got, test.want) - } - } -} diff --git a/_third_party/github.com/gorilla/context/LICENSE b/_third_party/github.com/gorilla/context/LICENSE deleted file mode 100644 index 0e5fb872..00000000 --- a/_third_party/github.com/gorilla/context/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 Rodrigo Moraes. 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/_third_party/github.com/gorilla/context/README.md b/_third_party/github.com/gorilla/context/README.md deleted file mode 100644 index c60a31b0..00000000 --- a/_third_party/github.com/gorilla/context/README.md +++ /dev/null @@ -1,7 +0,0 @@ -context -======= -[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context) - -gorilla/context is a general purpose registry for global request variables. - -Read the full documentation here: http://www.gorillatoolkit.org/pkg/context diff --git a/_third_party/github.com/gorilla/context/context.go b/_third_party/github.com/gorilla/context/context.go deleted file mode 100644 index 81cb128b..00000000 --- a/_third_party/github.com/gorilla/context/context.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2012 The Gorilla 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 context - -import ( - "net/http" - "sync" - "time" -) - -var ( - mutex sync.RWMutex - data = make(map[*http.Request]map[interface{}]interface{}) - datat = make(map[*http.Request]int64) -) - -// Set stores a value for a given key in a given request. -func Set(r *http.Request, key, val interface{}) { - mutex.Lock() - if data[r] == nil { - data[r] = make(map[interface{}]interface{}) - datat[r] = time.Now().Unix() - } - data[r][key] = val - mutex.Unlock() -} - -// Get returns a value stored for a given key in a given request. -func Get(r *http.Request, key interface{}) interface{} { - mutex.RLock() - if ctx := data[r]; ctx != nil { - value := ctx[key] - mutex.RUnlock() - return value - } - mutex.RUnlock() - return nil -} - -// GetOk returns stored value and presence state like multi-value return of map access. -func GetOk(r *http.Request, key interface{}) (interface{}, bool) { - mutex.RLock() - if _, ok := data[r]; ok { - value, ok := data[r][key] - mutex.RUnlock() - return value, ok - } - mutex.RUnlock() - return nil, false -} - -// GetAll returns all stored values for the request as a map. Nil is returned for invalid requests. -func GetAll(r *http.Request) map[interface{}]interface{} { - mutex.RLock() - if context, ok := data[r]; ok { - result := make(map[interface{}]interface{}, len(context)) - for k, v := range context { - result[k] = v - } - mutex.RUnlock() - return result - } - mutex.RUnlock() - return nil -} - -// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if -// the request was registered. -func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) { - mutex.RLock() - context, ok := data[r] - result := make(map[interface{}]interface{}, len(context)) - for k, v := range context { - result[k] = v - } - mutex.RUnlock() - return result, ok -} - -// Delete removes a value stored for a given key in a given request. -func Delete(r *http.Request, key interface{}) { - mutex.Lock() - if data[r] != nil { - delete(data[r], key) - } - mutex.Unlock() -} - -// Clear removes all values stored for a given request. -// -// This is usually called by a handler wrapper to clean up request -// variables at the end of a request lifetime. See ClearHandler(). -func Clear(r *http.Request) { - mutex.Lock() - clear(r) - mutex.Unlock() -} - -// clear is Clear without the lock. -func clear(r *http.Request) { - delete(data, r) - delete(datat, r) -} - -// Purge removes request data stored for longer than maxAge, in seconds. -// It returns the amount of requests removed. -// -// If maxAge <= 0, all request data is removed. -// -// This is only used for sanity check: in case context cleaning was not -// properly set some request data can be kept forever, consuming an increasing -// amount of memory. In case this is detected, Purge() must be called -// periodically until the problem is fixed. -func Purge(maxAge int) int { - mutex.Lock() - count := 0 - if maxAge <= 0 { - count = len(data) - data = make(map[*http.Request]map[interface{}]interface{}) - datat = make(map[*http.Request]int64) - } else { - min := time.Now().Unix() - int64(maxAge) - for r := range data { - if datat[r] < min { - clear(r) - count++ - } - } - } - mutex.Unlock() - return count -} - -// ClearHandler wraps an http.Handler and clears request values at the end -// of a request lifetime. -func ClearHandler(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - defer Clear(r) - h.ServeHTTP(w, r) - }) -} diff --git a/_third_party/github.com/gorilla/context/context_test.go b/_third_party/github.com/gorilla/context/context_test.go deleted file mode 100644 index 9814c501..00000000 --- a/_third_party/github.com/gorilla/context/context_test.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2012 The Gorilla 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 context - -import ( - "net/http" - "testing" -) - -type keyType int - -const ( - key1 keyType = iota - key2 -) - -func TestContext(t *testing.T) { - assertEqual := func(val interface{}, exp interface{}) { - if val != exp { - t.Errorf("Expected %v, got %v.", exp, val) - } - } - - r, _ := http.NewRequest("GET", "http://localhost:8080/", nil) - emptyR, _ := http.NewRequest("GET", "http://localhost:8080/", nil) - - // Get() - assertEqual(Get(r, key1), nil) - - // Set() - Set(r, key1, "1") - assertEqual(Get(r, key1), "1") - assertEqual(len(data[r]), 1) - - Set(r, key2, "2") - assertEqual(Get(r, key2), "2") - assertEqual(len(data[r]), 2) - - //GetOk - value, ok := GetOk(r, key1) - assertEqual(value, "1") - assertEqual(ok, true) - - value, ok = GetOk(r, "not exists") - assertEqual(value, nil) - assertEqual(ok, false) - - Set(r, "nil value", nil) - value, ok = GetOk(r, "nil value") - assertEqual(value, nil) - assertEqual(ok, true) - - // GetAll() - values := GetAll(r) - assertEqual(len(values), 3) - - // GetAll() for empty request - values = GetAll(emptyR) - if values != nil { - t.Error("GetAll didn't return nil value for invalid request") - } - - // GetAllOk() - values, ok = GetAllOk(r) - assertEqual(len(values), 3) - assertEqual(ok, true) - - // GetAllOk() for empty request - values, ok = GetAllOk(emptyR) - assertEqual(value, nil) - assertEqual(ok, false) - - // Delete() - Delete(r, key1) - assertEqual(Get(r, key1), nil) - assertEqual(len(data[r]), 2) - - Delete(r, key2) - assertEqual(Get(r, key2), nil) - assertEqual(len(data[r]), 1) - - // Clear() - Clear(r) - assertEqual(len(data), 0) -} - -func parallelReader(r *http.Request, key string, iterations int, wait, done chan struct{}) { - <-wait - for i := 0; i < iterations; i++ { - Get(r, key) - } - done <- struct{}{} - -} - -func parallelWriter(r *http.Request, key, value string, iterations int, wait, done chan struct{}) { - <-wait - for i := 0; i < iterations; i++ { - Set(r, key, value) - } - done <- struct{}{} - -} - -func benchmarkMutex(b *testing.B, numReaders, numWriters, iterations int) { - - b.StopTimer() - r, _ := http.NewRequest("GET", "http://localhost:8080/", nil) - done := make(chan struct{}) - b.StartTimer() - - for i := 0; i < b.N; i++ { - wait := make(chan struct{}) - - for i := 0; i < numReaders; i++ { - go parallelReader(r, "test", iterations, wait, done) - } - - for i := 0; i < numWriters; i++ { - go parallelWriter(r, "test", "123", iterations, wait, done) - } - - close(wait) - - for i := 0; i < numReaders+numWriters; i++ { - <-done - } - - } - -} - -func BenchmarkMutexSameReadWrite1(b *testing.B) { - benchmarkMutex(b, 1, 1, 32) -} -func BenchmarkMutexSameReadWrite2(b *testing.B) { - benchmarkMutex(b, 2, 2, 32) -} -func BenchmarkMutexSameReadWrite4(b *testing.B) { - benchmarkMutex(b, 4, 4, 32) -} -func BenchmarkMutex1(b *testing.B) { - benchmarkMutex(b, 2, 8, 32) -} -func BenchmarkMutex2(b *testing.B) { - benchmarkMutex(b, 16, 4, 64) -} -func BenchmarkMutex3(b *testing.B) { - benchmarkMutex(b, 1, 2, 128) -} -func BenchmarkMutex4(b *testing.B) { - benchmarkMutex(b, 128, 32, 256) -} -func BenchmarkMutex5(b *testing.B) { - benchmarkMutex(b, 1024, 2048, 64) -} -func BenchmarkMutex6(b *testing.B) { - benchmarkMutex(b, 2048, 1024, 512) -} diff --git a/_third_party/github.com/gorilla/context/doc.go b/_third_party/github.com/gorilla/context/doc.go deleted file mode 100644 index 73c74003..00000000 --- a/_third_party/github.com/gorilla/context/doc.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2012 The Gorilla 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 context stores values shared during a request lifetime. - -For example, a router can set variables extracted from the URL and later -application handlers can access those values, or it can be used to store -sessions values to be saved at the end of a request. There are several -others common uses. - -The idea was posted by Brad Fitzpatrick to the go-nuts mailing list: - - http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53 - -Here's the basic usage: first define the keys that you will need. The key -type is interface{} so a key can be of any type that supports equality. -Here we define a key using a custom int type to avoid name collisions: - - package foo - - import ( - "github.com/gorilla/context" - ) - - type key int - - const MyKey key = 0 - -Then set a variable. Variables are bound to an http.Request object, so you -need a request instance to set a value: - - context.Set(r, MyKey, "bar") - -The application can later access the variable using the same key you provided: - - func MyHandler(w http.ResponseWriter, r *http.Request) { - // val is "bar". - val := context.Get(r, foo.MyKey) - - // returns ("bar", true) - val, ok := context.GetOk(r, foo.MyKey) - // ... - } - -And that's all about the basic usage. We discuss some other ideas below. - -Any type can be stored in the context. To enforce a given type, make the key -private and wrap Get() and Set() to accept and return values of a specific -type: - - type key int - - const mykey key = 0 - - // GetMyKey returns a value for this package from the request values. - func GetMyKey(r *http.Request) SomeType { - if rv := context.Get(r, mykey); rv != nil { - return rv.(SomeType) - } - return nil - } - - // SetMyKey sets a value for this package in the request values. - func SetMyKey(r *http.Request, val SomeType) { - context.Set(r, mykey, val) - } - -Variables must be cleared at the end of a request, to remove all values -that were stored. This can be done in an http.Handler, after a request was -served. Just call Clear() passing the request: - - context.Clear(r) - -...or use ClearHandler(), which conveniently wraps an http.Handler to clear -variables at the end of a request lifetime. - -The Routers from the packages gorilla/mux and gorilla/pat call Clear() -so if you are using either of them you don't need to clear the context manually. -*/ -package context diff --git a/_third_party/github.com/gorilla/mux/LICENSE b/_third_party/github.com/gorilla/mux/LICENSE deleted file mode 100644 index 0e5fb872..00000000 --- a/_third_party/github.com/gorilla/mux/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 Rodrigo Moraes. 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/_third_party/github.com/gorilla/mux/README.md b/_third_party/github.com/gorilla/mux/README.md deleted file mode 100644 index e60301b0..00000000 --- a/_third_party/github.com/gorilla/mux/README.md +++ /dev/null @@ -1,7 +0,0 @@ -mux -=== -[![Build Status](https://travis-ci.org/gorilla/mux.png?branch=master)](https://travis-ci.org/gorilla/mux) - -gorilla/mux is a powerful URL router and dispatcher. - -Read the full documentation here: http://www.gorillatoolkit.org/pkg/mux diff --git a/_third_party/github.com/gorilla/mux/bench_test.go b/_third_party/github.com/gorilla/mux/bench_test.go deleted file mode 100644 index c5f97b2b..00000000 --- a/_third_party/github.com/gorilla/mux/bench_test.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import ( - "net/http" - "testing" -) - -func BenchmarkMux(b *testing.B) { - router := new(Router) - handler := func(w http.ResponseWriter, r *http.Request) {} - router.HandleFunc("/v1/{v1}", handler) - - request, _ := http.NewRequest("GET", "/v1/anything", nil) - for i := 0; i < b.N; i++ { - router.ServeHTTP(nil, request) - } -} diff --git a/_third_party/github.com/gorilla/mux/doc.go b/_third_party/github.com/gorilla/mux/doc.go deleted file mode 100644 index 9a5e381a..00000000 --- a/_third_party/github.com/gorilla/mux/doc.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2012 The Gorilla 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 gorilla/mux implements a request router and dispatcher. - -The name mux stands for "HTTP request multiplexer". Like the standard -http.ServeMux, mux.Router matches incoming requests against a list of -registered routes and calls a handler for the route that matches the URL -or other conditions. The main features are: - - * Requests can be matched based on URL host, path, path prefix, schemes, - header and query values, HTTP methods or using custom matchers. - * URL hosts and paths can have variables with an optional regular - expression. - * Registered URLs can be built, or "reversed", which helps maintaining - references to resources. - * Routes can be used as subrouters: nested routes are only tested if the - parent route matches. This is useful to define groups of routes that - share common conditions like a host, a path prefix or other repeated - attributes. As a bonus, this optimizes request matching. - * It implements the http.Handler interface so it is compatible with the - standard http.ServeMux. - -Let's start registering a couple of URL paths and handlers: - - func main() { - r := mux.NewRouter() - r.HandleFunc("/", HomeHandler) - r.HandleFunc("/products", ProductsHandler) - r.HandleFunc("/articles", ArticlesHandler) - http.Handle("/", r) - } - -Here we register three routes mapping URL paths to handlers. This is -equivalent to how http.HandleFunc() works: if an incoming request URL matches -one of the paths, the corresponding handler is called passing -(http.ResponseWriter, *http.Request) as parameters. - -Paths can have variables. They are defined using the format {name} or -{name:pattern}. If a regular expression pattern is not defined, the matched -variable will be anything until the next slash. For example: - - r := mux.NewRouter() - r.HandleFunc("/products/{key}", ProductHandler) - r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) - r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) - -The names are used to create a map of route variables which can be retrieved -calling mux.Vars(): - - vars := mux.Vars(request) - category := vars["category"] - -And this is all you need to know about the basic usage. More advanced options -are explained below. - -Routes can also be restricted to a domain or subdomain. Just define a host -pattern to be matched. They can also have variables: - - r := mux.NewRouter() - // Only matches if domain is "www.domain.com". - r.Host("www.domain.com") - // Matches a dynamic subdomain. - r.Host("{subdomain:[a-z]+}.domain.com") - -There are several other matchers that can be added. To match path prefixes: - - r.PathPrefix("/products/") - -...or HTTP methods: - - r.Methods("GET", "POST") - -...or URL schemes: - - r.Schemes("https") - -...or header values: - - r.Headers("X-Requested-With", "XMLHttpRequest") - -...or query values: - - r.Queries("key", "value") - -...or to use a custom matcher function: - - r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { - return r.ProtoMajor == 0 - }) - -...and finally, it is possible to combine several matchers in a single route: - - r.HandleFunc("/products", ProductsHandler). - Host("www.domain.com"). - Methods("GET"). - Schemes("http") - -Setting the same matching conditions again and again can be boring, so we have -a way to group several routes that share the same requirements. -We call it "subrouting". - -For example, let's say we have several URLs that should only match when the -host is "www.domain.com". Create a route for that host and get a "subrouter" -from it: - - r := mux.NewRouter() - s := r.Host("www.domain.com").Subrouter() - -Then register routes in the subrouter: - - s.HandleFunc("/products/", ProductsHandler) - s.HandleFunc("/products/{key}", ProductHandler) - s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) - -The three URL paths we registered above will only be tested if the domain is -"www.domain.com", because the subrouter is tested first. This is not -only convenient, but also optimizes request matching. You can create -subrouters combining any attribute matchers accepted by a route. - -Subrouters can be used to create domain or path "namespaces": you define -subrouters in a central place and then parts of the app can register its -paths relatively to a given subrouter. - -There's one more thing about subroutes. When a subrouter has a path prefix, -the inner routes use it as base for their paths: - - r := mux.NewRouter() - s := r.PathPrefix("/products").Subrouter() - // "/products/" - s.HandleFunc("/", ProductsHandler) - // "/products/{key}/" - s.HandleFunc("/{key}/", ProductHandler) - // "/products/{key}/details" - s.HandleFunc("/{key}/details", ProductDetailsHandler) - -Now let's see how to build registered URLs. - -Routes can be named. All routes that define a name can have their URLs built, -or "reversed". We define a name calling Name() on a route. For example: - - r := mux.NewRouter() - r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). - Name("article") - -To build a URL, get the route and call the URL() method, passing a sequence of -key/value pairs for the route variables. For the previous route, we would do: - - url, err := r.Get("article").URL("category", "technology", "id", "42") - -...and the result will be a url.URL with the following path: - - "/articles/technology/42" - -This also works for host variables: - - r := mux.NewRouter() - r.Host("{subdomain}.domain.com"). - Path("/articles/{category}/{id:[0-9]+}"). - HandlerFunc(ArticleHandler). - Name("article") - - // url.String() will be "http://news.domain.com/articles/technology/42" - url, err := r.Get("article").URL("subdomain", "news", - "category", "technology", - "id", "42") - -All variables defined in the route are required, and their values must -conform to the corresponding patterns. These requirements guarantee that a -generated URL will always match a registered route -- the only exception is -for explicitly defined "build-only" routes which never match. - -There's also a way to build only the URL host or path for a route: -use the methods URLHost() or URLPath() instead. For the previous route, -we would do: - - // "http://news.domain.com/" - host, err := r.Get("article").URLHost("subdomain", "news") - - // "/articles/technology/42" - path, err := r.Get("article").URLPath("category", "technology", "id", "42") - -And if you use subrouters, host and path defined separately can be built -as well: - - r := mux.NewRouter() - s := r.Host("{subdomain}.domain.com").Subrouter() - s.Path("/articles/{category}/{id:[0-9]+}"). - HandlerFunc(ArticleHandler). - Name("article") - - // "http://news.domain.com/articles/technology/42" - url, err := r.Get("article").URL("subdomain", "news", - "category", "technology", - "id", "42") -*/ -package mux diff --git a/_third_party/github.com/gorilla/mux/mux.go b/_third_party/github.com/gorilla/mux/mux.go deleted file mode 100644 index e7fb1dbe..00000000 --- a/_third_party/github.com/gorilla/mux/mux.go +++ /dev/null @@ -1,366 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import ( - "fmt" - "net/http" - "path" - - "github.com/mjibson/goread/_third_party/github.com/gorilla/context" -) - -// NewRouter returns a new router instance. -func NewRouter() *Router { - return &Router{namedRoutes: make(map[string]*Route), KeepContext: false} -} - -// Router registers routes to be matched and dispatches a handler. -// -// It implements the http.Handler interface, so it can be registered to serve -// requests: -// -// var router = mux.NewRouter() -// -// func main() { -// http.Handle("/", router) -// } -// -// Or, for Google App Engine, register it in a init() function: -// -// func init() { -// http.Handle("/", router) -// } -// -// This will send all incoming requests to the router. -type Router struct { - // Configurable Handler to be used when no route matches. - NotFoundHandler http.Handler - // Parent route, if this is a subrouter. - parent parentRoute - // Routes to be matched, in order. - routes []*Route - // Routes by name for URL building. - namedRoutes map[string]*Route - // See Router.StrictSlash(). This defines the flag for new routes. - strictSlash bool - // If true, do not clear the request context after handling the request - KeepContext bool -} - -// Match matches registered routes against the request. -func (r *Router) Match(req *http.Request, match *RouteMatch) bool { - for _, route := range r.routes { - if route.Match(req, match) { - return true - } - } - return false -} - -// ServeHTTP dispatches the handler registered in the matched route. -// -// When there is a match, the route variables can be retrieved calling -// mux.Vars(request). -func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { - // Clean path to canonical form and redirect. - if p := cleanPath(req.URL.Path); p != req.URL.Path { - - // Added 3 lines (Philip Schlump) - It was droping the query string and #whatever from query. - // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue: - // http://code.google.com/p/go/issues/detail?id=5252 - url := *req.URL - url.Path = p - p = url.String() - - w.Header().Set("Location", p) - w.WriteHeader(http.StatusMovedPermanently) - return - } - var match RouteMatch - var handler http.Handler - if r.Match(req, &match) { - handler = match.Handler - setVars(req, match.Vars) - setCurrentRoute(req, match.Route) - } - if handler == nil { - handler = r.NotFoundHandler - if handler == nil { - handler = http.NotFoundHandler() - } - } - if !r.KeepContext { - defer context.Clear(req) - } - handler.ServeHTTP(w, req) -} - -// Get returns a route registered with the given name. -func (r *Router) Get(name string) *Route { - return r.getNamedRoutes()[name] -} - -// GetRoute returns a route registered with the given name. This method -// was renamed to Get() and remains here for backwards compatibility. -func (r *Router) GetRoute(name string) *Route { - return r.getNamedRoutes()[name] -} - -// StrictSlash defines the trailing slash behavior for new routes. The initial -// value is false. -// -// When true, if the route path is "/path/", accessing "/path" will redirect -// to the former and vice versa. In other words, your application will always -// see the path as specified in the route. -// -// When false, if the route path is "/path", accessing "/path/" will not match -// this route and vice versa. -// -// Special case: when a route sets a path prefix using the PathPrefix() method, -// strict slash is ignored for that route because the redirect behavior can't -// be determined from a prefix alone. However, any subrouters created from that -// route inherit the original StrictSlash setting. -func (r *Router) StrictSlash(value bool) *Router { - r.strictSlash = value - return r -} - -// ---------------------------------------------------------------------------- -// parentRoute -// ---------------------------------------------------------------------------- - -// getNamedRoutes returns the map where named routes are registered. -func (r *Router) getNamedRoutes() map[string]*Route { - if r.namedRoutes == nil { - if r.parent != nil { - r.namedRoutes = r.parent.getNamedRoutes() - } else { - r.namedRoutes = make(map[string]*Route) - } - } - return r.namedRoutes -} - -// getRegexpGroup returns regexp definitions from the parent route, if any. -func (r *Router) getRegexpGroup() *routeRegexpGroup { - if r.parent != nil { - return r.parent.getRegexpGroup() - } - return nil -} - -func (r *Router) buildVars(m map[string]string) map[string]string { - if r.parent != nil { - m = r.parent.buildVars(m) - } - return m -} - -// ---------------------------------------------------------------------------- -// Route factories -// ---------------------------------------------------------------------------- - -// NewRoute registers an empty route. -func (r *Router) NewRoute() *Route { - route := &Route{parent: r, strictSlash: r.strictSlash} - r.routes = append(r.routes, route) - return route -} - -// Handle registers a new route with a matcher for the URL path. -// See Route.Path() and Route.Handler(). -func (r *Router) Handle(path string, handler http.Handler) *Route { - return r.NewRoute().Path(path).Handler(handler) -} - -// HandleFunc registers a new route with a matcher for the URL path. -// See Route.Path() and Route.HandlerFunc(). -func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, - *http.Request)) *Route { - return r.NewRoute().Path(path).HandlerFunc(f) -} - -// Headers registers a new route with a matcher for request header values. -// See Route.Headers(). -func (r *Router) Headers(pairs ...string) *Route { - return r.NewRoute().Headers(pairs...) -} - -// Host registers a new route with a matcher for the URL host. -// See Route.Host(). -func (r *Router) Host(tpl string) *Route { - return r.NewRoute().Host(tpl) -} - -// MatcherFunc registers a new route with a custom matcher function. -// See Route.MatcherFunc(). -func (r *Router) MatcherFunc(f MatcherFunc) *Route { - return r.NewRoute().MatcherFunc(f) -} - -// Methods registers a new route with a matcher for HTTP methods. -// See Route.Methods(). -func (r *Router) Methods(methods ...string) *Route { - return r.NewRoute().Methods(methods...) -} - -// Path registers a new route with a matcher for the URL path. -// See Route.Path(). -func (r *Router) Path(tpl string) *Route { - return r.NewRoute().Path(tpl) -} - -// PathPrefix registers a new route with a matcher for the URL path prefix. -// See Route.PathPrefix(). -func (r *Router) PathPrefix(tpl string) *Route { - return r.NewRoute().PathPrefix(tpl) -} - -// Queries registers a new route with a matcher for URL query values. -// See Route.Queries(). -func (r *Router) Queries(pairs ...string) *Route { - return r.NewRoute().Queries(pairs...) -} - -// Schemes registers a new route with a matcher for URL schemes. -// See Route.Schemes(). -func (r *Router) Schemes(schemes ...string) *Route { - return r.NewRoute().Schemes(schemes...) -} - -// BuildVars registers a new route with a custom function for modifying -// route variables before building a URL. -func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route { - return r.NewRoute().BuildVarsFunc(f) -} - -// ---------------------------------------------------------------------------- -// Context -// ---------------------------------------------------------------------------- - -// RouteMatch stores information about a matched route. -type RouteMatch struct { - Route *Route - Handler http.Handler - Vars map[string]string -} - -type contextKey int - -const ( - varsKey contextKey = iota - routeKey -) - -// Vars returns the route variables for the current request, if any. -func Vars(r *http.Request) map[string]string { - if rv := context.Get(r, varsKey); rv != nil { - return rv.(map[string]string) - } - return nil -} - -// CurrentRoute returns the matched route for the current request, if any. -func CurrentRoute(r *http.Request) *Route { - if rv := context.Get(r, routeKey); rv != nil { - return rv.(*Route) - } - return nil -} - -func setVars(r *http.Request, val interface{}) { - context.Set(r, varsKey, val) -} - -func setCurrentRoute(r *http.Request, val interface{}) { - context.Set(r, routeKey, val) -} - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -// cleanPath returns the canonical path for p, eliminating . and .. elements. -// Borrowed from the net/http package. -func cleanPath(p string) string { - if p == "" { - return "/" - } - if p[0] != '/' { - p = "/" + p - } - np := path.Clean(p) - // path.Clean removes trailing slash except for root; - // put the trailing slash back if necessary. - if p[len(p)-1] == '/' && np != "/" { - np += "/" - } - return np -} - -// uniqueVars returns an error if two slices contain duplicated strings. -func uniqueVars(s1, s2 []string) error { - for _, v1 := range s1 { - for _, v2 := range s2 { - if v1 == v2 { - return fmt.Errorf("mux: duplicated route variable %q", v2) - } - } - } - return nil -} - -// mapFromPairs converts variadic string parameters to a string map. -func mapFromPairs(pairs ...string) (map[string]string, error) { - length := len(pairs) - if length%2 != 0 { - return nil, fmt.Errorf( - "mux: number of parameters must be multiple of 2, got %v", pairs) - } - m := make(map[string]string, length/2) - for i := 0; i < length; i += 2 { - m[pairs[i]] = pairs[i+1] - } - return m, nil -} - -// matchInArray returns true if the given string value is in the array. -func matchInArray(arr []string, value string) bool { - for _, v := range arr { - if v == value { - return true - } - } - return false -} - -// matchMap returns true if the given key/value pairs exist in a given map. -func matchMap(toCheck map[string]string, toMatch map[string][]string, - canonicalKey bool) bool { - for k, v := range toCheck { - // Check if key exists. - if canonicalKey { - k = http.CanonicalHeaderKey(k) - } - if values := toMatch[k]; values == nil { - return false - } else if v != "" { - // If value was defined as an empty string we only check that the - // key exists. Otherwise we also check for equality. - valueExists := false - for _, value := range values { - if v == value { - valueExists = true - break - } - } - if !valueExists { - return false - } - } - } - return true -} diff --git a/_third_party/github.com/gorilla/mux/mux_test.go b/_third_party/github.com/gorilla/mux/mux_test.go deleted file mode 100644 index 4c7262ec..00000000 --- a/_third_party/github.com/gorilla/mux/mux_test.go +++ /dev/null @@ -1,1048 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import ( - "fmt" - "net/http" - "testing" - - "github.com/mjibson/goread/_third_party/github.com/gorilla/context" -) - -type routeTest struct { - title string // title of the test - route *Route // the route being tested - request *http.Request // a request to test the route - vars map[string]string // the expected vars of the match - host string // the expected host of the match - path string // the expected path of the match - shouldMatch bool // whether the request is expected to match the route at all - shouldRedirect bool // whether the request should result in a redirect -} - -func TestHost(t *testing.T) { - // newRequestHost a new request with a method, url, and host header - newRequestHost := func(method, url, host string) *http.Request { - req, err := http.NewRequest(method, url, nil) - if err != nil { - panic(err) - } - req.Host = host - return req - } - - tests := []routeTest{ - { - title: "Host route match", - route: new(Route).Host("aaa.bbb.ccc"), - request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), - vars: map[string]string{}, - host: "aaa.bbb.ccc", - path: "", - shouldMatch: true, - }, - { - title: "Host route, wrong host in request URL", - route: new(Route).Host("aaa.bbb.ccc"), - request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), - vars: map[string]string{}, - host: "aaa.bbb.ccc", - path: "", - shouldMatch: false, - }, - { - title: "Host route with port, match", - route: new(Route).Host("aaa.bbb.ccc:1234"), - request: newRequest("GET", "http://aaa.bbb.ccc:1234/111/222/333"), - vars: map[string]string{}, - host: "aaa.bbb.ccc:1234", - path: "", - shouldMatch: true, - }, - { - title: "Host route with port, wrong port in request URL", - route: new(Route).Host("aaa.bbb.ccc:1234"), - request: newRequest("GET", "http://aaa.bbb.ccc:9999/111/222/333"), - vars: map[string]string{}, - host: "aaa.bbb.ccc:1234", - path: "", - shouldMatch: false, - }, - { - title: "Host route, match with host in request header", - route: new(Route).Host("aaa.bbb.ccc"), - request: newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc"), - vars: map[string]string{}, - host: "aaa.bbb.ccc", - path: "", - shouldMatch: true, - }, - { - title: "Host route, wrong host in request header", - route: new(Route).Host("aaa.bbb.ccc"), - request: newRequestHost("GET", "/111/222/333", "aaa.222.ccc"), - vars: map[string]string{}, - host: "aaa.bbb.ccc", - path: "", - shouldMatch: false, - }, - // BUG {new(Route).Host("aaa.bbb.ccc:1234"), newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:1234"), map[string]string{}, "aaa.bbb.ccc:1234", "", true}, - { - title: "Host route with port, wrong host in request header", - route: new(Route).Host("aaa.bbb.ccc:1234"), - request: newRequestHost("GET", "/111/222/333", "aaa.bbb.ccc:9999"), - vars: map[string]string{}, - host: "aaa.bbb.ccc:1234", - path: "", - shouldMatch: false, - }, - { - title: "Host route with pattern, match", - route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc"), - request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), - vars: map[string]string{"v1": "bbb"}, - host: "aaa.bbb.ccc", - path: "", - shouldMatch: true, - }, - { - title: "Host route with pattern, wrong host in request URL", - route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc"), - request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), - vars: map[string]string{"v1": "bbb"}, - host: "aaa.bbb.ccc", - path: "", - shouldMatch: false, - }, - { - title: "Host route with multiple patterns, match", - route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}"), - request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), - vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc"}, - host: "aaa.bbb.ccc", - path: "", - shouldMatch: true, - }, - { - title: "Host route with multiple patterns, wrong host in request URL", - route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}"), - request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), - vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc"}, - host: "aaa.bbb.ccc", - path: "", - shouldMatch: false, - }, - { - title: "Path route with single pattern with pipe, match", - route: new(Route).Path("/{category:a|b/c}"), - request: newRequest("GET", "http://localhost/a"), - vars: map[string]string{"category": "a"}, - host: "", - path: "/a", - shouldMatch: true, - }, - { - title: "Path route with single pattern with pipe, match", - route: new(Route).Path("/{category:a|b/c}"), - request: newRequest("GET", "http://localhost/b/c"), - vars: map[string]string{"category": "b/c"}, - host: "", - path: "/b/c", - shouldMatch: true, - }, - { - title: "Path route with multiple patterns with pipe, match", - route: new(Route).Path("/{category:a|b/c}/{product}/{id:[0-9]+}"), - request: newRequest("GET", "http://localhost/a/product_name/1"), - vars: map[string]string{"category": "a", "product": "product_name", "id": "1"}, - host: "", - path: "/a/product_name/1", - shouldMatch: true, - }, - { - title: "Path route with multiple patterns with pipe, match", - route: new(Route).Path("/{category:a|b/c}/{product}/{id:[0-9]+}"), - request: newRequest("GET", "http://localhost/b/c/product_name/1"), - vars: map[string]string{"category": "b/c", "product": "product_name", "id": "1"}, - host: "", - path: "/b/c/product_name/1", - shouldMatch: true, - }, - } - for _, test := range tests { - testRoute(t, test) - } -} - -func TestPath(t *testing.T) { - tests := []routeTest{ - { - title: "Path route, match", - route: new(Route).Path("/111/222/333"), - request: newRequest("GET", "http://localhost/111/222/333"), - vars: map[string]string{}, - host: "", - path: "/111/222/333", - shouldMatch: true, - }, - { - title: "Path route, match with trailing slash in request and path", - route: new(Route).Path("/111/"), - request: newRequest("GET", "http://localhost/111/"), - vars: map[string]string{}, - host: "", - path: "/111/", - shouldMatch: true, - }, - { - title: "Path route, do not match with trailing slash in path", - route: new(Route).Path("/111/"), - request: newRequest("GET", "http://localhost/111"), - vars: map[string]string{}, - host: "", - path: "/111", - shouldMatch: false, - }, - { - title: "Path route, do not match with trailing slash in request", - route: new(Route).Path("/111"), - request: newRequest("GET", "http://localhost/111/"), - vars: map[string]string{}, - host: "", - path: "/111/", - shouldMatch: false, - }, - { - title: "Path route, wrong path in request in request URL", - route: new(Route).Path("/111/222/333"), - request: newRequest("GET", "http://localhost/1/2/3"), - vars: map[string]string{}, - host: "", - path: "/111/222/333", - shouldMatch: false, - }, - { - title: "Path route with pattern, match", - route: new(Route).Path("/111/{v1:[0-9]{3}}/333"), - request: newRequest("GET", "http://localhost/111/222/333"), - vars: map[string]string{"v1": "222"}, - host: "", - path: "/111/222/333", - shouldMatch: true, - }, - { - title: "Path route with pattern, URL in request does not match", - route: new(Route).Path("/111/{v1:[0-9]{3}}/333"), - request: newRequest("GET", "http://localhost/111/aaa/333"), - vars: map[string]string{"v1": "222"}, - host: "", - path: "/111/222/333", - shouldMatch: false, - }, - { - title: "Path route with multiple patterns, match", - route: new(Route).Path("/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}"), - request: newRequest("GET", "http://localhost/111/222/333"), - vars: map[string]string{"v1": "111", "v2": "222", "v3": "333"}, - host: "", - path: "/111/222/333", - shouldMatch: true, - }, - { - title: "Path route with multiple patterns, URL in request does not match", - route: new(Route).Path("/{v1:[0-9]{3}}/{v2:[0-9]{3}}/{v3:[0-9]{3}}"), - request: newRequest("GET", "http://localhost/111/aaa/333"), - vars: map[string]string{"v1": "111", "v2": "222", "v3": "333"}, - host: "", - path: "/111/222/333", - shouldMatch: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -func TestPathPrefix(t *testing.T) { - tests := []routeTest{ - { - title: "PathPrefix route, match", - route: new(Route).PathPrefix("/111"), - request: newRequest("GET", "http://localhost/111/222/333"), - vars: map[string]string{}, - host: "", - path: "/111", - shouldMatch: true, - }, - { - title: "PathPrefix route, match substring", - route: new(Route).PathPrefix("/1"), - request: newRequest("GET", "http://localhost/111/222/333"), - vars: map[string]string{}, - host: "", - path: "/1", - shouldMatch: true, - }, - { - title: "PathPrefix route, URL prefix in request does not match", - route: new(Route).PathPrefix("/111"), - request: newRequest("GET", "http://localhost/1/2/3"), - vars: map[string]string{}, - host: "", - path: "/111", - shouldMatch: false, - }, - { - title: "PathPrefix route with pattern, match", - route: new(Route).PathPrefix("/111/{v1:[0-9]{3}}"), - request: newRequest("GET", "http://localhost/111/222/333"), - vars: map[string]string{"v1": "222"}, - host: "", - path: "/111/222", - shouldMatch: true, - }, - { - title: "PathPrefix route with pattern, URL prefix in request does not match", - route: new(Route).PathPrefix("/111/{v1:[0-9]{3}}"), - request: newRequest("GET", "http://localhost/111/aaa/333"), - vars: map[string]string{"v1": "222"}, - host: "", - path: "/111/222", - shouldMatch: false, - }, - { - title: "PathPrefix route with multiple patterns, match", - route: new(Route).PathPrefix("/{v1:[0-9]{3}}/{v2:[0-9]{3}}"), - request: newRequest("GET", "http://localhost/111/222/333"), - vars: map[string]string{"v1": "111", "v2": "222"}, - host: "", - path: "/111/222", - shouldMatch: true, - }, - { - title: "PathPrefix route with multiple patterns, URL prefix in request does not match", - route: new(Route).PathPrefix("/{v1:[0-9]{3}}/{v2:[0-9]{3}}"), - request: newRequest("GET", "http://localhost/111/aaa/333"), - vars: map[string]string{"v1": "111", "v2": "222"}, - host: "", - path: "/111/222", - shouldMatch: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -func TestHostPath(t *testing.T) { - tests := []routeTest{ - { - title: "Host and Path route, match", - route: new(Route).Host("aaa.bbb.ccc").Path("/111/222/333"), - request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Host and Path route, wrong host in request URL", - route: new(Route).Host("aaa.bbb.ccc").Path("/111/222/333"), - request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - { - title: "Host and Path route with pattern, match", - route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"), - request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), - vars: map[string]string{"v1": "bbb", "v2": "222"}, - host: "aaa.bbb.ccc", - path: "/111/222/333", - shouldMatch: true, - }, - { - title: "Host and Path route with pattern, URL in request does not match", - route: new(Route).Host("aaa.{v1:[a-z]{3}}.ccc").Path("/111/{v2:[0-9]{3}}/333"), - request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), - vars: map[string]string{"v1": "bbb", "v2": "222"}, - host: "aaa.bbb.ccc", - path: "/111/222/333", - shouldMatch: false, - }, - { - title: "Host and Path route with multiple patterns, match", - route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}").Path("/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}"), - request: newRequest("GET", "http://aaa.bbb.ccc/111/222/333"), - vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc", "v4": "111", "v5": "222", "v6": "333"}, - host: "aaa.bbb.ccc", - path: "/111/222/333", - shouldMatch: true, - }, - { - title: "Host and Path route with multiple patterns, URL in request does not match", - route: new(Route).Host("{v1:[a-z]{3}}.{v2:[a-z]{3}}.{v3:[a-z]{3}}").Path("/{v4:[0-9]{3}}/{v5:[0-9]{3}}/{v6:[0-9]{3}}"), - request: newRequest("GET", "http://aaa.222.ccc/111/222/333"), - vars: map[string]string{"v1": "aaa", "v2": "bbb", "v3": "ccc", "v4": "111", "v5": "222", "v6": "333"}, - host: "aaa.bbb.ccc", - path: "/111/222/333", - shouldMatch: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -func TestHeaders(t *testing.T) { - // newRequestHeaders creates a new request with a method, url, and headers - newRequestHeaders := func(method, url string, headers map[string]string) *http.Request { - req, err := http.NewRequest(method, url, nil) - if err != nil { - panic(err) - } - for k, v := range headers { - req.Header.Add(k, v) - } - return req - } - - tests := []routeTest{ - { - title: "Headers route, match", - route: new(Route).Headers("foo", "bar", "baz", "ding"), - request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar", "baz": "ding"}), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Headers route, bad header values", - route: new(Route).Headers("foo", "bar", "baz", "ding"), - request: newRequestHeaders("GET", "http://localhost", map[string]string{"foo": "bar", "baz": "dong"}), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } - -} - -func TestMethods(t *testing.T) { - tests := []routeTest{ - { - title: "Methods route, match GET", - route: new(Route).Methods("GET", "POST"), - request: newRequest("GET", "http://localhost"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Methods route, match POST", - route: new(Route).Methods("GET", "POST"), - request: newRequest("POST", "http://localhost"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Methods route, bad method", - route: new(Route).Methods("GET", "POST"), - request: newRequest("PUT", "http://localhost"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -func TestQueries(t *testing.T) { - tests := []routeTest{ - { - title: "Queries route, match", - route: new(Route).Queries("foo", "bar", "baz", "ding"), - request: newRequest("GET", "http://localhost?foo=bar&baz=ding"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Queries route, match with a query string", - route: new(Route).Host("www.example.com").Path("/api").Queries("foo", "bar", "baz", "ding"), - request: newRequest("GET", "http://www.example.com/api?foo=bar&baz=ding"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Queries route, match with a query string out of order", - route: new(Route).Host("www.example.com").Path("/api").Queries("foo", "bar", "baz", "ding"), - request: newRequest("GET", "http://www.example.com/api?baz=ding&foo=bar"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Queries route, bad query", - route: new(Route).Queries("foo", "bar", "baz", "ding"), - request: newRequest("GET", "http://localhost?foo=bar&baz=dong"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - { - title: "Queries route with pattern, match", - route: new(Route).Queries("foo", "{v1}"), - request: newRequest("GET", "http://localhost?foo=bar"), - vars: map[string]string{"v1": "bar"}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Queries route with multiple patterns, match", - route: new(Route).Queries("foo", "{v1}", "baz", "{v2}"), - request: newRequest("GET", "http://localhost?foo=bar&baz=ding"), - vars: map[string]string{"v1": "bar", "v2": "ding"}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Queries route with regexp pattern, match", - route: new(Route).Queries("foo", "{v1:[0-9]+}"), - request: newRequest("GET", "http://localhost?foo=10"), - vars: map[string]string{"v1": "10"}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Queries route with regexp pattern, regexp does not match", - route: new(Route).Queries("foo", "{v1:[0-9]+}"), - request: newRequest("GET", "http://localhost?foo=a"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - { - title: "Queries route with regexp pattern with quantifier, match", - route: new(Route).Queries("foo", "{v1:[0-9]{1}}"), - request: newRequest("GET", "http://localhost?foo=1"), - vars: map[string]string{"v1": "1"}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Queries route with regexp pattern with quantifier, additional variable in query string, match", - route: new(Route).Queries("foo", "{v1:[0-9]{1}}"), - request: newRequest("GET", "http://localhost?bar=2&foo=1"), - vars: map[string]string{"v1": "1"}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Queries route with regexp pattern with quantifier, regexp does not match", - route: new(Route).Queries("foo", "{v1:[0-9]{1}}"), - request: newRequest("GET", "http://localhost?foo=12"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - { - title: "Queries route with regexp pattern with quantifier, additional variable in query string, regexp does not match", - route: new(Route).Queries("foo", "{v1:[0-9]{1}}"), - request: newRequest("GET", "http://localhost?foo=12"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -func TestSchemes(t *testing.T) { - tests := []routeTest{ - // Schemes - { - title: "Schemes route, match https", - route: new(Route).Schemes("https", "ftp"), - request: newRequest("GET", "https://localhost"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Schemes route, match ftp", - route: new(Route).Schemes("https", "ftp"), - request: newRequest("GET", "ftp://localhost"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "Schemes route, bad scheme", - route: new(Route).Schemes("https", "ftp"), - request: newRequest("GET", "http://localhost"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - } - for _, test := range tests { - testRoute(t, test) - } -} - -func TestMatcherFunc(t *testing.T) { - m := func(r *http.Request, m *RouteMatch) bool { - if r.URL.Host == "aaa.bbb.ccc" { - return true - } - return false - } - - tests := []routeTest{ - { - title: "MatchFunc route, match", - route: new(Route).MatcherFunc(m), - request: newRequest("GET", "http://aaa.bbb.ccc"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: true, - }, - { - title: "MatchFunc route, non-match", - route: new(Route).MatcherFunc(m), - request: newRequest("GET", "http://aaa.222.ccc"), - vars: map[string]string{}, - host: "", - path: "", - shouldMatch: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -func TestBuildVarsFunc(t *testing.T) { - tests := []routeTest{ - { - title: "BuildVarsFunc set on route", - route: new(Route).Path(`/111/{v1:\d}{v2:.*}`).BuildVarsFunc(func(vars map[string]string) map[string]string { - vars["v1"] = "3" - vars["v2"] = "a" - return vars - }), - request: newRequest("GET", "http://localhost/111/2"), - path: "/111/3a", - shouldMatch: true, - }, - { - title: "BuildVarsFunc set on route and parent route", - route: new(Route).PathPrefix(`/{v1:\d}`).BuildVarsFunc(func(vars map[string]string) map[string]string { - vars["v1"] = "2" - return vars - }).Subrouter().Path(`/{v2:\w}`).BuildVarsFunc(func(vars map[string]string) map[string]string { - vars["v2"] = "b" - return vars - }), - request: newRequest("GET", "http://localhost/1/a"), - path: "/2/b", - shouldMatch: true, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -func TestSubRouter(t *testing.T) { - subrouter1 := new(Route).Host("{v1:[a-z]+}.google.com").Subrouter() - subrouter2 := new(Route).PathPrefix("/foo/{v1}").Subrouter() - - tests := []routeTest{ - { - route: subrouter1.Path("/{v2:[a-z]+}"), - request: newRequest("GET", "http://aaa.google.com/bbb"), - vars: map[string]string{"v1": "aaa", "v2": "bbb"}, - host: "aaa.google.com", - path: "/bbb", - shouldMatch: true, - }, - { - route: subrouter1.Path("/{v2:[a-z]+}"), - request: newRequest("GET", "http://111.google.com/111"), - vars: map[string]string{"v1": "aaa", "v2": "bbb"}, - host: "aaa.google.com", - path: "/bbb", - shouldMatch: false, - }, - { - route: subrouter2.Path("/baz/{v2}"), - request: newRequest("GET", "http://localhost/foo/bar/baz/ding"), - vars: map[string]string{"v1": "bar", "v2": "ding"}, - host: "", - path: "/foo/bar/baz/ding", - shouldMatch: true, - }, - { - route: subrouter2.Path("/baz/{v2}"), - request: newRequest("GET", "http://localhost/foo/bar"), - vars: map[string]string{"v1": "bar", "v2": "ding"}, - host: "", - path: "/foo/bar/baz/ding", - shouldMatch: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -func TestNamedRoutes(t *testing.T) { - r1 := NewRouter() - r1.NewRoute().Name("a") - r1.NewRoute().Name("b") - r1.NewRoute().Name("c") - - r2 := r1.NewRoute().Subrouter() - r2.NewRoute().Name("d") - r2.NewRoute().Name("e") - r2.NewRoute().Name("f") - - r3 := r2.NewRoute().Subrouter() - r3.NewRoute().Name("g") - r3.NewRoute().Name("h") - r3.NewRoute().Name("i") - - if r1.namedRoutes == nil || len(r1.namedRoutes) != 9 { - t.Errorf("Expected 9 named routes, got %v", r1.namedRoutes) - } else if r1.Get("i") == nil { - t.Errorf("Subroute name not registered") - } -} - -func TestStrictSlash(t *testing.T) { - r := NewRouter() - r.StrictSlash(true) - - tests := []routeTest{ - { - title: "Redirect path without slash", - route: r.NewRoute().Path("/111/"), - request: newRequest("GET", "http://localhost/111"), - vars: map[string]string{}, - host: "", - path: "/111/", - shouldMatch: true, - shouldRedirect: true, - }, - { - title: "Do not redirect path with slash", - route: r.NewRoute().Path("/111/"), - request: newRequest("GET", "http://localhost/111/"), - vars: map[string]string{}, - host: "", - path: "/111/", - shouldMatch: true, - shouldRedirect: false, - }, - { - title: "Redirect path with slash", - route: r.NewRoute().Path("/111"), - request: newRequest("GET", "http://localhost/111/"), - vars: map[string]string{}, - host: "", - path: "/111", - shouldMatch: true, - shouldRedirect: true, - }, - { - title: "Do not redirect path without slash", - route: r.NewRoute().Path("/111"), - request: newRequest("GET", "http://localhost/111"), - vars: map[string]string{}, - host: "", - path: "/111", - shouldMatch: true, - shouldRedirect: false, - }, - { - title: "Propagate StrictSlash to subrouters", - route: r.NewRoute().PathPrefix("/static/").Subrouter().Path("/images/"), - request: newRequest("GET", "http://localhost/static/images"), - vars: map[string]string{}, - host: "", - path: "/static/images/", - shouldMatch: true, - shouldRedirect: true, - }, - { - title: "Ignore StrictSlash for path prefix", - route: r.NewRoute().PathPrefix("/static/"), - request: newRequest("GET", "http://localhost/static/logo.png"), - vars: map[string]string{}, - host: "", - path: "/static/", - shouldMatch: true, - shouldRedirect: false, - }, - } - - for _, test := range tests { - testRoute(t, test) - } -} - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -func getRouteTemplate(route *Route) string { - host, path := "none", "none" - if route.regexp != nil { - if route.regexp.host != nil { - host = route.regexp.host.template - } - if route.regexp.path != nil { - path = route.regexp.path.template - } - } - return fmt.Sprintf("Host: %v, Path: %v", host, path) -} - -func testRoute(t *testing.T, test routeTest) { - request := test.request - route := test.route - vars := test.vars - shouldMatch := test.shouldMatch - host := test.host - path := test.path - url := test.host + test.path - shouldRedirect := test.shouldRedirect - - var match RouteMatch - ok := route.Match(request, &match) - if ok != shouldMatch { - msg := "Should match" - if !shouldMatch { - msg = "Should not match" - } - t.Errorf("(%v) %v:\nRoute: %#v\nRequest: %#v\nVars: %v\n", test.title, msg, route, request, vars) - return - } - if shouldMatch { - if test.vars != nil && !stringMapEqual(test.vars, match.Vars) { - t.Errorf("(%v) Vars not equal: expected %v, got %v", test.title, vars, match.Vars) - return - } - if host != "" { - u, _ := test.route.URLHost(mapToPairs(match.Vars)...) - if host != u.Host { - t.Errorf("(%v) URLHost not equal: expected %v, got %v -- %v", test.title, host, u.Host, getRouteTemplate(route)) - return - } - } - if path != "" { - u, _ := route.URLPath(mapToPairs(match.Vars)...) - if path != u.Path { - t.Errorf("(%v) URLPath not equal: expected %v, got %v -- %v", test.title, path, u.Path, getRouteTemplate(route)) - return - } - } - if url != "" { - u, _ := route.URL(mapToPairs(match.Vars)...) - if url != u.Host+u.Path { - t.Errorf("(%v) URL not equal: expected %v, got %v -- %v", test.title, url, u.Host+u.Path, getRouteTemplate(route)) - return - } - } - if shouldRedirect && match.Handler == nil { - t.Errorf("(%v) Did not redirect", test.title) - return - } - if !shouldRedirect && match.Handler != nil { - t.Errorf("(%v) Unexpected redirect", test.title) - return - } - } -} - -// Tests that the context is cleared or not cleared properly depending on -// the configuration of the router -func TestKeepContext(t *testing.T) { - func1 := func(w http.ResponseWriter, r *http.Request) {} - - r := NewRouter() - r.HandleFunc("/", func1).Name("func1") - - req, _ := http.NewRequest("GET", "http://localhost/", nil) - context.Set(req, "t", 1) - - res := new(http.ResponseWriter) - r.ServeHTTP(*res, req) - - if _, ok := context.GetOk(req, "t"); ok { - t.Error("Context should have been cleared at end of request") - } - - r.KeepContext = true - - req, _ = http.NewRequest("GET", "http://localhost/", nil) - context.Set(req, "t", 1) - - r.ServeHTTP(*res, req) - if _, ok := context.GetOk(req, "t"); !ok { - t.Error("Context should NOT have been cleared at end of request") - } - -} - -type TestA301ResponseWriter struct { - hh http.Header - status int -} - -func (ho TestA301ResponseWriter) Header() http.Header { - return http.Header(ho.hh) -} - -func (ho TestA301ResponseWriter) Write(b []byte) (int, error) { - return 0, nil -} - -func (ho TestA301ResponseWriter) WriteHeader(code int) { - ho.status = code -} - -func Test301Redirect(t *testing.T) { - m := make(http.Header) - - func1 := func(w http.ResponseWriter, r *http.Request) {} - func2 := func(w http.ResponseWriter, r *http.Request) {} - - r := NewRouter() - r.HandleFunc("/api/", func2).Name("func2") - r.HandleFunc("/", func1).Name("func1") - - req, _ := http.NewRequest("GET", "http://localhost//api/?abc=def", nil) - - res := TestA301ResponseWriter{ - hh: m, - status: 0, - } - r.ServeHTTP(&res, req) - - if "http://localhost/api/?abc=def" != res.hh["Location"][0] { - t.Errorf("Should have complete URL with query string") - } -} - -// https://plus.google.com/101022900381697718949/posts/eWy6DjFJ6uW -func TestSubrouterHeader(t *testing.T) { - expected := "func1 response" - func1 := func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, expected) - } - func2 := func(http.ResponseWriter, *http.Request) {} - - r := NewRouter() - s := r.Headers("SomeSpecialHeader", "").Subrouter() - s.HandleFunc("/", func1).Name("func1") - r.HandleFunc("/", func2).Name("func2") - - req, _ := http.NewRequest("GET", "http://localhost/", nil) - req.Header.Add("SomeSpecialHeader", "foo") - match := new(RouteMatch) - matched := r.Match(req, match) - if !matched { - t.Errorf("Should match request") - } - if match.Route.GetName() != "func1" { - t.Errorf("Expecting func1 handler, got %s", match.Route.GetName()) - } - resp := NewRecorder() - match.Handler.ServeHTTP(resp, req) - if resp.Body.String() != expected { - t.Errorf("Expecting %q", expected) - } -} - -// mapToPairs converts a string map to a slice of string pairs -func mapToPairs(m map[string]string) []string { - var i int - p := make([]string, len(m)*2) - for k, v := range m { - p[i] = k - p[i+1] = v - i += 2 - } - return p -} - -// stringMapEqual checks the equality of two string maps -func stringMapEqual(m1, m2 map[string]string) bool { - nil1 := m1 == nil - nil2 := m2 == nil - if nil1 != nil2 || len(m1) != len(m2) { - return false - } - for k, v := range m1 { - if v != m2[k] { - return false - } - } - return true -} - -// newRequest is a helper function to create a new request with a method and url -func newRequest(method, url string) *http.Request { - req, err := http.NewRequest(method, url, nil) - if err != nil { - panic(err) - } - return req -} diff --git a/_third_party/github.com/gorilla/mux/old_test.go b/_third_party/github.com/gorilla/mux/old_test.go deleted file mode 100644 index 1f7c190c..00000000 --- a/_third_party/github.com/gorilla/mux/old_test.go +++ /dev/null @@ -1,714 +0,0 @@ -// Old tests ported to Go1. This is a mess. Want to drop it one day. - -// Copyright 2011 Gorilla 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 mux - -import ( - "bytes" - "net/http" - "testing" -) - -// ---------------------------------------------------------------------------- -// ResponseRecorder -// ---------------------------------------------------------------------------- -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// ResponseRecorder is an implementation of http.ResponseWriter that -// records its mutations for later inspection in tests. -type ResponseRecorder struct { - Code int // the HTTP response code from WriteHeader - HeaderMap http.Header // the HTTP response headers - Body *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to - Flushed bool -} - -// NewRecorder returns an initialized ResponseRecorder. -func NewRecorder() *ResponseRecorder { - return &ResponseRecorder{ - HeaderMap: make(http.Header), - Body: new(bytes.Buffer), - } -} - -// DefaultRemoteAddr is the default remote address to return in RemoteAddr if -// an explicit DefaultRemoteAddr isn't set on ResponseRecorder. -const DefaultRemoteAddr = "1.2.3.4" - -// Header returns the response headers. -func (rw *ResponseRecorder) Header() http.Header { - return rw.HeaderMap -} - -// Write always succeeds and writes to rw.Body, if not nil. -func (rw *ResponseRecorder) Write(buf []byte) (int, error) { - if rw.Body != nil { - rw.Body.Write(buf) - } - if rw.Code == 0 { - rw.Code = http.StatusOK - } - return len(buf), nil -} - -// WriteHeader sets rw.Code. -func (rw *ResponseRecorder) WriteHeader(code int) { - rw.Code = code -} - -// Flush sets rw.Flushed to true. -func (rw *ResponseRecorder) Flush() { - rw.Flushed = true -} - -// ---------------------------------------------------------------------------- - -func TestRouteMatchers(t *testing.T) { - var scheme, host, path, query, method string - var headers map[string]string - var resultVars map[bool]map[string]string - - router := NewRouter() - router.NewRoute().Host("{var1}.google.com"). - Path("/{var2:[a-z]+}/{var3:[0-9]+}"). - Queries("foo", "bar"). - Methods("GET"). - Schemes("https"). - Headers("x-requested-with", "XMLHttpRequest") - router.NewRoute().Host("www.{var4}.com"). - PathPrefix("/foo/{var5:[a-z]+}/{var6:[0-9]+}"). - Queries("baz", "ding"). - Methods("POST"). - Schemes("http"). - Headers("Content-Type", "application/json") - - reset := func() { - // Everything match. - scheme = "https" - host = "www.google.com" - path = "/product/42" - query = "?foo=bar" - method = "GET" - headers = map[string]string{"X-Requested-With": "XMLHttpRequest"} - resultVars = map[bool]map[string]string{ - true: {"var1": "www", "var2": "product", "var3": "42"}, - false: {}, - } - } - - reset2 := func() { - // Everything match. - scheme = "http" - host = "www.google.com" - path = "/foo/product/42/path/that/is/ignored" - query = "?baz=ding" - method = "POST" - headers = map[string]string{"Content-Type": "application/json"} - resultVars = map[bool]map[string]string{ - true: {"var4": "google", "var5": "product", "var6": "42"}, - false: {}, - } - } - - match := func(shouldMatch bool) { - url := scheme + "://" + host + path + query - request, _ := http.NewRequest(method, url, nil) - for key, value := range headers { - request.Header.Add(key, value) - } - - var routeMatch RouteMatch - matched := router.Match(request, &routeMatch) - if matched != shouldMatch { - // Need better messages. :) - if matched { - t.Errorf("Should match.") - } else { - t.Errorf("Should not match.") - } - } - - if matched { - currentRoute := routeMatch.Route - if currentRoute == nil { - t.Errorf("Expected a current route.") - } - vars := routeMatch.Vars - expectedVars := resultVars[shouldMatch] - if len(vars) != len(expectedVars) { - t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars) - } - for name, value := range vars { - if expectedVars[name] != value { - t.Errorf("Expected vars: %v Got: %v.", expectedVars, vars) - } - } - } - } - - // 1st route -------------------------------------------------------------- - - // Everything match. - reset() - match(true) - - // Scheme doesn't match. - reset() - scheme = "http" - match(false) - - // Host doesn't match. - reset() - host = "www.mygoogle.com" - match(false) - - // Path doesn't match. - reset() - path = "/product/notdigits" - match(false) - - // Query doesn't match. - reset() - query = "?foo=baz" - match(false) - - // Method doesn't match. - reset() - method = "POST" - match(false) - - // Header doesn't match. - reset() - headers = map[string]string{} - match(false) - - // Everything match, again. - reset() - match(true) - - // 2nd route -------------------------------------------------------------- - - // Everything match. - reset2() - match(true) - - // Scheme doesn't match. - reset2() - scheme = "https" - match(false) - - // Host doesn't match. - reset2() - host = "sub.google.com" - match(false) - - // Path doesn't match. - reset2() - path = "/bar/product/42" - match(false) - - // Query doesn't match. - reset2() - query = "?foo=baz" - match(false) - - // Method doesn't match. - reset2() - method = "GET" - match(false) - - // Header doesn't match. - reset2() - headers = map[string]string{} - match(false) - - // Everything match, again. - reset2() - match(true) -} - -type headerMatcherTest struct { - matcher headerMatcher - headers map[string]string - result bool -} - -var headerMatcherTests = []headerMatcherTest{ - { - matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}), - headers: map[string]string{"X-Requested-With": "XMLHttpRequest"}, - result: true, - }, - { - matcher: headerMatcher(map[string]string{"x-requested-with": ""}), - headers: map[string]string{"X-Requested-With": "anything"}, - result: true, - }, - { - matcher: headerMatcher(map[string]string{"x-requested-with": "XMLHttpRequest"}), - headers: map[string]string{}, - result: false, - }, -} - -type hostMatcherTest struct { - matcher *Route - url string - vars map[string]string - result bool -} - -var hostMatcherTests = []hostMatcherTest{ - { - matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"), - url: "http://abc.def.ghi/", - vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"}, - result: true, - }, - { - matcher: NewRouter().NewRoute().Host("{foo:[a-z][a-z][a-z]}.{bar:[a-z][a-z][a-z]}.{baz:[a-z][a-z][a-z]}"), - url: "http://a.b.c/", - vars: map[string]string{"foo": "abc", "bar": "def", "baz": "ghi"}, - result: false, - }, -} - -type methodMatcherTest struct { - matcher methodMatcher - method string - result bool -} - -var methodMatcherTests = []methodMatcherTest{ - { - matcher: methodMatcher([]string{"GET", "POST", "PUT"}), - method: "GET", - result: true, - }, - { - matcher: methodMatcher([]string{"GET", "POST", "PUT"}), - method: "POST", - result: true, - }, - { - matcher: methodMatcher([]string{"GET", "POST", "PUT"}), - method: "PUT", - result: true, - }, - { - matcher: methodMatcher([]string{"GET", "POST", "PUT"}), - method: "DELETE", - result: false, - }, -} - -type pathMatcherTest struct { - matcher *Route - url string - vars map[string]string - result bool -} - -var pathMatcherTests = []pathMatcherTest{ - { - matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"), - url: "http://localhost:8080/123/456/789", - vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"}, - result: true, - }, - { - matcher: NewRouter().NewRoute().Path("/{foo:[0-9][0-9][0-9]}/{bar:[0-9][0-9][0-9]}/{baz:[0-9][0-9][0-9]}"), - url: "http://localhost:8080/1/2/3", - vars: map[string]string{"foo": "123", "bar": "456", "baz": "789"}, - result: false, - }, -} - -type schemeMatcherTest struct { - matcher schemeMatcher - url string - result bool -} - -var schemeMatcherTests = []schemeMatcherTest{ - { - matcher: schemeMatcher([]string{"http", "https"}), - url: "http://localhost:8080/", - result: true, - }, - { - matcher: schemeMatcher([]string{"http", "https"}), - url: "https://localhost:8080/", - result: true, - }, - { - matcher: schemeMatcher([]string{"https"}), - url: "http://localhost:8080/", - result: false, - }, - { - matcher: schemeMatcher([]string{"http"}), - url: "https://localhost:8080/", - result: false, - }, -} - -type urlBuildingTest struct { - route *Route - vars []string - url string -} - -var urlBuildingTests = []urlBuildingTest{ - { - route: new(Route).Host("foo.domain.com"), - vars: []string{}, - url: "http://foo.domain.com", - }, - { - route: new(Route).Host("{subdomain}.domain.com"), - vars: []string{"subdomain", "bar"}, - url: "http://bar.domain.com", - }, - { - route: new(Route).Host("foo.domain.com").Path("/articles"), - vars: []string{}, - url: "http://foo.domain.com/articles", - }, - { - route: new(Route).Path("/articles"), - vars: []string{}, - url: "/articles", - }, - { - route: new(Route).Path("/articles/{category}/{id:[0-9]+}"), - vars: []string{"category", "technology", "id", "42"}, - url: "/articles/technology/42", - }, - { - route: new(Route).Host("{subdomain}.domain.com").Path("/articles/{category}/{id:[0-9]+}"), - vars: []string{"subdomain", "foo", "category", "technology", "id", "42"}, - url: "http://foo.domain.com/articles/technology/42", - }, -} - -func TestHeaderMatcher(t *testing.T) { - for _, v := range headerMatcherTests { - request, _ := http.NewRequest("GET", "http://localhost:8080/", nil) - for key, value := range v.headers { - request.Header.Add(key, value) - } - var routeMatch RouteMatch - result := v.matcher.Match(request, &routeMatch) - if result != v.result { - if v.result { - t.Errorf("%#v: should match %v.", v.matcher, request.Header) - } else { - t.Errorf("%#v: should not match %v.", v.matcher, request.Header) - } - } - } -} - -func TestHostMatcher(t *testing.T) { - for _, v := range hostMatcherTests { - request, _ := http.NewRequest("GET", v.url, nil) - var routeMatch RouteMatch - result := v.matcher.Match(request, &routeMatch) - vars := routeMatch.Vars - if result != v.result { - if v.result { - t.Errorf("%#v: should match %v.", v.matcher, v.url) - } else { - t.Errorf("%#v: should not match %v.", v.matcher, v.url) - } - } - if result { - if len(vars) != len(v.vars) { - t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars)) - } - for name, value := range vars { - if v.vars[name] != value { - t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value) - } - } - } else { - if len(vars) != 0 { - t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars)) - } - } - } -} - -func TestMethodMatcher(t *testing.T) { - for _, v := range methodMatcherTests { - request, _ := http.NewRequest(v.method, "http://localhost:8080/", nil) - var routeMatch RouteMatch - result := v.matcher.Match(request, &routeMatch) - if result != v.result { - if v.result { - t.Errorf("%#v: should match %v.", v.matcher, v.method) - } else { - t.Errorf("%#v: should not match %v.", v.matcher, v.method) - } - } - } -} - -func TestPathMatcher(t *testing.T) { - for _, v := range pathMatcherTests { - request, _ := http.NewRequest("GET", v.url, nil) - var routeMatch RouteMatch - result := v.matcher.Match(request, &routeMatch) - vars := routeMatch.Vars - if result != v.result { - if v.result { - t.Errorf("%#v: should match %v.", v.matcher, v.url) - } else { - t.Errorf("%#v: should not match %v.", v.matcher, v.url) - } - } - if result { - if len(vars) != len(v.vars) { - t.Errorf("%#v: vars length should be %v, got %v.", v.matcher, len(v.vars), len(vars)) - } - for name, value := range vars { - if v.vars[name] != value { - t.Errorf("%#v: expected value %v for key %v, got %v.", v.matcher, v.vars[name], name, value) - } - } - } else { - if len(vars) != 0 { - t.Errorf("%#v: vars length should be 0, got %v.", v.matcher, len(vars)) - } - } - } -} - -func TestSchemeMatcher(t *testing.T) { - for _, v := range schemeMatcherTests { - request, _ := http.NewRequest("GET", v.url, nil) - var routeMatch RouteMatch - result := v.matcher.Match(request, &routeMatch) - if result != v.result { - if v.result { - t.Errorf("%#v: should match %v.", v.matcher, v.url) - } else { - t.Errorf("%#v: should not match %v.", v.matcher, v.url) - } - } - } -} - -func TestUrlBuilding(t *testing.T) { - - for _, v := range urlBuildingTests { - u, _ := v.route.URL(v.vars...) - url := u.String() - if url != v.url { - t.Errorf("expected %v, got %v", v.url, url) - /* - reversePath := "" - reverseHost := "" - if v.route.pathTemplate != nil { - reversePath = v.route.pathTemplate.Reverse - } - if v.route.hostTemplate != nil { - reverseHost = v.route.hostTemplate.Reverse - } - - t.Errorf("%#v:\nexpected: %q\ngot: %q\nreverse path: %q\nreverse host: %q", v.route, v.url, url, reversePath, reverseHost) - */ - } - } - - ArticleHandler := func(w http.ResponseWriter, r *http.Request) { - } - - router := NewRouter() - router.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).Name("article") - - url, _ := router.Get("article").URL("category", "technology", "id", "42") - expected := "/articles/technology/42" - if url.String() != expected { - t.Errorf("Expected %v, got %v", expected, url.String()) - } -} - -func TestMatchedRouteName(t *testing.T) { - routeName := "stock" - router := NewRouter() - route := router.NewRoute().Path("/products/").Name(routeName) - - url := "http://www.domain.com/products/" - request, _ := http.NewRequest("GET", url, nil) - var rv RouteMatch - ok := router.Match(request, &rv) - - if !ok || rv.Route != route { - t.Errorf("Expected same route, got %+v.", rv.Route) - } - - retName := rv.Route.GetName() - if retName != routeName { - t.Errorf("Expected %q, got %q.", routeName, retName) - } -} - -func TestSubRouting(t *testing.T) { - // Example from docs. - router := NewRouter() - subrouter := router.NewRoute().Host("www.domain.com").Subrouter() - route := subrouter.NewRoute().Path("/products/").Name("products") - - url := "http://www.domain.com/products/" - request, _ := http.NewRequest("GET", url, nil) - var rv RouteMatch - ok := router.Match(request, &rv) - - if !ok || rv.Route != route { - t.Errorf("Expected same route, got %+v.", rv.Route) - } - - u, _ := router.Get("products").URL() - builtUrl := u.String() - // Yay, subroute aware of the domain when building! - if builtUrl != url { - t.Errorf("Expected %q, got %q.", url, builtUrl) - } -} - -func TestVariableNames(t *testing.T) { - route := new(Route).Host("{arg1}.domain.com").Path("/{arg1}/{arg2:[0-9]+}") - if route.err == nil { - t.Errorf("Expected error for duplicated variable names") - } -} - -func TestRedirectSlash(t *testing.T) { - var route *Route - var routeMatch RouteMatch - r := NewRouter() - - r.StrictSlash(false) - route = r.NewRoute() - if route.strictSlash != false { - t.Errorf("Expected false redirectSlash.") - } - - r.StrictSlash(true) - route = r.NewRoute() - if route.strictSlash != true { - t.Errorf("Expected true redirectSlash.") - } - - route = new(Route) - route.strictSlash = true - route.Path("/{arg1}/{arg2:[0-9]+}/") - request, _ := http.NewRequest("GET", "http://localhost/foo/123", nil) - routeMatch = RouteMatch{} - _ = route.Match(request, &routeMatch) - vars := routeMatch.Vars - if vars["arg1"] != "foo" { - t.Errorf("Expected foo.") - } - if vars["arg2"] != "123" { - t.Errorf("Expected 123.") - } - rsp := NewRecorder() - routeMatch.Handler.ServeHTTP(rsp, request) - if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123/" { - t.Errorf("Expected redirect header.") - } - - route = new(Route) - route.strictSlash = true - route.Path("/{arg1}/{arg2:[0-9]+}") - request, _ = http.NewRequest("GET", "http://localhost/foo/123/", nil) - routeMatch = RouteMatch{} - _ = route.Match(request, &routeMatch) - vars = routeMatch.Vars - if vars["arg1"] != "foo" { - t.Errorf("Expected foo.") - } - if vars["arg2"] != "123" { - t.Errorf("Expected 123.") - } - rsp = NewRecorder() - routeMatch.Handler.ServeHTTP(rsp, request) - if rsp.HeaderMap.Get("Location") != "http://localhost/foo/123" { - t.Errorf("Expected redirect header.") - } -} - -// Test for the new regexp library, still not available in stable Go. -func TestNewRegexp(t *testing.T) { - var p *routeRegexp - var matches []string - - tests := map[string]map[string][]string{ - "/{foo:a{2}}": { - "/a": nil, - "/aa": {"aa"}, - "/aaa": nil, - "/aaaa": nil, - }, - "/{foo:a{2,}}": { - "/a": nil, - "/aa": {"aa"}, - "/aaa": {"aaa"}, - "/aaaa": {"aaaa"}, - }, - "/{foo:a{2,3}}": { - "/a": nil, - "/aa": {"aa"}, - "/aaa": {"aaa"}, - "/aaaa": nil, - }, - "/{foo:[a-z]{3}}/{bar:[a-z]{2}}": { - "/a": nil, - "/ab": nil, - "/abc": nil, - "/abcd": nil, - "/abc/ab": {"abc", "ab"}, - "/abc/abc": nil, - "/abcd/ab": nil, - }, - `/{foo:\w{3,}}/{bar:\d{2,}}`: { - "/a": nil, - "/ab": nil, - "/abc": nil, - "/abc/1": nil, - "/abc/12": {"abc", "12"}, - "/abcd/12": {"abcd", "12"}, - "/abcd/123": {"abcd", "123"}, - }, - } - - for pattern, paths := range tests { - p, _ = newRouteRegexp(pattern, false, false, false, false) - for path, result := range paths { - matches = p.regexp.FindStringSubmatch(path) - if result == nil { - if matches != nil { - t.Errorf("%v should not match %v.", pattern, path) - } - } else { - if len(matches) != len(result)+1 { - t.Errorf("Expected %v matches, got %v.", len(result)+1, len(matches)) - } else { - for k, v := range result { - if matches[k+1] != v { - t.Errorf("Expected %v, got %v.", v, matches[k+1]) - } - } - } - } - } - } -} diff --git a/_third_party/github.com/gorilla/mux/regexp.go b/_third_party/github.com/gorilla/mux/regexp.go deleted file mode 100644 index d98575ee..00000000 --- a/_third_party/github.com/gorilla/mux/regexp.go +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import ( - "bytes" - "fmt" - "net/http" - "net/url" - "regexp" - "strings" -) - -// newRouteRegexp parses a route template and returns a routeRegexp, -// used to match a host, a path or a query string. -// -// It will extract named variables, assemble a regexp to be matched, create -// a "reverse" template to build URLs and compile regexps to validate variable -// values used in URL building. -// -// Previously we accepted only Python-like identifiers for variable -// names ([a-zA-Z_][a-zA-Z0-9_]*), but currently the only restriction is that -// name and pattern can't be empty, and names can't contain a colon. -func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash bool) (*routeRegexp, error) { - // Check if it is well-formed. - idxs, errBraces := braceIndices(tpl) - if errBraces != nil { - return nil, errBraces - } - // Backup the original. - template := tpl - // Now let's parse it. - defaultPattern := "[^/]+" - if matchQuery { - defaultPattern = "[^?&]+" - } else if matchHost { - defaultPattern = "[^.]+" - matchPrefix = false - } - // Only match strict slash if not matching - if matchPrefix || matchHost || matchQuery { - strictSlash = false - } - // Set a flag for strictSlash. - endSlash := false - if strictSlash && strings.HasSuffix(tpl, "/") { - tpl = tpl[:len(tpl)-1] - endSlash = true - } - varsN := make([]string, len(idxs)/2) - varsR := make([]*regexp.Regexp, len(idxs)/2) - pattern := bytes.NewBufferString("") - pattern.WriteByte('^') - reverse := bytes.NewBufferString("") - var end int - var err error - for i := 0; i < len(idxs); i += 2 { - // Set all values we are interested in. - raw := tpl[end:idxs[i]] - end = idxs[i+1] - parts := strings.SplitN(tpl[idxs[i]+1:end-1], ":", 2) - name := parts[0] - patt := defaultPattern - if len(parts) == 2 { - patt = parts[1] - } - // Name or pattern can't be empty. - if name == "" || patt == "" { - return nil, fmt.Errorf("mux: missing name or pattern in %q", - tpl[idxs[i]:end]) - } - // Build the regexp pattern. - fmt.Fprintf(pattern, "%s(%s)", regexp.QuoteMeta(raw), patt) - // Build the reverse template. - fmt.Fprintf(reverse, "%s%%s", raw) - - // Append variable name and compiled pattern. - varsN[i/2] = name - varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt)) - if err != nil { - return nil, err - } - } - // Add the remaining. - raw := tpl[end:] - pattern.WriteString(regexp.QuoteMeta(raw)) - if strictSlash { - pattern.WriteString("[/]?") - } - if !matchPrefix { - pattern.WriteByte('$') - } - reverse.WriteString(raw) - if endSlash { - reverse.WriteByte('/') - } - // Compile full regexp. - reg, errCompile := regexp.Compile(pattern.String()) - if errCompile != nil { - return nil, errCompile - } - // Done! - return &routeRegexp{ - template: template, - matchHost: matchHost, - matchQuery: matchQuery, - strictSlash: strictSlash, - regexp: reg, - reverse: reverse.String(), - varsN: varsN, - varsR: varsR, - }, nil -} - -// routeRegexp stores a regexp to match a host or path and information to -// collect and validate route variables. -type routeRegexp struct { - // The unmodified template. - template string - // True for host match, false for path or query string match. - matchHost bool - // True for query string match, false for path and host match. - matchQuery bool - // The strictSlash value defined on the route, but disabled if PathPrefix was used. - strictSlash bool - // Expanded regexp. - regexp *regexp.Regexp - // Reverse template. - reverse string - // Variable names. - varsN []string - // Variable regexps (validators). - varsR []*regexp.Regexp -} - -// Match matches the regexp against the URL host or path. -func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool { - if !r.matchHost { - if r.matchQuery { - return r.matchQueryString(req) - } else { - return r.regexp.MatchString(req.URL.Path) - } - } - return r.regexp.MatchString(getHost(req)) -} - -// url builds a URL part using the given values. -func (r *routeRegexp) url(values map[string]string) (string, error) { - urlValues := make([]interface{}, len(r.varsN)) - for k, v := range r.varsN { - value, ok := values[v] - if !ok { - return "", fmt.Errorf("mux: missing route variable %q", v) - } - urlValues[k] = value - } - rv := fmt.Sprintf(r.reverse, urlValues...) - if !r.regexp.MatchString(rv) { - // The URL is checked against the full regexp, instead of checking - // individual variables. This is faster but to provide a good error - // message, we check individual regexps if the URL doesn't match. - for k, v := range r.varsN { - if !r.varsR[k].MatchString(values[v]) { - return "", fmt.Errorf( - "mux: variable %q doesn't match, expected %q", values[v], - r.varsR[k].String()) - } - } - } - return rv, nil -} - -// getUrlQuery returns a single query parameter from a request URL. -// For a URL with foo=bar&baz=ding, we return only the relevant key -// value pair for the routeRegexp. -func (r *routeRegexp) getUrlQuery(req *http.Request) string { - if !r.matchQuery { - return "" - } - key := strings.Split(r.template, "=")[0] - val := req.URL.Query().Get(key) - return key + "=" + val -} - -func (r *routeRegexp) matchQueryString(req *http.Request) bool { - return r.regexp.MatchString(r.getUrlQuery(req)) -} - -// braceIndices returns the first level curly brace indices from a string. -// It returns an error in case of unbalanced braces. -func braceIndices(s string) ([]int, error) { - var level, idx int - idxs := make([]int, 0) - for i := 0; i < len(s); i++ { - switch s[i] { - case '{': - if level++; level == 1 { - idx = i - } - case '}': - if level--; level == 0 { - idxs = append(idxs, idx, i+1) - } else if level < 0 { - return nil, fmt.Errorf("mux: unbalanced braces in %q", s) - } - } - } - if level != 0 { - return nil, fmt.Errorf("mux: unbalanced braces in %q", s) - } - return idxs, nil -} - -// ---------------------------------------------------------------------------- -// routeRegexpGroup -// ---------------------------------------------------------------------------- - -// routeRegexpGroup groups the route matchers that carry variables. -type routeRegexpGroup struct { - host *routeRegexp - path *routeRegexp - queries []*routeRegexp -} - -// setMatch extracts the variables from the URL once a route matches. -func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) { - // Store host variables. - if v.host != nil { - hostVars := v.host.regexp.FindStringSubmatch(getHost(req)) - if hostVars != nil { - for k, v := range v.host.varsN { - m.Vars[v] = hostVars[k+1] - } - } - } - // Store path variables. - if v.path != nil { - pathVars := v.path.regexp.FindStringSubmatch(req.URL.Path) - if pathVars != nil { - for k, v := range v.path.varsN { - m.Vars[v] = pathVars[k+1] - } - // Check if we should redirect. - if v.path.strictSlash { - p1 := strings.HasSuffix(req.URL.Path, "/") - p2 := strings.HasSuffix(v.path.template, "/") - if p1 != p2 { - u, _ := url.Parse(req.URL.String()) - if p1 { - u.Path = u.Path[:len(u.Path)-1] - } else { - u.Path += "/" - } - m.Handler = http.RedirectHandler(u.String(), 301) - } - } - } - } - // Store query string variables. - for _, q := range v.queries { - queryVars := q.regexp.FindStringSubmatch(q.getUrlQuery(req)) - if queryVars != nil { - for k, v := range q.varsN { - m.Vars[v] = queryVars[k+1] - } - } - } -} - -// getHost tries its best to return the request host. -func getHost(r *http.Request) string { - if r.URL.IsAbs() { - return r.URL.Host - } - host := r.Host - // Slice off any port information. - if i := strings.Index(host, ":"); i != -1 { - host = host[:i] - } - return host - -} diff --git a/_third_party/github.com/gorilla/mux/route.go b/_third_party/github.com/gorilla/mux/route.go deleted file mode 100644 index 6cb12d3c..00000000 --- a/_third_party/github.com/gorilla/mux/route.go +++ /dev/null @@ -1,571 +0,0 @@ -// Copyright 2012 The Gorilla 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 mux - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "strings" -) - -// Route stores information to match a request and build URLs. -type Route struct { - // Parent where the route was registered (a Router). - parent parentRoute - // Request handler for the route. - handler http.Handler - // List of matchers. - matchers []matcher - // Manager for the variables from host and path. - regexp *routeRegexpGroup - // If true, when the path pattern is "/path/", accessing "/path" will - // redirect to the former and vice versa. - strictSlash bool - // If true, this route never matches: it is only used to build URLs. - buildOnly bool - // The name used to build URLs. - name string - // Error resulted from building a route. - err error - - buildVarsFunc BuildVarsFunc -} - -// Match matches the route against the request. -func (r *Route) Match(req *http.Request, match *RouteMatch) bool { - if r.buildOnly || r.err != nil { - return false - } - // Match everything. - for _, m := range r.matchers { - if matched := m.Match(req, match); !matched { - return false - } - } - // Yay, we have a match. Let's collect some info about it. - if match.Route == nil { - match.Route = r - } - if match.Handler == nil { - match.Handler = r.handler - } - if match.Vars == nil { - match.Vars = make(map[string]string) - } - // Set variables. - if r.regexp != nil { - r.regexp.setMatch(req, match, r) - } - return true -} - -// ---------------------------------------------------------------------------- -// Route attributes -// ---------------------------------------------------------------------------- - -// GetError returns an error resulted from building the route, if any. -func (r *Route) GetError() error { - return r.err -} - -// BuildOnly sets the route to never match: it is only used to build URLs. -func (r *Route) BuildOnly() *Route { - r.buildOnly = true - return r -} - -// Handler -------------------------------------------------------------------- - -// Handler sets a handler for the route. -func (r *Route) Handler(handler http.Handler) *Route { - if r.err == nil { - r.handler = handler - } - return r -} - -// HandlerFunc sets a handler function for the route. -func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route { - return r.Handler(http.HandlerFunc(f)) -} - -// GetHandler returns the handler for the route, if any. -func (r *Route) GetHandler() http.Handler { - return r.handler -} - -// Name ----------------------------------------------------------------------- - -// Name sets the name for the route, used to build URLs. -// If the name was registered already it will be overwritten. -func (r *Route) Name(name string) *Route { - if r.name != "" { - r.err = fmt.Errorf("mux: route already has name %q, can't set %q", - r.name, name) - } - if r.err == nil { - r.name = name - r.getNamedRoutes()[name] = r - } - return r -} - -// GetName returns the name for the route, if any. -func (r *Route) GetName() string { - return r.name -} - -// ---------------------------------------------------------------------------- -// Matchers -// ---------------------------------------------------------------------------- - -// matcher types try to match a request. -type matcher interface { - Match(*http.Request, *RouteMatch) bool -} - -// addMatcher adds a matcher to the route. -func (r *Route) addMatcher(m matcher) *Route { - if r.err == nil { - r.matchers = append(r.matchers, m) - } - return r -} - -// addRegexpMatcher adds a host or path matcher and builder to a route. -func (r *Route) addRegexpMatcher(tpl string, matchHost, matchPrefix, matchQuery bool) error { - if r.err != nil { - return r.err - } - r.regexp = r.getRegexpGroup() - if !matchHost && !matchQuery { - if len(tpl) == 0 || tpl[0] != '/' { - return fmt.Errorf("mux: path must start with a slash, got %q", tpl) - } - if r.regexp.path != nil { - tpl = strings.TrimRight(r.regexp.path.template, "/") + tpl - } - } - rr, err := newRouteRegexp(tpl, matchHost, matchPrefix, matchQuery, r.strictSlash) - if err != nil { - return err - } - for _, q := range r.regexp.queries { - if err = uniqueVars(rr.varsN, q.varsN); err != nil { - return err - } - } - if matchHost { - if r.regexp.path != nil { - if err = uniqueVars(rr.varsN, r.regexp.path.varsN); err != nil { - return err - } - } - r.regexp.host = rr - } else { - if r.regexp.host != nil { - if err = uniqueVars(rr.varsN, r.regexp.host.varsN); err != nil { - return err - } - } - if matchQuery { - r.regexp.queries = append(r.regexp.queries, rr) - } else { - r.regexp.path = rr - } - } - r.addMatcher(rr) - return nil -} - -// Headers -------------------------------------------------------------------- - -// headerMatcher matches the request against header values. -type headerMatcher map[string]string - -func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchMap(m, r.Header, true) -} - -// Headers adds a matcher for request header values. -// It accepts a sequence of key/value pairs to be matched. For example: -// -// r := mux.NewRouter() -// r.Headers("Content-Type", "application/json", -// "X-Requested-With", "XMLHttpRequest") -// -// The above route will only match if both request header values match. -// -// It the value is an empty string, it will match any value if the key is set. -func (r *Route) Headers(pairs ...string) *Route { - if r.err == nil { - var headers map[string]string - headers, r.err = mapFromPairs(pairs...) - return r.addMatcher(headerMatcher(headers)) - } - return r -} - -// Host ----------------------------------------------------------------------- - -// Host adds a matcher for the URL host. -// It accepts a template with zero or more URL variables enclosed by {}. -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next dot. -// -// - {name:pattern} matches the given regexp pattern. -// -// For example: -// -// r := mux.NewRouter() -// r.Host("www.domain.com") -// r.Host("{subdomain}.domain.com") -// r.Host("{subdomain:[a-z]+}.domain.com") -// -// Variable names must be unique in a given route. They can be retrieved -// calling mux.Vars(request). -func (r *Route) Host(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, true, false, false) - return r -} - -// MatcherFunc ---------------------------------------------------------------- - -// MatcherFunc is the function signature used by custom matchers. -type MatcherFunc func(*http.Request, *RouteMatch) bool - -func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool { - return m(r, match) -} - -// MatcherFunc adds a custom function to be used as request matcher. -func (r *Route) MatcherFunc(f MatcherFunc) *Route { - return r.addMatcher(f) -} - -// Methods -------------------------------------------------------------------- - -// methodMatcher matches the request against HTTP methods. -type methodMatcher []string - -func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchInArray(m, r.Method) -} - -// Methods adds a matcher for HTTP methods. -// It accepts a sequence of one or more methods to be matched, e.g.: -// "GET", "POST", "PUT". -func (r *Route) Methods(methods ...string) *Route { - for k, v := range methods { - methods[k] = strings.ToUpper(v) - } - return r.addMatcher(methodMatcher(methods)) -} - -// Path ----------------------------------------------------------------------- - -// Path adds a matcher for the URL path. -// It accepts a template with zero or more URL variables enclosed by {}. The -// template must start with a "/". -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next slash. -// -// - {name:pattern} matches the given regexp pattern. -// -// For example: -// -// r := mux.NewRouter() -// r.Path("/products/").Handler(ProductsHandler) -// r.Path("/products/{key}").Handler(ProductsHandler) -// r.Path("/articles/{category}/{id:[0-9]+}"). -// Handler(ArticleHandler) -// -// Variable names must be unique in a given route. They can be retrieved -// calling mux.Vars(request). -func (r *Route) Path(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, false, false, false) - return r -} - -// PathPrefix ----------------------------------------------------------------- - -// PathPrefix adds a matcher for the URL path prefix. This matches if the given -// template is a prefix of the full URL path. See Route.Path() for details on -// the tpl argument. -// -// Note that it does not treat slashes specially ("/foobar/" will be matched by -// the prefix "/foo") so you may want to use a trailing slash here. -// -// Also note that the setting of Router.StrictSlash() has no effect on routes -// with a PathPrefix matcher. -func (r *Route) PathPrefix(tpl string) *Route { - r.err = r.addRegexpMatcher(tpl, false, true, false) - return r -} - -// Query ---------------------------------------------------------------------- - -// Queries adds a matcher for URL query values. -// It accepts a sequence of key/value pairs. Values may define variables. -// For example: -// -// r := mux.NewRouter() -// r.Queries("foo", "bar", "id", "{id:[0-9]+}") -// -// The above route will only match if the URL contains the defined queries -// values, e.g.: ?foo=bar&id=42. -// -// It the value is an empty string, it will match any value if the key is set. -// -// Variables can define an optional regexp pattern to be matched: -// -// - {name} matches anything until the next slash. -// -// - {name:pattern} matches the given regexp pattern. -func (r *Route) Queries(pairs ...string) *Route { - length := len(pairs) - if length%2 != 0 { - r.err = fmt.Errorf( - "mux: number of parameters must be multiple of 2, got %v", pairs) - return nil - } - for i := 0; i < length; i += 2 { - if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], false, false, true); r.err != nil { - return r - } - } - - return r -} - -// Schemes -------------------------------------------------------------------- - -// schemeMatcher matches the request against URL schemes. -type schemeMatcher []string - -func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool { - return matchInArray(m, r.URL.Scheme) -} - -// Schemes adds a matcher for URL schemes. -// It accepts a sequence of schemes to be matched, e.g.: "http", "https". -func (r *Route) Schemes(schemes ...string) *Route { - for k, v := range schemes { - schemes[k] = strings.ToLower(v) - } - return r.addMatcher(schemeMatcher(schemes)) -} - -// BuildVarsFunc -------------------------------------------------------------- - -// BuildVarsFunc is the function signature used by custom build variable -// functions (which can modify route variables before a route's URL is built). -type BuildVarsFunc func(map[string]string) map[string]string - -// BuildVarsFunc adds a custom function to be used to modify build variables -// before a route's URL is built. -func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route { - r.buildVarsFunc = f - return r -} - -// Subrouter ------------------------------------------------------------------ - -// Subrouter creates a subrouter for the route. -// -// It will test the inner routes only if the parent route matched. For example: -// -// r := mux.NewRouter() -// s := r.Host("www.domain.com").Subrouter() -// s.HandleFunc("/products/", ProductsHandler) -// s.HandleFunc("/products/{key}", ProductHandler) -// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) -// -// Here, the routes registered in the subrouter won't be tested if the host -// doesn't match. -func (r *Route) Subrouter() *Router { - router := &Router{parent: r, strictSlash: r.strictSlash} - r.addMatcher(router) - return router -} - -// ---------------------------------------------------------------------------- -// URL building -// ---------------------------------------------------------------------------- - -// URL builds a URL for the route. -// -// It accepts a sequence of key/value pairs for the route variables. For -// example, given this route: -// -// r := mux.NewRouter() -// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). -// Name("article") -// -// ...a URL for it can be built using: -// -// url, err := r.Get("article").URL("category", "technology", "id", "42") -// -// ...which will return an url.URL with the following path: -// -// "/articles/technology/42" -// -// This also works for host variables: -// -// r := mux.NewRouter() -// r.Host("{subdomain}.domain.com"). -// HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). -// Name("article") -// -// // url.String() will be "http://news.domain.com/articles/technology/42" -// url, err := r.Get("article").URL("subdomain", "news", -// "category", "technology", -// "id", "42") -// -// All variables defined in the route are required, and their values must -// conform to the corresponding patterns. -func (r *Route) URL(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp == nil { - return nil, errors.New("mux: route doesn't have a host or path") - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - var scheme, host, path string - if r.regexp.host != nil { - // Set a default scheme. - scheme = "http" - if host, err = r.regexp.host.url(values); err != nil { - return nil, err - } - } - if r.regexp.path != nil { - if path, err = r.regexp.path.url(values); err != nil { - return nil, err - } - } - return &url.URL{ - Scheme: scheme, - Host: host, - Path: path, - }, nil -} - -// URLHost builds the host part of the URL for a route. See Route.URL(). -// -// The route must have a host defined. -func (r *Route) URLHost(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp == nil || r.regexp.host == nil { - return nil, errors.New("mux: route doesn't have a host") - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - host, err := r.regexp.host.url(values) - if err != nil { - return nil, err - } - return &url.URL{ - Scheme: "http", - Host: host, - }, nil -} - -// URLPath builds the path part of the URL for a route. See Route.URL(). -// -// The route must have a path defined. -func (r *Route) URLPath(pairs ...string) (*url.URL, error) { - if r.err != nil { - return nil, r.err - } - if r.regexp == nil || r.regexp.path == nil { - return nil, errors.New("mux: route doesn't have a path") - } - values, err := r.prepareVars(pairs...) - if err != nil { - return nil, err - } - path, err := r.regexp.path.url(values) - if err != nil { - return nil, err - } - return &url.URL{ - Path: path, - }, nil -} - -// prepareVars converts the route variable pairs into a map. If the route has a -// BuildVarsFunc, it is invoked. -func (r *Route) prepareVars(pairs ...string) (map[string]string, error) { - m, err := mapFromPairs(pairs...) - if err != nil { - return nil, err - } - return r.buildVars(m), nil -} - -func (r *Route) buildVars(m map[string]string) map[string]string { - if r.parent != nil { - m = r.parent.buildVars(m) - } - if r.buildVarsFunc != nil { - m = r.buildVarsFunc(m) - } - return m -} - -// ---------------------------------------------------------------------------- -// parentRoute -// ---------------------------------------------------------------------------- - -// parentRoute allows routes to know about parent host and path definitions. -type parentRoute interface { - getNamedRoutes() map[string]*Route - getRegexpGroup() *routeRegexpGroup - buildVars(map[string]string) map[string]string -} - -// getNamedRoutes returns the map where named routes are registered. -func (r *Route) getNamedRoutes() map[string]*Route { - if r.parent == nil { - // During tests router is not always set. - r.parent = NewRouter() - } - return r.parent.getNamedRoutes() -} - -// getRegexpGroup returns regexp definitions from this route. -func (r *Route) getRegexpGroup() *routeRegexpGroup { - if r.regexp == nil { - if r.parent == nil { - // During tests router is not always set. - r.parent = NewRouter() - } - regexp := r.parent.getRegexpGroup() - if regexp == nil { - r.regexp = new(routeRegexpGroup) - } else { - // Copy. - r.regexp = &routeRegexpGroup{ - host: regexp.host, - path: regexp.path, - queries: regexp.queries, - } - } - } - return r.regexp -} diff --git a/_third_party/github.com/mjibson/appstats/README.md b/_third_party/github.com/mjibson/appstats/README.md deleted file mode 100644 index ff7f15df..00000000 --- a/_third_party/github.com/mjibson/appstats/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# appstats - -A port of the python appstats implementation to the Go runtime on Google App Engine. - -For installation and usage, see the docs: [http://godoc.org/github.com/mjibson/appstats](http://godoc.org/github.com/mjibson/appstats). diff --git a/_third_party/github.com/mjibson/appstats/appstats.go b/_third_party/github.com/mjibson/appstats/appstats.go deleted file mode 100644 index 5b9b6c1f..00000000 --- a/_third_party/github.com/mjibson/appstats/appstats.go +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package appstats - -import ( - "bytes" - "encoding/gob" - "fmt" - "math/rand" - "net/http" - "net/url" - "runtime/debug" - "time" - - "appengine" - "appengine/memcache" - "appengine/user" - "appengine_internal" -) - -var ( - // RecordFraction is the fraction of requests to record. - // Set to a number between 0.0 (none) and 1.0 (all). - RecordFraction float64 = 1.0 - - // ShouldRecord is the function used to determine if recording will occur - // for a given request. The default is to use RecordFraction. - ShouldRecord = DefaultShouldRecord - - // ProtoMaxBytes is the amount of protobuf data to record. - // Data after this is truncated. - ProtoMaxBytes = 150 - - // Namespace is the memcache namespace under which to store appstats data. - Namespace = "__appstats__" -) - -const ( - serveURL = "/_ah/stats/" - detailsURL = serveURL + "details" - fileURL = serveURL + "file" - staticURL = serveURL + "static/" -) - -func init() { - http.HandleFunc(serveURL, appstatsHandler) -} - -// DefaultShouldRecord will record a request based on RecordFraction. -func DefaultShouldRecord(r *http.Request) bool { - if RecordFraction >= 1.0 { - return true - } - - return rand.Float64() < RecordFraction -} - -// Context is a timing-aware appengine.Context. -type Context struct { - appengine.Context - header http.Header - stats *requestStats -} - -// Call times an appengine.Context Call. Internal use only. -func (c Context) Call(service, method string, in, out appengine_internal.ProtoMessage, opts *appengine_internal.CallOptions) error { - c.stats.wg.Add(1) - defer c.stats.wg.Done() - - if service == "__go__" { - return c.Context.Call(service, method, in, out, opts) - } - - stat := rpcStat{ - Service: service, - Method: method, - Start: time.Now(), - Offset: time.Since(c.stats.Start), - StackData: string(debug.Stack()), - } - err := c.Context.Call(service, method, in, out, opts) - stat.Duration = time.Since(stat.Start) - stat.In = in.String() - stat.Out = out.String() - stat.Cost = getCost(out) - - if len(stat.In) > ProtoMaxBytes { - stat.In = stat.In[:ProtoMaxBytes] + "..." - } - if len(stat.Out) > ProtoMaxBytes { - stat.Out = stat.Out[:ProtoMaxBytes] + "..." - } - - c.stats.lock.Lock() - c.stats.RPCStats = append(c.stats.RPCStats, stat) - c.stats.Cost += stat.Cost - c.stats.lock.Unlock() - return err -} - -// NewContext creates a new timing-aware context from req. -func NewContext(req *http.Request) Context { - c := appengine.NewContext(req) - var uname string - var admin bool - if u := user.Current(c); u != nil { - uname = u.String() - admin = u.Admin - } - return Context{ - Context: c, - header: req.Header, - stats: &requestStats{ - User: uname, - Admin: admin, - Method: req.Method, - Path: req.URL.Path, - Query: req.URL.RawQuery, - Start: time.Now(), - }, - } -} - -// WithContext enables profiling of functions without a corresponding request, -// as in the appengine/delay package. method and path may be empty. -func WithContext(context appengine.Context, method, path string, f func(Context)) { - var uname string - var admin bool - if u := user.Current(context); u != nil { - uname = u.String() - admin = u.Admin - } - c := Context{ - Context: context, - stats: &requestStats{ - User: uname, - Admin: admin, - Method: method, - Path: path, - Start: time.Now(), - }, - } - f(c) - c.save() -} - -const bufMaxLen = 1000000 - -func (c Context) save() { - c.stats.wg.Wait() - c.stats.Duration = time.Since(c.stats.Start) - - var buf_part, buf_full bytes.Buffer - full := stats_full{ - Header: c.header, - Stats: c.stats, - } - if err := gob.NewEncoder(&buf_full).Encode(&full); err != nil { - c.Errorf("appstats Save error: %v", err) - return - } else if buf_full.Len() > bufMaxLen { - // first try clearing stack traces - for i := range full.Stats.RPCStats { - full.Stats.RPCStats[i].StackData = "" - } - buf_full.Truncate(0) - gob.NewEncoder(&buf_full).Encode(&full) - } - part := stats_part(*c.stats) - for i := range part.RPCStats { - part.RPCStats[i].StackData = "" - part.RPCStats[i].In = "" - part.RPCStats[i].Out = "" - } - if err := gob.NewEncoder(&buf_part).Encode(&part); err != nil { - c.Errorf("appstats Save error: %v", err) - return - } - - item_part := &memcache.Item{ - Key: c.stats.PartKey(), - Value: buf_part.Bytes(), - } - - item_full := &memcache.Item{ - Key: c.stats.FullKey(), - Value: buf_full.Bytes(), - } - - c.Infof("Saved; %s: %s, %s: %s, link: %v", - item_part.Key, - byteSize(len(item_part.Value)), - item_full.Key, - byteSize(len(item_full.Value)), - c.URL(), - ) - - nc := c.storeContext() - memcache.SetMulti(nc, []*memcache.Item{item_part, item_full}) -} - -// URL returns the appstats URL for the current request. -func (c Context) URL() string { - u := url.URL{ - Path: detailsURL, - RawQuery: fmt.Sprintf("time=%v", c.stats.Start.Nanosecond()), - } - return u.String() -} - -func (c Context) storeContext() appengine.Context { - nc, _ := appengine.Namespace(c.Context, Namespace) - return nc -} - -func context(r *http.Request) appengine.Context { - c := appengine.NewContext(r) - nc, _ := appengine.Namespace(c, Namespace) - return nc -} - -// handler is an http.Handler that records RPC statistics. -type handler struct { - f func(appengine.Context, http.ResponseWriter, *http.Request) -} - -// NewHandler returns a new Handler that will execute f. -func NewHandler(f func(appengine.Context, http.ResponseWriter, *http.Request)) http.Handler { - return handler{ - f: f, - } -} - -// NewHandlerFunc returns a new HandlerFunc that will execute f. -func NewHandlerFunc(f func(appengine.Context, http.ResponseWriter, *http.Request)) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - h := handler{ - f: f, - } - h.ServeHTTP(w, r) - } -} - -type responseWriter struct { - http.ResponseWriter - - c Context -} - -func (r responseWriter) Write(b []byte) (int, error) { - // Emulate the behavior of http.ResponseWriter.Write since it doesn't - // call our WriteHeader implementation. - if r.c.stats.Status == 0 { - r.WriteHeader(http.StatusOK) - } - - return r.ResponseWriter.Write(b) -} - -func (r responseWriter) WriteHeader(i int) { - r.c.stats.Status = i - r.ResponseWriter.WriteHeader(i) -} - -func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if ShouldRecord(r) { - c := NewContext(r) - rw := responseWriter{ - ResponseWriter: w, - c: c, - } - h.f(c, rw, r) - c.save() - } else { - c := appengine.NewContext(r) - h.f(c, w, r) - } -} diff --git a/_third_party/github.com/mjibson/appstats/bytesize.go b/_third_party/github.com/mjibson/appstats/bytesize.go deleted file mode 100644 index 4facb87a..00000000 --- a/_third_party/github.com/mjibson/appstats/bytesize.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package appstats - -import ( - "fmt" -) - -type byteSize float64 - -const ( - _ = iota - _KB byteSize = 1 << (10 * iota) - _MB - _GB - _TB - _PB - _EB - _ZB - _YB -) - -func (b byteSize) String() string { - switch { - case b >= _YB: - return fmt.Sprintf("%.2fYB", b/_YB) - case b >= _ZB: - return fmt.Sprintf("%.2fZB", b/_ZB) - case b >= _EB: - return fmt.Sprintf("%.2fEB", b/_EB) - case b >= _PB: - return fmt.Sprintf("%.2fPB", b/_PB) - case b >= _TB: - return fmt.Sprintf("%.2fTB", b/_TB) - case b >= _GB: - return fmt.Sprintf("%.2fGB", b/_GB) - case b >= _MB: - return fmt.Sprintf("%.2fMB", b/_MB) - case b >= _KB: - return fmt.Sprintf("%.2fKB", b/_KB) - } - return fmt.Sprintf("%.2fB", b) -} diff --git a/_third_party/github.com/mjibson/appstats/cost.go b/_third_party/github.com/mjibson/appstats/cost.go deleted file mode 100644 index 179f6fd3..00000000 --- a/_third_party/github.com/mjibson/appstats/cost.go +++ /dev/null @@ -1,60 +0,0 @@ -package appstats - -import ( - "reflect" - - "github.com/mjibson/goread/_third_party/github.com/golang/protobuf/proto" -) - -const ( - cost_Write = 10 - cost_Read = 7 - cost_Small = 1 -) - -// todo: implement read and small ops costs - -func getCost(p proto.Message) int64 { - v := reflect.ValueOf(p) - v = reflect.Indirect(v) - if v.Kind() != reflect.Struct { - return 0 - } - - var cost int64 - cost += extractCost(v) - - return cost -} - -func extractCost(v reflect.Value) int64 { - v = v.FieldByName("Cost") - if v.Kind() != reflect.Ptr { - return 0 - } - v = v.Elem() - if v.Kind() != reflect.Struct { - return 0 - } - - var cost int64 - - extract := func(name string) int64 { - w := v.FieldByName(name) - if w.Kind() != reflect.Ptr { - return 0 - } - w = w.Elem() - switch w.Kind() { - case reflect.Int, reflect.Int32, reflect.Int64: - return w.Int() - } - - return 0 - } - - cost += extract("IndexWrites") - cost += extract("EntityWrites") - - return cost * cost_Write -} diff --git a/_third_party/github.com/mjibson/appstats/doc.go b/_third_party/github.com/mjibson/appstats/doc.go deleted file mode 100644 index b285209d..00000000 --- a/_third_party/github.com/mjibson/appstats/doc.go +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -Package appstats profiles the RPC performance of Google App Engine applications. - -Reference: https://developers.google.com/appengine/docs/python/tools/appstats - -To use this package, change your HTTP handler functions to use this signature: - - func(appengine.Context, http.ResponseWriter, *http.Request) - -Register them in the usual way, wrapping them with NewHandler. - - -Example - -This is a small example using this package. - - import ( - "net/http" - - "appengine" - - "github.com/mjibson/appstats" - ) - - func init() { - http.Handle("/", appstats.NewHandler(Main)) - } - - func Main(c appengine.Context, w http.ResponseWriter, r *http.Request) { - // do stuff with c: datastore.Get(c, key, entity) - w.Write([]byte("success")) - } - - -Usage - -Use your app, and view the appstats interface at http://localhost:8080/_ah/stats/, or your production URL. - - -Configuration - -Refer to the variables section of the documentation: http://godoc.org/github.com/mjibson/appstats#pkg-variables. - - -Routing - -In general, your app.yaml will not need to change. In the case of conflicting -routes, add the following to your app.yaml: - - handlers: - - url: /_ah/stats/.* - script: _go_app - - -TODO - -Cost calculation is experimental. Currently it only includes write ops (read and small ops are TODO). -*/ -package appstats diff --git a/_third_party/github.com/mjibson/appstats/funcs.go b/_third_party/github.com/mjibson/appstats/funcs.go deleted file mode 100644 index 1a6bcd00..00000000 --- a/_third_party/github.com/mjibson/appstats/funcs.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package appstats - -import ( - "html/template" - "reflect" - "strconv" - "strings" -) - -// eq reports whether the first argument is equal to -// any of the remaining arguments. -func eq(args ...interface{}) bool { - if len(args) == 0 { - return false - } - x := args[0] - switch x := x.(type) { - case string, int, int64, byte, float32, float64: - for _, y := range args[1:] { - if x == y { - return true - } - } - return false - } - - for _, y := range args[1:] { - if reflect.DeepEqual(x, y) { - return true - } - } - return false -} - -func add(a, b int) int { - return a + b -} - -func rjust(i, count int) string { - s := strconv.Itoa(i) - return strings.Repeat(" ", count-len(s)) + s -} - -func lt(a, b int) bool { - return a < b -} - -var funcs = template.FuncMap{ - "add": add, - "eq": eq, - "lt": lt, - "rjust": rjust, -} diff --git a/_third_party/github.com/mjibson/appstats/handler.go b/_third_party/github.com/mjibson/appstats/handler.go deleted file mode 100644 index a4a0436a..00000000 --- a/_third_party/github.com/mjibson/appstats/handler.go +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package appstats - -import ( - "bytes" - "encoding/gob" - "fmt" - "html/template" - "io/ioutil" - "net/http" - "sort" - "strconv" - "strings" - "time" - - "appengine" - "appengine/memcache" - "appengine/user" -) - -var templates *template.Template -var staticFiles map[string][]byte - -func init() { - templates = template.New("appstats").Funcs(funcs) - templates.Parse(htmlBase) - templates.Parse(htmlMain) - templates.Parse(htmlDetails) - templates.Parse(htmlFile) - - staticFiles = map[string][]byte{ - "app_engine_logo_sm.gif": app_engine_logo_sm_gif, - "appstats_css.css": appstats_css_css, - "appstats_js.js": appstats_js_js, - "gantt.js": gantt_js, - "minus.gif": minus_gif, - "pix.gif": pix_gif, - "plus.gif": plus_gif, - } -} - -func serveError(w http.ResponseWriter, err error) { - http.Error(w, err.Error(), http.StatusInternalServerError) -} - -func appstatsHandler(w http.ResponseWriter, r *http.Request) { - c := appengine.NewContext(r) - if appengine.IsDevAppServer() { - // noop - } else if u := user.Current(c); u == nil { - if loginURL, err := user.LoginURL(c, r.URL.String()); err == nil { - http.Redirect(w, r, loginURL, http.StatusTemporaryRedirect) - } else { - serveError(w, err) - } - return - } else if !u.Admin { - http.Error(w, "Forbidden", http.StatusForbidden) - return - } - - if detailsURL == r.URL.Path { - details(w, r) - } else if fileURL == r.URL.Path { - file(w, r) - } else if strings.HasPrefix(r.URL.Path, staticURL) { - static(w, r) - } else { - index(w, r) - } -} - -func index(w http.ResponseWriter, r *http.Request) { - keys := make([]string, modulus) - for i := range keys { - keys[i] = fmt.Sprintf(keyPart, i*distance) - } - - c := context(r) - items, err := memcache.GetMulti(c, keys) - if err != nil { - return - } - - ars := allrequestStats{} - for _, v := range items { - t := stats_part{} - err := gob.NewDecoder(bytes.NewBuffer(v.Value)).Decode(&t) - if err != nil { - continue - } - r := requestStats(t) - ars = append(ars, &r) - } - sort.Sort(reverse{ars}) - - requestById := make(map[int]*requestStats, len(ars)) - idByRequest := make(map[*requestStats]int, len(ars)) - requests := make(map[int]*statByName) - byRequest := make(map[int]map[string]cVal) - for i, v := range ars { - idx := i + 1 - requestById[idx] = v - idByRequest[v] = idx - requests[idx] = &statByName{ - RequestStats: v, - } - byRequest[idx] = make(map[string]cVal) - } - - requestByPath := make(map[string][]int) - byCount := make(map[string]cVal) - byRPC := make(map[skey]cVal) - for _, t := range ars { - id := idByRequest[t] - - requestByPath[t.Path] = append(requestByPath[t.Path], id) - - for _, r := range t.RPCStats { - rpc := r.Name() - - v := byRequest[id][rpc] - v.count++ - v.cost += r.Cost - byRequest[id][rpc] = v - - v = byCount[rpc] - v.count++ - v.cost += r.Cost - byCount[rpc] = v - - v = byRPC[skey{rpc, t.Path}] - v.count++ - v.cost += r.Cost - byRPC[skey{rpc, t.Path}] = v - } - } - - for k, v := range byRequest { - stats := statsByName{} - for rpc, s := range v { - stats = append(stats, &statByName{ - Name: rpc, - Count: s.count, - Cost: s.cost, - }) - } - sort.Sort(reverse{stats}) - requests[k].SubStats = stats - } - - statsByRPC := make(map[string]statsByName) - pathStats := make(map[string]statsByName) - for k, v := range byRPC { - statsByRPC[k.a] = append(statsByRPC[k.a], &statByName{ - Name: k.b, - Count: v.count, - Cost: v.cost, - }) - pathStats[k.b] = append(pathStats[k.b], &statByName{ - Name: k.a, - Count: v.count, - Cost: v.cost, - }) - } - for k, v := range statsByRPC { - sort.Sort(reverse{v}) - statsByRPC[k] = v - } - - pathStatsByCount := statsByName{} - for k, v := range pathStats { - total := 0 - var cost int64 - for _, stat := range v { - total += stat.Count - cost += stat.Cost - } - sort.Sort(reverse{v}) - - pathStatsByCount = append(pathStatsByCount, &statByName{ - Name: k, - Count: total, - Cost: cost, - SubStats: v, - Requests: len(requestByPath[k]), - RecentReqs: requestByPath[k], - }) - } - sort.Sort(reverse{pathStatsByCount}) - - allStatsByCount := statsByName{} - for k, v := range byCount { - allStatsByCount = append(allStatsByCount, &statByName{ - Name: k, - Count: v.count, - Cost: v.cost, - SubStats: statsByRPC[k], - }) - } - sort.Sort(reverse{allStatsByCount}) - - v := struct { - Env map[string]string - Requests map[int]*statByName - RequestStatsByCount map[int]*statByName - AllStatsByCount statsByName - PathStatsByCount statsByName - }{ - Env: map[string]string{ - "APPLICATION_ID": appengine.AppID(c), - }, - Requests: requests, - AllStatsByCount: allStatsByCount, - PathStatsByCount: pathStatsByCount, - } - - _ = templates.ExecuteTemplate(w, "main", v) -} - -func details(w http.ResponseWriter, r *http.Request) { - i, _ := strconv.Atoi(r.FormValue("time")) - qtime := roundTime(i) - key := fmt.Sprintf(keyFull, qtime) - - c := context(r) - - v := struct { - Env map[string]string - Record *requestStats - Header http.Header - AllStatsByCount statsByName - Real time.Duration - }{ - Env: map[string]string{ - "APPLICATION_ID": appengine.AppID(c), - }, - } - - item, err := memcache.Get(c, key) - if err != nil { - templates.ExecuteTemplate(w, "details", v) - return - } - - full := stats_full{} - err = gob.NewDecoder(bytes.NewBuffer(item.Value)).Decode(&full) - if err != nil { - templates.ExecuteTemplate(w, "details", v) - return - } - - byCount := make(map[string]cVal) - durationCount := make(map[string]time.Duration) - var _real time.Duration - for _, r := range full.Stats.RPCStats { - rpc := r.Name() - - // byCount - if _, present := byCount[rpc]; !present { - durationCount[rpc] = 0 - } - v := byCount[rpc] - v.count++ - v.cost += r.Cost - byCount[rpc] = v - durationCount[rpc] += r.Duration - _real += r.Duration - } - - allStatsByCount := statsByName{} - for k, v := range byCount { - allStatsByCount = append(allStatsByCount, &statByName{ - Name: k, - Count: v.count, - Cost: v.cost, - Duration: durationCount[k], - }) - } - sort.Sort(allStatsByCount) - - v.Record = full.Stats - v.Header = full.Header - v.AllStatsByCount = allStatsByCount - v.Real = _real - - _ = templates.ExecuteTemplate(w, "details", v) -} - -func file(w http.ResponseWriter, r *http.Request) { - fname := r.URL.Query().Get("f") - n := r.URL.Query().Get("n") - lineno, _ := strconv.Atoi(n) - c := context(r) - - f, err := ioutil.ReadFile(fname) - if err != nil { - serveError(w, err) - return - } - - fp := make(map[int]string) - for k, v := range strings.Split(string(f), "\n") { - fp[k+1] = v - } - - v := struct { - Env map[string]string - Filename string - Lineno int - Fp map[int]string - }{ - Env: map[string]string{ - "APPLICATION_ID": appengine.AppID(c), - }, - Filename: fname, - Lineno: lineno, - Fp: fp, - } - - _ = templates.ExecuteTemplate(w, "file", v) -} - -func static(w http.ResponseWriter, r *http.Request) { - fname := r.URL.Path[strings.LastIndex(r.URL.Path, "/")+1:] - if v, present := staticFiles[fname]; present { - h := w.Header() - - if strings.HasSuffix(r.URL.Path, ".css") { - h.Set("Content-type", "text/css") - } else if strings.HasSuffix(r.URL.Path, ".js") { - h.Set("Content-type", "text/javascript") - } - - h.Set("Cache-Control", "public, max-age=expiry") - expires := time.Now().Add(time.Hour) - h.Set("Expires", expires.Format(time.RFC1123)) - - w.Write(v) - } -} diff --git a/_third_party/github.com/mjibson/appstats/html.go b/_third_party/github.com/mjibson/appstats/html.go deleted file mode 100644 index 65ad51d2..00000000 --- a/_third_party/github.com/mjibson/appstats/html.go +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * These are modified from the python appstats implementation. - * If the above license infringes in some way on the original owner's - * copyright, I will change it. - */ - -package appstats - -const htmlBase = ` -{{ define "top" }} - - - - - Appstats - {{.Env.APPLICATION_ID}} -{{ end }} - -{{ define "body" }} - - -
- {{/* Header begin */}} -
-
- -
-
-
-
-

Application Stats for {{.Env.APPLICATION_ID}}

-
-
- All costs displayed in micropennies (1 dollar equals 100 pennies, 1 penny equals 1 million micropennies) -
-
-
-
- {{/* Header end */}} - {{/* Body begin */}} -
- {{/* Content begin */}} -
-{{ end }} - -{{ define "end" }} -
- {{/* Content end */}} -
- {{/* Body end */}} -
- -{{ end }} - -{{ define "footer" }} - - -{{ end }} -` - -const htmlMain = ` -{{ define "main" }} -{{ template "top" . }} -{{ template "body" . }} - -
- -
- -{{ if .Requests }} -
-
- {{/* RPC stats table begin */}} -
-
-
-

RPC Stats

-
-
-
- - - - - - - - - - - - - - {{ range $index, $item := .AllStatsByCount }} - - - - - - - - - - {{ range $subitem := $item.SubStats }} - - - - - - - {{ end }} - - {{ end }} -
RPCCountCostCost %
- - {{$item.Name}} - {{$item.Count}}{{$item.Cost}}{{/*$item.CostPct*/}}
{{$subitem.Name}}{{$subitem.Count}}{{$subitem.Cost}}{{/*$subitem.CostPct*/}}
-
- {{/* RPC stats table end */}} -
-
- {{/* Path stats table begin */}} -
-
-
-

Path Stats

-
-
-
- - - - - - - - - - - - - - - - - - {{ range $index, $item := .PathStatsByCount }} - - - - - - - - - {{ range $subitem := $item.SubStats }} - - - - - - - - - {{ end }} - - {{ end }} -
Path#RPCsCostCost%#RequestsMost Recent requests
- - {{$item.Name}} - - {{$item.Count}} - {{$item.Cost}}{{/*$item.CostPct*/}}{{$item.Requests}} - {{ range $index, $element := $item.RecentReqs }} - {{ if lt $index 10 }} - ({{$element}}) - {{ end }} - {{ if eq $index 10 }} - ... - {{ end }} - {{ end }} -
{{$subitem.Name}}{{$subitem.Count}}{{$subitem.Cost}}{{/*$subitem.CostPct*/}}
-
- {{/* Path stats table end */}} -
-
-
-
-
-

Requests History

-
-
-
- - - - - - - - - - - {{ range $index, $r := .Requests }} - - - - - - - {{ range $item := $r.SubStats }} - - - - - - {{/**/}} - - {{ end }} - - {{ end }} -
Request
- - ({{$index}}) - - {{$r.RequestStats.Start}} - "{{$r.RequestStats.Method}} - {{$r.RequestStats.Path}}{{if $r.RequestStats.Query}}?{{$r.RequestStats.Query}}{{end}}" - {{if $r.RequestStats.Status}}{{$r.RequestStats.Status}}{{end}} - - real={{$r.RequestStats.Duration}} - {{/* - overhead={{$r.overhead_walltime_milliseconds}}ms - ({{$r.combined_rpc_count}} RPC{{$r.combined_rpc_count}}, - billed_ops=[{{$r.combined_rpc_billed_ops}}]) - */}} - ({{$r.RequestStats.RPCStats | len}} RPCs, - cost={{$r.RequestStats.Cost}}) -
{{$item.Name}}{{$item.Count}}{{$item.Cost}}{{$item.total_billed_ops_str}}
-
-{{ else }} -
- No requests have been recorded yet. While it is possible that you - simply need to wait until your server receives some requests, this - is often caused by a configuration problem. - Learn more -
-{{ end }} - -{{ template "end" . }} - - - -{{ template "footer" . }} -{{ end }} -` - -const htmlDetails = ` -{{ define "details" }} -{{ template "top" . }} -{{ template "body" . }} - -{{ if not .Record }} -

Invalid or stale record key!

-{{ else }} -
-
-
- {{.Record.Start}}
- - {{.Record.Status}} - -
-
- - {{.Record.Method}} {{.Record.Path}}{{if .Record.Query}}?{{.Record.Query}}{{end}} - -
- {{.Record.User}}{{ if .Record.Admin }}*{{ end }} - real={{.Record.Duration}} - cost={{.Record.Cost}} - {{/* - overhead={{.Record.overhead_walltime_milliseconds}}ms -
- billed_ops={{.Record.combined_rpc_billed_ops}} - */}} -
-
-
- -
-

Timeline

-
-
[Chart goes here]
-
- {{ if .Record.RPCStats }} -
-
-
-

RPC Call Traces

-
-
-
- - - - - - - {{ range $index, $t := .Record.RPCStats }} - - - - - - - {{ if $t.In }} - - - - {{ end }} - {{ if $t.Out }} - - - - {{ end }} - {{ if $t.StackData }} - - - - {{ range $stackindex, $f := $t.Stack }} - - - - {{/* - {{ if $f.variables_size }} - - - - {{ end }}{{# f.variables_size #} - */}} - {{ end }}{{/* t.call_stack_list */}} - {{ end }}{{/* t.call_stack_size */}} - - {{ end }}{{/* .Record.individual_stats_list */}} -
RPC
- - @{{$t.Offset}} - {{$t.Name}} - real={{$t.Duration}} - cost={{$t.Cost}} - {{/* - billed_ops=[{{t.billed_ops_str}}] - */}} -
Request: {{$t.Request}}
Response: {{$t.Response}}
Stack:
-   - {{ $f.Location }}:{{ $f.Lineno }} {{ $f.Call }} -
{{ for item in f.variables_list }}{{item.key}} = {{item.value}}
{{ end }} -
-
- {{ end }}{{/* traces */}} -
- - {{ if .AllStatsByCount }} -
-

RPC Stats

- - - - - - - - - - {{ range $item := .AllStatsByCount }} - - - - - - - - - {{ end }} - -
service.call#RPCsreal timeCostBilled Ops
{{$item.Name}}{{$item.Count}}{{$item.Duration}}{{$item.Cost}}
-
- {{ end }}{{/* rpcstats_by_count */}} - - {{ if .Header }} -
-

CGI Environment

- - - {{ range $key, $value := .Header }} - - - - - {{ end }} - -
{{$key}}={{$value}}
-
- {{ end }}{{/* .Header */}} - -{{ end }} - -{{ template "end" . }} - - - - - -{{ template "footer" . }} -{{ end }} -` -const htmlFile = ` -{{ define "file" }} -{{ template "top" . }} -{{ template "body" . }} - -

{{.Filename}}

-Go to line {{.Lineno}} | -Go to bottom - -
-{{ range $index, $line := .Fp }}{{ rjust $index 4 }}: {{ $line }}
-{{ end }}
-
-Back to top - - -{{ template "end" . }} -{{ template "footer" . }} -{{ end }} -` diff --git a/_third_party/github.com/mjibson/appstats/static.go b/_third_party/github.com/mjibson/appstats/static.go deleted file mode 100644 index 8945332f..00000000 --- a/_third_party/github.com/mjibson/appstats/static.go +++ /dev/null @@ -1,15 +0,0 @@ -package appstats - -var app_engine_logo_sm_gif = []byte("GIF89a\xb0\x00\x1e\x00\xf7\x00\x00z'!\x04d\x04{j3\x142w>Ow\x9c\x06\x01\xbc\v\x03\x98#\x15\x982%\xb1, \xb8?3\xd4'\x11\x94v\x0e\xdfE/\x9dLG\x86_Z\xbbYN\xa4d^\x95mh\xaauo\xd3XF\xd3bU\xebkW\xc7uk\xe4zk'\xae.>\xbbBM\x9bQC\xbdIg\x80gu\xa8wO\xc5V\xad\x86\x03\xbc\x92\x05\xa2\x8a8ר\x01\u07b6\vˬ7\u07fe2\xfa\xd61\x83\x85~\xac\x9ce\xb5\xa6zܿMւx\xf8\x88wDZg\xeb\xcfL\xff\xe2Q\xf0\xd7s\xfd\xear\t3\x92\x18?\x94\x056\xa6\x03)\xb9\t.\xbb\x06<\xb6\x135\xbd\x158\xbe\x1a<\xbf+J\x8f\x18G\xae(S\xb2D]\x92Zi\x88ry\x8bMm\xb3a{\xb7\x1b=\xc0!?\xc2\x1fA\xc1\x12J\xc5%E\xc3(F\xc2+K\xc51O\xc6+\\\xc33R\xc77T\xc89V\xc9z鏜\xf1\xd0\x19nXr\xc4\fz\x80dH\x03\x00\xa4\xf2\x108\x16\x18\x00\x0062\x8c \x00,\x0fIcB\b\",\x13G\rap\x06\f\u05eb\xe4\x8d\x1c9\xb2\xf4\x8d\a\v\f\xa6\xe2J/ڈ-\xd06n,ѣ\x12R\xec\xf0\xb8\xe5\x03u\x114\xe46\xb7\x1f\xb4C\xc3\xec\x90\xc5\x19f\x98qF\x169\xc4\x04\xbfC\xc2(\x1d&\xa6 \xb6\xa55\r\\\x95\x8b_9\x02h55$\x01\u007f\xf9;C\x12\xbc\x80\x8a#\xd4\x00\b\"\x1b\xc88\x80\xc1\x89N\x00\xa3\x13\x96\xc0\x06!\x16\x00\x80\xb59\xc4^\x00p\x05\fF\xc0\x80V`\xe6\x04!8\x1e\x1cp\xf0\x03\xbe\b\x04\x184 @\xf5\xa0a\xb1rd\xef\x00\xfe~\xa0E+`\x81\x8c\f\xde\xec\fN\x18\x055\x8c\xa1\x8b6\xa8/\x81\x0f\x01C\xaf\xfe\xe7\x10)>D\x18;\xa0]\x1b\xb6؆G\xa4\x8c}\v,\x9d1\x9c\xd4\x1ec@\xa1W\x02i\x1d\x15\x05\xc2\xc0r\xa4\xa1\tn\xe0b\x1b\xdc0\nl0\xc1)Py\xc81 1\x862\xc0\xe1\b5\x1ca\x01\xfc\x00\x91@\b\xaf\x171 \x01\x03L(\x90p\xc0\x00\x04\x02`\x86(jP\x03H\f\x04\r<\xb0\x03.\xac7\x87\xb1\x99\xea\x0e\xdc\xf8F\xd2 b\f$\xec\xc2=IX\x9f\x02ǁ\x85G@Q\x83\xad|\xc8\x18\xbd\xe4\x90j0\v\x8cm,\x87'n\xf0\x84/pA\t[\bR\x1a\x11\xb8\xc60Z\xad\r\xb2s\x888\xb6Q\x8e74E\b\bڎ3^\xc1\n-\xcc\x00\b\xcaX\x84\xa9& \xbe\x16\x1c\xe0\x01\xc7`D\xc2T\xf0B\x06\xa0\x80\x19\xe1\x18\xc3\ff\xf0\x06`\xbcA\byP\x85`x\xe8\xa9g4\xc0\x00\b\xfeh\bG\x86\xb1:\x81\xf0\xa2t\x90;e\x9c\x94P\x97\x80:\xe4\x1a\x04\xcd\xd1\x14L6\x10^<\xa1h\xc5l\xa37\xb6\xd0\bOħ\x14IS#.K\xf7\t(\xe8G `\b\xda2\ue2031\x8cr\x1c\xe1\xe0\xc6\xf3\x80\xa0\x13\n\x18\xe0\x00\xac\x19H8xg\anH\xa3\x04\xcc;\xdc@\xa6\x91\xb6=\xf0\xe5\x19}\b\x82\x18\xe0Ѓ=\xacbB\xd08\x0e\x1d\x04ÂB]`O\x10\xe1\x86\x13t\xc6,+\xe4\xc0\x96\xb5\x9a\x02\xe7\xc6\xd1\x06(03\xab[\xed*3\x1f\x12\x89&В\x1c\\\xa8\xd6+\xd9(F$8b\x18\xe2\x10\x1f눹\xd1\xc7-\xc1\x95\x021\x05\x12L!\x10V\xf8\xa0)d8\x06D\xc8\x01\x87k\x1en\x15\t(\x00\x04\x9e\xd1H\f\x1c\x00\x05\xaa\xd8\xc9*B\x00\x02\x17\xa8e\x1a/`@\x1d\\(\x10p$\x83\x14\x11\x13\x03g\xa0\x91\x01O\x95C\x1b\n(T\x05\x16\xf1\x8c\\,\x826\x10\x19\xfe\x05\x12\xaa\xb0\x060,\xa1\n;\xf0\x1f\x12\x8c\xf4\x055LA\t\xa7\xb8%o}\v܈l\xe3\x97gP\x03\x14\x9e`3j\x14At\x03\tF\x11\xacV\x8e3\xd8\xc0\bH0\x93\x19B\xa1\x1f5x\x81Y\xcf\x1d\xddt\x05\"[\xda~\xe1V\x0eI\xc5\x0ffP\x03\x1f\xbc\x01\x15\xd8\xf0\x067\x8e\xb1\x89\x1e\f\x00\b\xc9\x10\x88\"\x1cP\x00\x05\xb0 \x10\x15\x80@\x1e$\xa1\xd3r(B\x04 (\xc1mV\x90\x82\x01#\x88\x1cLj\x02\x0ezP\x86\xf6\x1c\"\x00\x18\xf6\x00_`\xc1\xdf\x02\x18 \x01\n\xb8\xc0+F)\x90_<\xc2\fn0\xc55.\x01\xd1$\bC\x17\x8d\x00\x83\xb1\xae\xe6b\x18˘s\x11\x11G(\xd8p\x86KP\x17?\x99\x10\xcf~2q\x1fOX!\x14\xc3\xd0\xc5(0q\x06$\xa8\x01;\xa6\x01\xb2\x90ˑ\r\"w\xee\xc4)\x16\x1f2\xea\xf0\x03\x1a̠\a>\x10\x02J\x86\x10\x86:\xf4A\xa7\xe4\x80\x05\xfe\x1e$\x10\x81;\x14\"\x15\xad\xb0\xa1\xa4Za\x87\x14\xa4@\x10\x8a\x80\xb3t\xdcI\x062\b\x81\a8\xa8\x01\x19\x04\xe3\f@\xe4a\x0f\x80\xc8o9z\x81\x87\a8\x1a\x0f\xa9 \x06\x89)RL\x87T\x1a+\xd9X\x02_\x1fⲢe%\x1c\xb8HE\x1f\xf8\xc0\x87?L\xa2\x15\xb4\xa0\x051\x9c\x914n\x10\xa3\x17\xbd F2&\xad\rX|\xaf\x17̸\x8c78\xc1\x841\x00\"\x15\xaa\xf8\x83\x10(i\xc9\xd32\x83\x19ɐ\x0e7`ъ!\"cҔF\x02t!\x02\xb9ik%\x1bN\x8a\xab\xa4\xb8\xe1\x06*|t-j\xc9\fG\xa0\x1a\x91\xa4\x91\xa3\x13>\b\x82*h\x11\x9dp\xbcb\b5\xf8A4\xb12$\x1c?\xa4ރ\x01E\x12\x9c\xb0\x050\x80\xe1\nf\xe2\x05i䂍8\xd0 \x0f\x8a\x1eH/\x8e@\x80\x98\xc6\xe5:\x13\x81\xf8`\x8c\x11\x8aG\xb8\xc1\r\x910ŷ\a\x9e\x95\bϠ\x0f\x10\xf1\x86\x0fh\x80\xe0p\x8e\x9b\xfc\xe4\x89\xc1FĄ\x00:\x82X\x82\a{H8\xcagNs\xacL\x82\x065`\x82%\x80#\n4\b\xa1\x0f\xf2\xac\xb9ЇޓpH\x02\b<\xf0\x01\x13P\xa2\aU\xacb\xdeD\x8f\xba\xd4)B\vI\xfc\xe1\x0f\x808\x8a\xa4\xa7\xce\xf5\xaeO$\x1c\xdfІ6D\xe9\xf5\xb2\x9b\xfd\xechO\xbb\xda\xd7\xfe\x90\x80\x00\x00;") - -var appstats_css_css = []byte("/* Copyright 2012 Google Inc. All Rights Reserved. */\nhtml,body,div,h1,h2,h3,h4,h5,h6,p,img,dl,dt,dd,ol,ul,li,table,caption,tbody,tfoot,thead,tr,th,td,form,fieldset,embed,object,applet{margin:0;padding:0;border:0;}body{font-size:62.5%;font-family:Arial,sans-serif;color:#000;background:#fff}a{color:#00c}a:active{color:#f00}a:visited{color:#551a8b}table{border-collapse:collapse;border-width:0;empty-cells:show}ul{padding:0 0 1em 1em}ol{padding:0 0 1em 1.3em}li{line-height:1.5em;padding:0 0 .5em 0}p{padding:0 0 1em 0}h1,h2,h3,h4,h5{padding:0 0 1em 0}h1,h2{font-size:1.3em}h3{font-size:1.1em}h4,h5,table{font-size:1em}sup,sub{font-size:.7em}input,select,textarea,option{font-family:inherit;font-size:inherit}.g-doc,.g-doc-1024,.g-doc-800{font-size:130%}.g-doc{width:100%;text-align:left}.g-section{width:100%;vertical-align:top;display:inline-block}*:first-child+html .g-section{display:block}* html .g-section{overflow:hidden}@-moz-document url-prefix(''){.g-section{overflow:hidden}}@-moz-document url-prefix(''){.g-section,tt:default{overflow:visible}}.g-section,.g-unit{zoom:1}.g-split .g-unit{text-align:right}.g-split .g-first{text-align:left}.g-doc-1024{width:73.074em;min-width:950px;margin:0 auto;text-align:left}* html .g-doc-1024{width:71.313em}*+html .g-doc-1024{width:71.313em}.g-doc-800{width:57.69em;min-width:750px;margin:0 auto;text-align:left}* html .g-doc-800{width:56.3em}*+html .g-doc-800{width:56.3em}.g-tpl-160 .g-unit,.g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-tpl-160 .g-unit,.g-unit .g-unit .g-unit .g-tpl-160 .g-unit{margin:0 0 0 160px;width:auto;float:none}.g-unit .g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-unit .g-tpl-160 .g-first,.g-unit .g-tpl-160 .g-first,.g-tpl-160 .g-first{margin:0;width:160px;float:left}.g-tpl-160-alt .g-unit,.g-unit .g-tpl-160-alt .g-unit,.g-unit .g-unit .g-tpl-160-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-160-alt .g-unit{margin:0 160px 0 0;width:auto;float:none}.g-unit .g-unit .g-unit .g-tpl-160-alt .g-first,.g-unit .g-unit .g-tpl-160-alt .g-first,.g-unit .g-tpl-160-alt .g-first,.g-tpl-160-alt .g-first{margin:0;width:160px;float:right}.g-tpl-180 .g-unit,.g-unit .g-tpl-180 .g-unit,.g-unit .g-unit .g-tpl-180 .g-unit,.g-unit .g-unit .g-unit .g-tpl-180 .g-unit{margin:0 0 0 180px;width:auto;float:none}.g-unit .g-unit .g-unit .g-tpl-180 .g-first,.g-unit .g-unit .g-tpl-180 .g-first,.g-unit .g-tpl-180 .g-first,.g-tpl-180 .g-first{margin:0;width:180px;float:left}.g-tpl-180-alt .g-unit,.g-unit .g-tpl-180-alt .g-unit,.g-unit .g-unit .g-tpl-180-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-180-alt .g-unit{margin:0 180px 0 0;width:auto;float:none}.g-unit .g-unit .g-unit .g-tpl-180-alt .g-first,.g-unit .g-unit .g-tpl-180-alt .g-first,.g-unit .g-tpl-180-alt .g-first,.g-tpl-180-alt .g-first{margin:0;width:180px;float:right}.g-tpl-300 .g-unit,.g-unit .g-tpl-300 .g-unit,.g-unit .g-unit .g-tpl-300 .g-unit,.g-unit .g-unit .g-unit .g-tpl-300 .g-unit{margin:0 0 0 300px;width:auto;float:none}.g-unit .g-unit .g-unit .g-tpl-300 .g-first,.g-unit .g-unit .g-tpl-300 .g-first,.g-unit .g-tpl-300 .g-first,.g-tpl-300 .g-first{margin:0;width:300px;float:left}.g-tpl-300-alt .g-unit,.g-unit .g-tpl-300-alt .g-unit,.g-unit .g-unit .g-tpl-300-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-300-alt .g-unit{margin:0 300px 0 0;width:auto;float:none}.g-unit .g-unit .g-unit .g-tpl-300-alt .g-first,.g-unit .g-unit .g-tpl-300-alt .g-first,.g-unit .g-tpl-300-alt .g-first,.g-tpl-300-alt .g-first{margin:0;width:300px;float:right}.g-tpl-25-75 .g-unit,.g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-tpl-25-75 .g-unit,.g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit{width:74.999%;float:right;margin:0}.g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-unit .g-tpl-25-75 .g-first,.g-unit .g-tpl-25-75 .g-first,.g-tpl-25-75 .g-first{width:24.999%;float:left;margin:0}.g-tpl-25-75-alt .g-unit,.g-unit .g-tpl-25-75-alt .g-unit,.g-unit .g-unit .g-tpl-25-75-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-25-75-alt .g-unit{width:24.999%;float:left;margin:0}.g-unit .g-unit .g-unit .g-tpl-25-75-alt .g-first,.g-unit .g-unit .g-tpl-25-75-alt .g-first,.g-unit .g-tpl-25-75-alt .g-first,.g-tpl-25-75-alt .g-first{width:74.999%;float:right;margin:0}.g-tpl-75-25 .g-unit,.g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-tpl-75-25 .g-unit,.g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit{width:24.999%;float:right;margin:0}.g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-unit .g-tpl-75-25 .g-first,.g-unit .g-tpl-75-25 .g-first,.g-tpl-75-25 .g-first{width:74.999%;float:left;margin:0}.g-tpl-75-25-alt .g-unit,.g-unit .g-tpl-75-25-alt .g-unit,.g-unit .g-unit .g-tpl-75-25-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-75-25-alt .g-unit{width:74.999%;float:left;margin:0}.g-unit .g-unit .g-unit .g-tpl-75-25-alt .g-first,.g-unit .g-unit .g-tpl-75-25-alt .g-first,.g-unit .g-tpl-75-25-alt .g-first,.g-tpl-75-25-alt .g-first{width:24.999%;float:right;margin:0}.g-tpl-33-67 .g-unit,.g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-tpl-33-67 .g-unit,.g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit{width:66.999%;float:right;margin:0}.g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-unit .g-tpl-33-67 .g-first,.g-unit .g-tpl-33-67 .g-first,.g-tpl-33-67 .g-first{width:32.999%;float:left;margin:0}.g-tpl-33-67-alt .g-unit,.g-unit .g-tpl-33-67-alt .g-unit,.g-unit .g-unit .g-tpl-33-67-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-33-67-alt .g-unit{width:32.999%;float:left;margin:0}.g-unit .g-unit .g-unit .g-tpl-33-67-alt .g-first,.g-unit .g-unit .g-tpl-33-67-alt .g-first,.g-unit .g-tpl-33-67-alt .g-first,.g-tpl-33-67-alt .g-first{width:66.999%;float:right;margin:0}.g-tpl-67-33 .g-unit,.g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-tpl-67-33 .g-unit,.g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit{width:32.999%;float:right;margin:0}.g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-unit .g-tpl-67-33 .g-first,.g-unit .g-tpl-67-33 .g-first,.g-tpl-67-33 .g-first{width:66.999%;float:left;margin:0}.g-tpl-67-33-alt .g-unit,.g-unit .g-tpl-67-33-alt .g-unit,.g-unit .g-unit .g-tpl-67-33-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-67-33-alt .g-unit{width:66.999%;float:left;margin:0}.g-unit .g-unit .g-unit .g-tpl-67-33-alt .g-first,.g-unit .g-unit .g-tpl-67-33-alt .g-first,.g-unit .g-tpl-67-33-alt .g-first,.g-tpl-67-33-alt .g-first{width:32.999%;float:right;margin:0}.g-tpl-50-50 .g-unit,.g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-tpl-50-50 .g-unit,.g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit{width:49.999%;float:right;margin:0}.g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-unit .g-tpl-50-50 .g-first,.g-unit .g-tpl-50-50 .g-first,.g-tpl-50-50 .g-first{width:49.999%;float:left;margin:0}.g-tpl-50-50-alt .g-unit,.g-unit .g-tpl-50-50-alt .g-unit,.g-unit .g-unit .g-tpl-50-50-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-50-50-alt .g-unit{width:49.999%;float:left;margin:0}.g-unit .g-unit .g-unit .g-tpl-50-50-alt .g-first,.g-unit .g-unit .g-tpl-50-50-alt .g-first,.g-unit .g-tpl-50-50-alt .g-first,.g-tpl-50-50-alt .g-first{width:49.999%;float:right;margin:0}.g-tpl-nest{width:auto}.g-tpl-nest .g-section{display:inline}.g-tpl-nest .g-unit,.g-unit .g-tpl-nest .g-unit,.g-unit .g-unit .g-tpl-nest .g-unit,.g-unit .g-unit .g-unit .g-tpl-nest .g-unit{float:left;width:auto;margin:0}.g-tpl-nest-alt .g-unit,.g-unit .g-tpl-nest-alt .g-unit,.g-unit .g-unit .g-tpl-nest-alt .g-unit,.g-unit .g-unit .g-unit .g-tpl-nest-alt .g-unit{float:right;width:auto;margin:0}html>body .goog-inline-block{display:-moz-inline-box;display:inline-block;}.goog-inline-block{position:relative;display:inline-block}* html .goog-inline-block{display:inline}*:first-child+html .goog-inline-block{display:inline}.goog-tab{position:relative;border:1px solid #8ac;padding:4px 9px;color:#000;background:#e5ecf9;border-top-left-radius:2px;border-top-right-radius:2px;-moz-border-radius-topleft:2px;-webkit-border-top-left-radius:2px;-moz-border-radius-topright:2px;-webkit-border-top-right-radius:2px}.goog-tab-bar-top .goog-tab{margin:1px 4px 0 0;border-bottom:0;float:left}.goog-tab-bar-bottom .goog-tab{margin:0 4px 1px 0;border-top:0;float:left}.goog-tab-bar-start .goog-tab{margin:0 0 4px 1px;border-right:0}.goog-tab-bar-end .goog-tab{margin:0 1px 4px 0;border-left:0}.goog-tab-hover{text-decoration:underline;cursor:pointer}.goog-tab-disabled{color:#fff;background:#ccc;border-color:#ccc}.goog-tab-selected{background:#fff!important;color:black;font-weight:bold}.goog-tab-bar-top .goog-tab-selected{top:1px;margin-top:0;padding-bottom:5px}.goog-tab-bar-bottom .goog-tab-selected{top:-1px;margin-bottom:0;padding-top:5px}.goog-tab-bar-start .goog-tab-selected{left:1px;margin-left:0;padding-right:9px}.goog-tab-bar-end .goog-tab-selected{left:-1px;margin-right:0;padding-left:9px}.goog-tab-content{padding:.1em .8em .8em .8em;border:1px solid #8ac;border-top:none}.goog-tab-bar{position:relative;margin:0 0 0 5px;border:0;padding:0;list-style:none;cursor:default;outline:none}.goog-tab-bar-clear{border-top:1px solid #8ac;clear:both;height:0;overflow:hidden}.goog-tab-bar-start{float:left}.goog-tab-bar-end{float:right}* html .goog-tab-bar-start{margin-right:-3px}* html .goog-tab-bar-end{margin-left:-3px}.ae-table-plain{border-collapse:collapse;width:100%}.ae-table{border:1px solid #c5d7ef;border-collapse:collapse;width:100%}#bd h2.ae-table-title{background:#e5ecf9;margin:0;color:#000;font-size:1em;padding:3px 0 3px 5px;border-left:1px solid #c5d7ef;border-right:1px solid #c5d7ef;border-top:1px solid #c5d7ef}.ae-table-caption,.ae-table caption{border:1px solid #c5d7ef;background:#e5ecf9;-moz-margin-start:-1px}.ae-table caption{padding:3px 5px;text-align:left}.ae-table th,.ae-table td{background-color:#fff;padding:.35em 1em .25em .35em;margin:0}.ae-table thead th{font-weight:bold;text-align:left;background:#c5d7ef;vertical-align:bottom}.ae-table thead th .ae-no-bold{font-weight:normal}.ae-table tfoot tr td{border-top:1px solid #c5d7ef;background-color:#e5ecf9}.ae-table td{border-top:1px solid #c5d7ef;border-bottom:1px solid #c5d7ef}.ae-even>td,.ae-even th,.ae-even-top td,.ae-even-tween td,.ae-even-bottom td,ol.ae-even{background-color:#e9e9e9;border-top:1px solid #c5d7ef;border-bottom:1px solid #c5d7ef}.ae-even-top td{border-bottom:0}.ae-even-bottom td{border-top:0}.ae-even-tween td{border:0}.ae-table .ae-tween td{border:0}.ae-table .ae-tween-top td{border-bottom:0}.ae-table .ae-tween-bottom td{border-top:0}#bd .ae-table .cbc{width:1.5em;padding-right:0}.ae-table #ae-live td{background-color:#ffeac0}.ae-table-fixed{table-layout:fixed}.ae-table-fixed td,.ae-table-nowrap{overflow:hidden;white-space:nowrap}.ae-paginate strong{margin:0 .5em}tfoot .ae-paginate{text-align:right}.ae-table-caption .ae-paginate,.ae-table-caption .ae-orderby{padding:2px 5px}.g-doc{width:auto;margin:8px 10px 0 10px}#ae-logo{margin-bottom:0}#ae-appbar-lrg{margin:0 0 1.25em 0;padding:.2em .6em;background-color:#e5ecf9;border-top:1px solid #6b90da}#ae-appbar-lrg h1{font-size:1em;margin:0;padding:0}#ft p{text-align:center;margin-top:2.5em;padding-top:.5em;border-top:2px solid #c3d9ff}#bd h3{font-weight:bold;font-size:1.4em}#bd p{padding:0 0 1em 0}#ae-content{padding-left:1em;border-left:1px solid #6b90da;min-height:200px}.ae-table .ae-pager{background-color:#c5d7ef}#ae-nav ul{list-style-type:none;margin:0;padding:1em 0}#ae-nav ul li{padding:.1em 0 .1em .5em;margin-bottom:.3em}#ae-nav .ae-nav-selected{color:#44464a;display:block;font-weight:bold;background-color:#e5ecf9;border-bottom:1px solid #cedff2}a.ae-nav-selected{color:#44464a;text-decoration:none}#ae-nav ul li span.ae-nav-disabled{color:#666}#ae-nav ul ul{margin:0;padding:0 0 0 .5em}#ae-nav ul ul li{padding-left:.5em}#ae-nav ul li a,#ae-nav ul li span,#ae-nav ul ul li a{padding-left:.5em}#ae-nav li a:link,#ae-nav li a:visited{color:#00c}#ae-nav li a:link.ae-nav-selected,#ae-nav li a:visited.ae-nav-selected{color:#000;text-decoration:none}.ae-nav-group{padding:.5em;margin:0 .75em 0 0;background-color:#fffbe8;border:1px solid #fff1a9}.ae-nav-group h4{font-weight:bold;padding:auto auto .5em .5em;padding-left:.4em;margin-bottom:.5em;padding-bottom:0}.ae-nav-group ul{margin:0 0 .5em 0;padding:0 0 0 1.3em;list-style-type:none}.ae-nav-group ul li{padding-bottom:.5em}.ae-nav-group li a:link,.ae-nav-group li a:visited{color:#00c}.ae-nav-group li a:hover{color:#00c}#datastore_search{margin-bottom:1em}#hint{background-color:#f6f9ff;border:1px solid #e5ecf9;margin-bottom:1em;padding:0.5em 1em}#message{color:red;position:relative;bottom:6px}#pagetotal{float:right}#pagetotal .count{font-weight:bold}table.entities{border:1px solid #c5d7ef;border-collapse:collapse;width:100%;margin-bottom:0}table.entities th,table.entities td{padding:.25em 1.5em .5em .5em}table.entities th{font-weight:bold;text-align:left;background:#e5ecf9;white-space:nowrap}table.entities th a,table.entities th a:visited{color:black;text-decoration:none}table.entities td{background-color:#fff;text-align:left;vertical-align:top;cursor:pointer}table.entities tr.even td{background-color:#f9f9f9}div.entities{background-color:#c5d7ef;margin-top:0}#entities-pager,#entities-control{padding:.3em 1em .4em 1em}#entities-pager{text-align:right}.ae-page-number{margin:0 0.5em}.ae-page-selected{font-weight:bold}#ae-stats-hd span{font-weight:normal}#ae-rpc-label-col{width:85%}#ae-rpc-stats-col{width:15%}#ae-path-label-col{width:45%}#ae-path-reqs-col{width:10%}#ae-path-rpcs-col{width:10%}#ae-path-stats-col{width:35%}#ae-stats-refresh{margin-bottom:1em}.ae-table-wrapper-left{margin-right:.5em}.ae-table-wrapper-right{margin-left:.5em}#ae-req-history,#ae-rpc-traces{margin-top:1em}.ae-zippy,.ae-zippy-all{position:relative;top:1px;height:12px;width:12px}.goog-zippy-collapsed{background:transparent url('./plus.gif') no-repeat}.goog-zippy-expanded{background:transparent url('./minus.gif') no-repeat}td.ae-hanging-indent{padding-left:20px;text-indent:-20px}.ae-stats-request-link{text-decoration:none}.ae-table td.rpc-req{padding-left:20px;width:20em}#bd div.ae-table-title{background:#e5ecf9;margin:0;color:#000;padding:3px 0 3px 5px;border-left:1px solid #c5d7ef;border-right:1px solid #c5d7ef;border-top:1px solid #c5d7ef}#bd div.ae-table-title h2{font-size:1em;margin:0;padding:0}#bd div.ae-table-title h2.ae-zippy{padding-left:16px;text-decoration:underline;color:#00c}#ae-head-glance span,#ae-rpc-expand-all span,#ae-path-expand-all span,#ae-request-expand-all span{padding-right:.5em}.ae-action{color:#00c;text-decoration:underline;cursor:pointer}.ae-toggle{padding-left:16px;background-position:left center;background-repeat:no-repeat;cursor:pointer}.ae-minus{background-image:url('./minus.gif')}.ae-plus{background-image:url('./plus.gif')}#ae-stats-summary{margin-bottom:1em}#ae-stats-summary dt{float:left;text-align:right;margin-right:1em;font-weight:bold}.ae-stats-date{color:#666}.ae-stats-response-200{color:green}#ae-stats-summary dd{float:left}table.ae-stats-gantt-table{width:95%;border:1px solid #999}div.ae-stats-gantt-container{position:relative;width:100%;height:1em;background-color:#eeeeff}img.ae-stats-gantt-bar{border:0;height:1em;background-color:#7777ff;position:absolute;top:0}img.ae-stats-gantt-extra{border:0;height:0.5em;background-color:#ff6666;position:absolute;top:25%}span.ae-stats-gantt-inline{font-size:80%;position:absolute;top:0.1em;white-space:nowrap;overflow:hidden}a.ae-stats-gantt-link{text-decoration:none}div.ae-stats-gantt-axis{position:relative;width:100%;height:1em}img.ae-stats-gantt-tick{width:1px;height:1em;position:absolute;background-color:gray}span.ae-stats-gantt-scale{position:absolute}") - -var appstats_js_js = []byte("/* Copyright 2008-10 Google Inc. All Rights Reserved. */ (function(){function e(a){throw a;}\nvar h=void 0,k=!0,l=null,p=!1,r,s=this,aa=function(){},ba=function(a){a.M=function(){return a.Db?a.Db:a.Db=new a}},ca=function(a){var b=typeof a;if(\"object\"==b)if(a){if(a instanceof Array)return\"array\";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(\"[object Window]\"==c)return\"object\";if(\"[object Array]\"==c||\"number\"==typeof a.length&&\"undefined\"!=typeof a.splice&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"splice\"))return\"array\";if(\"[object Function]\"==\nc||\"undefined\"!=typeof a.call&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"call\"))return\"function\"}else return\"null\";else if(\"function\"==b&&\"undefined\"==typeof a.call)return\"object\";return b},da=function(a){return\"array\"==ca(a)},u=function(a){return\"string\"==typeof a},w=function(a){return\"function\"==ca(a)},ea=function(a){var b=typeof a;return\"object\"==b&&a!=l||\"function\"==b},x=function(a){return a[fa]||(a[fa]=++ga)},fa=\"closure_uid_\"+Math.floor(2147483648*Math.random()).toString(36),\nga=0,ha=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=Array.prototype.slice.call(arguments);b.unshift.apply(b,c);return a.apply(this,b)}},ia=function(a,b){var c=a.split(\".\"),d=s;!(c[0]in d)&&d.execScript&&d.execScript(\"var \"+c[0]);for(var g;c.length&&(g=c.shift());)!c.length&&b!==h?d[g]=b:d=d[g]?d[g]:d[g]={}},y=function(a,b){function c(){}c.prototype=b.prototype;a.e=b.prototype;a.prototype=new c;a.prototype.constructor=a};var ja=function(a){Error.captureStackTrace?Error.captureStackTrace(this,ja):this.stack=Error().stack||\"\";a&&(this.message=String(a))};y(ja,Error);ja.prototype.name=\"CustomError\";var ka=function(a,b){for(var c=1;c\")&&(a=a.replace(pa,\">\"));-1!=a.indexOf('\"')&&(a=a.replace(qa,\""\"));return a},na=/&/g,oa=//g,qa=/\\\"/g,ma=/[&<>\\\"]/;var sa=function(a,b){b.unshift(a);ja.call(this,ka.apply(l,b));b.shift()};y(sa,ja);sa.prototype.name=\"AssertionError\";var ta=function(a,b,c){var d=\"Assertion failed\";if(b)var d=d+(\": \"+b),g=c;else a&&(d+=\": \"+a,g=l);e(new sa(\"\"+d,g||[]))},z=function(a,b,c){a||ta(\"\",b,Array.prototype.slice.call(arguments,2))},ua=function(a,b,c,d){a instanceof b||ta(\"instanceof check failed.\",c,Array.prototype.slice.call(arguments,3))};var A=Array.prototype,va=A.indexOf?function(a,b,c){z(a.length!=l);return A.indexOf.call(a,b,c)}:function(a,b,c){c=c==l?0:0>c?Math.max(0,a.length+c):c;if(u(a))return!u(b)||1!=b.length?-1:a.indexOf(b,c);for(;c=arguments.length?A.slice.call(a,b):A.slice.call(a,b,c)};var Ea=function(a,b,c){b in a&&e(Error('The object already contains the key \"'+b+'\"'));a[b]=c},Fa=function(a){var b={},c;for(c in a)b[a[c]]=c;return b},Ga=\"constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf\".split(\" \"),Ha=function(a,b){for(var c,d,g=1;gparseFloat(Ua)){Ta=String(Ya);break a}}Ta=Ua}\nvar Za=Ta,$a={},F=function(a){var b;if(!(b=$a[a])){b=0;for(var c=la(String(Za)).split(\".\"),d=la(String(a)).split(\".\"),g=Math.max(c.length,d.length),f=0;0==b&&f(0==v[1].length?0:parseInt(v[1],10))?1:\n0)||((0==t[2].length)<(0==v[2].length)?-1:(0==t[2].length)>(0==v[2].length)?1:0)||(t[2]v[2]?1:0)}while(0==b)}b=$a[a]=0<=b}return b},ab=s.document,bb=!ab||!B?h:Sa()||(\"CSS1Compat\"==ab.compatMode?parseInt(Za,10):5);var cb,db=!B||B&&9<=bb;!C&&!B||B&&B&&9<=bb||C&&F(\"1.9.1\");var eb=B&&!F(\"9\");var fb=function(a){a=a.className;return u(a)&&a.match(/\\S+/g)||[]},G=function(a,b){for(var c=fb(a),d=Ca(arguments,1),g=c.length+d.length,f=c,j=0;j\");c=c.join(\"\")}var f=a.createElement(c);if(d)if(u(d))f.className=d;else if(da(d))G.apply(l,[f].concat(d));else{var c=function(a,b){\"style\"==b?f.style.cssText=a:\"class\"==b?f.className=a:\"for\"==b?f.htmlFor=a:b in mb?f.setAttribute(mb[b],a):0==b.lastIndexOf(\"aria-\",0)||0==b.lastIndexOf(\"data-\",0)?f.setAttribute(b,a):f[b]=a},j;for(j in d)c.call(h,d[j],j)}if(2a):p},vb=function(a,b,c){if(!(a.nodeName in sb))if(3==a.nodeType)c?b.push(String(a.nodeValue).replace(/(\\r\\n|\\r|\\n)/g,\"\")):b.push(a.nodeValue);else if(a.nodeName in tb)b.push(tb[a.nodeName]);else for(a=a.firstChild;a;)vb(a,b,c),a=a.nextSibling},hb=function(a){this.B=a||s.document||document};r=hb.prototype;r.Fa=jb;r.a=function(a){return u(a)?this.B.getElementById(a):a};\nr.k=function(a,b,c){return nb(this.B,arguments)};r.createElement=function(a){return this.B.createElement(a)};r.createTextNode=function(a){return this.B.createTextNode(a)};r.appendChild=function(a,b){a.appendChild(b)};r.contains=qb;var wb=function(a){wb[\" \"](a);return a};wb[\" \"]=aa;var xb=!B||B&&9<=bb,yb=!B||B&&9<=bb,zb=B&&!F(\"9\");!D||F(\"528\");C&&F(\"1.9b\")||B&&F(\"8\")||Qa&&F(\"9.5\")||D&&F(\"528\");C&&!F(\"8\")||B&&F(\"9\");var Ab=function(){};Ab.prototype.Rb=p;var H=function(a,b){this.type=a;this.currentTarget=this.target=b};r=H.prototype;r.Z=p;r.defaultPrevented=p;r.Ia=k;r.stopPropagation=function(){this.Z=k};r.preventDefault=function(){this.defaultPrevented=k;this.Ia=p};var I=function(a,b){a&&this.sa(a,b)};y(I,H);var Bb=[1,4,2];r=I.prototype;r.target=l;r.relatedTarget=l;r.offsetX=0;r.offsetY=0;r.clientX=0;r.clientY=0;r.screenX=0;r.screenY=0;r.button=0;r.keyCode=0;r.charCode=0;r.ctrlKey=p;r.altKey=p;r.shiftKey=p;r.metaKey=p;r.Ya=p;r.P=l;\nr.sa=function(a,b){var c=this.type=a.type;H.call(this,c);this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(C){var g;a:{try{wb(d.nodeName);g=k;break a}catch(f){}g=p}g||(d=l)}}else\"mouseover\"==c?d=a.fromElement:\"mouseout\"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=D||a.offsetX!==h?a.offsetX:a.layerX;this.offsetY=D||a.offsetY!==h?a.offsetY:a.layerY;this.clientX=a.clientX!==h?a.clientX:a.pageX;this.clientY=a.clientY!==h?a.clientY:a.pageY;this.screenX=a.screenX||\n0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||(\"keypress\"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.Ya=E?a.metaKey:a.ctrlKey;this.state=a.state;this.P=a;a.defaultPrevented&&this.preventDefault();delete this.Z};var Cb=function(a){return xb?0==a.P.button:\"click\"==a.type?k:!!(a.P.button&Bb[0])};\nI.prototype.stopPropagation=function(){I.e.stopPropagation.call(this);this.P.stopPropagation?this.P.stopPropagation():this.P.cancelBubble=k};I.prototype.preventDefault=function(){I.e.preventDefault.call(this);var a=this.P;if(a.preventDefault)a.preventDefault();else if(a.returnValue=p,zb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};var Db=function(){},Eb=0;r=Db.prototype;r.key=0;r.Y=p;r.Cb=p;r.sa=function(a,b,c,d,g,f){w(a)?this.Ab=k:a&&a.handleEvent&&w(a.handleEvent)?this.Ab=p:e(Error(\"Invalid listener argument\"));this.ea=a;this.tb=b;this.src=c;this.type=d;this.capture=!!g;this.Aa=f;this.Cb=p;this.key=++Eb;this.Y=p};r.handleEvent=function(a){return this.Ab?this.ea.call(this.Aa||this.src,a):this.ea.handleEvent.call(this.ea,a)};var Fb={},J={},Gb={},Hb={},K=function(a,b,c,d,g){if(b){if(da(b)){for(var f=0;ff.keyCode||f.returnValue!=h)return k;a:{var q=p;if(0==f.keyCode)try{f.keyCode=-1;break a}catch(t){q=k}if(q||f.returnValue==h)f.returnValue=k}}q=new I;q.sa(f,this);f=k;try{if(m){for(var v=[],Pa=q.currentTarget;Pa;Pa=Pa.parentNode)v.push(Pa);j=g[k];j.v=j.C;for(var S=v.length-1;!q.Z&&0<=S&&j.v;S--)q.currentTarget=v[S],f&=Nb(j,v[S],d,k,q);if(n){j=g[p];j.v=j.C;for(S=0;!q.Z&&Sb||b>bc(this))&&e(Error(\"Child component index out of bounds\"));if(!this.h||!this.r)this.h={},this.r=[];if(a.getParent()==this){var d=Xb(a);this.h[d]=a;Aa(this.r,a)}else Ea(this.h,Xb(a),a);$b(a,this);Da(this.r,b,0,a);a.d&&this.d&&a.getParent()==this?(c=this.z(),c.insertBefore(a.a(),c.childNodes[b]||l)):c?(this.c||this.k(),c=P(this,b+1),b=this.z(),c=c?c.c:l,a.d&&e(Error(\"Component already rendered\")),a.c||a.k(),b?b.insertBefore(a.c,\nc||l):a.m.B.body.appendChild(a.c),(!a.n||a.n.d)&&a.t()):this.d&&(!a.d&&a.c&&a.c.parentNode&&1==a.c.parentNode.nodeType)&&a.t()};r.z=function(){return this.c};\nvar cc=function(a){if(a.pa==l){var b;a:{b=a.d?a.c:a.m.B.body;var c=ib(b);if(c.defaultView&&c.defaultView.getComputedStyle&&(b=c.defaultView.getComputedStyle(b,l))){b=b.direction||b.getPropertyValue(\"direction\")||\"\";break a}b=\"\"}a.pa=\"rtl\"==(b||((a.d?a.c:a.m.B.body).currentStyle?(a.d?a.c:a.m.B.body).currentStyle.direction:l)||(a.d?a.c:a.m.B.body).style&&(a.d?a.c:a.m.B.body).style.direction)}return a.pa};O.prototype.na=function(a){this.d&&e(Error(\"Component already rendered\"));this.pa=a};\nvar bc=function(a){return a.r?a.r.length:0},P=function(a,b){return a.r?a.r[b]||l:l},ac=function(a,b,c){a.r&&wa(a.r,b,c)},dc=function(a,b){return a.r&&b?va(a.r,b):-1};O.prototype.removeChild=function(a,b){if(a){var c=u(a)?a:Xb(a);a=this.h&&c?(c in this.h?this.h[c]:h)||l:l;if(c&&a){var d=this.h;c in d&&delete d[c];Aa(this.r,a);b&&(a.$(),a.c&&pb(a.c));$b(a,l)}}a||e(Error(\"Child is not in parent component\"));return a};var fc=function(a,b,c,d,g){if(!B&&(!D||!F(\"525\")))return k;if(E&&g)return ec(a);if(g&&!d||!c&&(17==b||18==b||E&&91==b))return p;if(D&&d&&c)switch(a){case 220:case 219:case 221:case 192:case 186:case 189:case 187:case 188:case 190:case 191:case 192:case 222:return p}if(B&&d&&b==a)return p;switch(a){case 13:return!(B&&B&&9<=bb);case 27:return!D}return ec(a)},ec=function(a){if(48<=a&&57>=a||96<=a&&106>=a||65<=a&&90>=a||D&&0==a)return k;switch(a){case 32:case 63:case 107:case 109:case 110:case 111:case 186:case 59:case 189:case 187:case 61:case 188:case 190:case 191:case 192:case 222:case 219:case 220:case 221:return k;\ndefault:return p}},gc=function(a){switch(a){case 61:return 187;case 59:return 186;case 224:return 91;case 0:return 224;default:return a}};var Q=function(a,b){a&&hc(this,a,b)};y(Q,Qb);r=Q.prototype;r.c=l;r.Ba=l;r.Sa=l;r.Ca=l;r.s=-1;r.N=-1;r.gb=p;\nvar ic={3:13,12:144,63232:38,63233:40,63234:37,63235:39,63236:112,63237:113,63238:114,63239:115,63240:116,63241:117,63242:118,63243:119,63244:120,63245:121,63246:122,63247:123,63248:44,63272:46,63273:36,63275:35,63276:33,63277:34,63289:144,63302:45},jc={Up:38,Down:40,Left:37,Right:39,Enter:13,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,\"U+007F\":46,Home:36,End:35,PageUp:33,PageDown:34,Insert:45},kc=B||D&&F(\"525\"),lc=E&&C;\nQ.prototype.Pb=function(a){if(D&&(17==this.s&&!a.ctrlKey||18==this.s&&!a.altKey||E&&91==this.s&&!a.metaKey))this.N=this.s=-1;-1==this.s&&(a.ctrlKey&&17!=a.keyCode?this.s=17:a.altKey&&18!=a.keyCode?this.s=18:a.metaKey&&91!=a.keyCode&&(this.s=91));kc&&!fc(a.keyCode,this.s,a.shiftKey,a.ctrlKey,a.altKey)?this.handleEvent(a):(this.N=C?gc(a.keyCode):a.keyCode,lc&&(this.gb=a.altKey))};Q.prototype.Qb=function(a){this.N=this.s=-1;this.gb=a.altKey};\nQ.prototype.handleEvent=function(a){var b=a.P,c,d,g=b.altKey;B&&\"keypress\"==a.type?(c=this.N,d=13!=c&&27!=c?b.keyCode:0):D&&\"keypress\"==a.type?(c=this.N,d=0<=b.charCode&&63232>b.charCode&&ec(c)?b.charCode:0):Qa?(c=this.N,d=ec(c)?b.keyCode:0):(c=b.keyCode||this.N,d=b.charCode||0,lc&&(g=this.gb),E&&(63==d&&224==c)&&(c=191));var f=c,j=b.keyIdentifier;c?63232<=c&&c in ic?f=ic[c]:25==c&&a.shiftKey&&(f=9):j&&j in jc&&(f=jc[j]);a=f==this.s;this.s=f;b=new mc(f,d,a,b);b.altKey=g;this.dispatchEvent(b)};\nQ.prototype.a=function(){return this.c};var hc=function(a,b,c){a.Ca&&a.detach();a.c=b;a.Ba=K(a.c,\"keypress\",a,c);a.Sa=K(a.c,\"keydown\",a.Pb,c,a);a.Ca=K(a.c,\"keyup\",a.Qb,c,a)};Q.prototype.detach=function(){this.Ba&&(L(this.Ba),L(this.Sa),L(this.Ca),this.Ca=this.Sa=this.Ba=l);this.c=l;this.N=this.s=-1};var mc=function(a,b,c,d){d&&this.sa(d,h);this.type=\"key\";this.keyCode=a;this.charCode=b;this.repeat=c};y(mc,I);var oc=function(a,b){a||e(Error(\"Invalid class name \"+a));w(b)||e(Error(\"Invalid decorator function \"+b));nc[a]=b},pc={},nc={};var R=function(){},qc;ba(R);r=R.prototype;r.I=function(){};r.k=function(a){var b=a.Fa().k(\"div\",this.ra(a).join(\" \"),a.wa);rc(a,b);return b};r.z=function(a){return a};r.oa=function(a,b,c){if(a=a.a?a.a():a)if(B&&!F(\"7\")){var d=sc(fb(a),b);d.push(b);ha(c?G:gb,a).apply(l,d)}else c?G(a,b):gb(a,b)};r.X=function(){return k};\nr.H=function(a,b){b.id&&Yb(a,b.id);var c=this.z(b);c&&c.firstChild?(c=c.firstChild.nextSibling?Ba(c.childNodes):c.firstChild,a.wa=c):a.wa=l;var d=0,g=this.o(),f=this.o(),j=p,m=p,c=p,n=fb(b);wa(n,function(a){if(!j&&a==g)j=k,f==g&&(m=k);else if(!m&&a==f)m=k;else{var b=d;this.nb||(this.Da||tc(this),this.nb=Fa(this.Da));a=parseInt(this.nb[a],10);d=b|(isNaN(a)?0:a)}},this);a.f=d;j||(n.push(g),f==g&&(m=k));m||n.push(f);var q=a.F;q&&n.push.apply(n,q);if(B&&!F(\"7\")){var t=sc(n);0a?b-1:a},0);break;case 38:if(\"vertical\"==this.K)Kc(this);else return p;break;case 37:if(\"horizontal\"==this.K)cc(this)?Lc(this):\nKc(this);else return p;break;case 40:if(\"vertical\"==this.K)Lc(this);else return p;break;case 39:if(\"horizontal\"==this.K)cc(this)?Kc(this):Lc(this);else return p;break;default:return p}return k};var Gc=function(a,b){var c=b.a(),c=c.id||(c.id=Xb(b));a.L||(a.L={});a.L[c]=b};W.prototype.za=function(a,b){ua(a,T,\"The child of a container must be a control\");W.e.za.call(this,a,b)};\nW.prototype.Oa=function(a,b,c){a.S|=2;a.S|=64;(this.R()||!this.Ob)&&zc(a,32,p);a.Ka(p);W.e.Oa.call(this,a,b,c);a.d&&this.d&&Gc(this,a);b<=this.i&&this.i++};W.prototype.removeChild=function(a,b){if(a=u(a)?this.h&&a?(a in this.h?this.h[a]:h)||l:l:a){var c=dc(this,a);-1!=c&&(c==this.i?a.A(p):ca?c-1:a},a.i)},Jc=function(a,b,c){c=0>c?dc(a,a.g):c;var d=bc(a);c=b.call(a,c,d);for(var g=0;g<=d;){var f=P(a,c);if(f&&f.D()&&f.isEnabled()&&f.p&2){a.Qa(c);break}g++;c=b.call(a,c,d)}};W.prototype.Qa=function(a){Ic(this,a)};var Mc=function(){};y(Mc,R);ba(Mc);r=Mc.prototype;r.o=function(){return\"goog-tab\"};r.I=function(){return\"tab\"};r.k=function(a){var b=Mc.e.k.call(this,a);(a=a.Na())&&this.Pa(b,a);return b};r.H=function(a,b){b=Mc.e.H.call(this,a,b);var c=this.Na(b);c&&(a.mb=c);if(a.f&8&&(c=a.getParent())&&w(c.V))a.u(8,p),c.V(a);return b};r.Na=function(a){return a.title||\"\"};r.Pa=function(a,b){a&&(a.title=b||\"\")};var Nc=function(a,b,c){T.call(this,a,b||Mc.M(),c);zc(this,8,k);this.S|=9};y(Nc,T);Nc.prototype.Na=function(){return this.mb};Nc.prototype.Pa=function(a){this.vb().Pa(this.a(),a);this.mb=a};oc(\"goog-tab\",function(){return new Nc(l)});var X=function(){};y(X,Ec);ba(X);X.prototype.o=function(){return\"goog-tab-bar\"};X.prototype.I=function(){return\"tablist\"};X.prototype.Ma=function(a,b,c){this.wb||(this.Ea||Oc(this),this.wb=Fa(this.Ea));var d=this.wb[b];d?(Fc(a,Pc(d)),a.pb=d):X.e.Ma.call(this,a,b,c)};X.prototype.ra=function(a){var b=X.e.ra.call(this,a);this.Ea||Oc(this);b.push(this.Ea[a.pb]);return b};var Oc=function(a){var b=a.o();a.Ea={top:b+\"-top\",bottom:b+\"-bottom\",start:b+\"-start\",end:b+\"-end\"}};var Y=function(a,b,c){a=a||\"top\";Fc(this,Pc(a));this.pb=a;W.call(this,this.K,b||X.M(),c);Qc(this)};y(Y,W);r=Y.prototype;r.Ub=k;r.G=l;r.t=function(){Y.e.t.call(this);Qc(this)};r.removeChild=function(a,b){Rc(this,a);return Y.e.removeChild.call(this,a,b)};r.Qa=function(a){Y.e.Qa.call(this,a);this.Ub&&this.V(P(this,a))};r.V=function(a){a?xc(a,k):this.G&&xc(this.G,p)};\nvar Rc=function(a,b){if(b&&b==a.G){for(var c=dc(a,b),d=c-1;b=P(a,d);d--)if(b.D()&&b.isEnabled()){a.V(b);return}for(c+=1;b=P(a,c);c++)if(b.D()&&b.isEnabled()){a.V(b);return}a.V(l)}};r=Y.prototype;r.ac=function(a){this.G&&this.G!=a.target&&xc(this.G,p);this.G=a.target};r.bc=function(a){a.target==this.G&&(this.G=l)};r.Zb=function(a){Rc(this,a.target)};r.$b=function(a){Rc(this,a.target)};r.ma=function(){P(this,this.i)||this.A(this.G||P(this,0))};\nvar Qc=function(a){M(M(M(M(Zb(a),a,\"select\",a.ac),a,\"unselect\",a.bc),a,\"disable\",a.Zb),a,\"hide\",a.$b)},Pc=function(a){return\"start\"==a||\"end\"==a?\"vertical\":\"horizontal\"};oc(\"goog-tab-bar\",function(){return new Y});var Z=function(a,b,c,d,g){function f(a){a&&(a.tabIndex=0,a.setAttribute(\"role\",j.I()),G(a,\"goog-zippy-header\"),Sc(j,a),a&&M(j.Lb,a,\"keydown\",j.Mb))}this.m=g||jb();this.T=this.m.a(a)||l;this.xa=this.m.a(d||l);this.ba=(this.La=w(b)?b:l)||!b?l:this.m.a(b);this.l=c==k;this.Lb=new Ob(this);this.kb=new Ob(this);var j=this;f(this.T);f(this.xa);this.W(this.l)};y(Z,Qb);r=Z.prototype;r.fa=k;r.ic=k;r.I=function(){return\"tab\"};r.z=function(){return this.ba};r.toggle=function(){this.W(!this.l)};\nr.W=function(a){this.ba?Rb(this.ba,a):a&&this.La&&(this.ba=this.La());this.ba&&G(this.ba,\"goog-zippy-content\");if(this.xa)Rb(this.T,!a),Rb(this.xa,a);else if(this.T){var b=this.T;a?G(b,\"goog-zippy-expanded\"):gb(b,\"goog-zippy-expanded\");b=this.T;!a?G(b,\"goog-zippy-collapsed\"):gb(b,\"goog-zippy-collapsed\");this.T.setAttribute(\"aria-expanded\",a)}this.l=a;this.dispatchEvent(new Tc(\"toggle\",this))};r.lb=function(){return this.ic};\nr.Ka=function(a){this.fa!=a&&((this.fa=a)?(Sc(this,this.T),Sc(this,this.xa)):(a=this.kb,wa(a.da,L),a.da.length=0))};var Sc=function(a,b){b&&M(a.kb,b,\"click\",a.dc)};Z.prototype.Mb=function(a){if(13==a.keyCode||32==a.keyCode)this.toggle(),this.dispatchEvent(new H(\"action\",this)),a.preventDefault(),a.stopPropagation()};Z.prototype.dc=function(){this.toggle();this.dispatchEvent(new H(\"action\",this))};var Tc=function(a,b){H.call(this,a,b)};y(Tc,H);var Vc=function(a,b){this.ib=[];for(var c=kb(a),c=lb(\"span\",\"ae-zippy\",c),d=0,g;g=c[d];d++){var f;if(g.parentNode.parentNode.parentNode.nextElementSibling!=h)f=g.parentNode.parentNode.parentNode.nextElementSibling;else for(f=g.parentNode.parentNode.parentNode.nextSibling;f&&1!=f.nodeType;)f=f.nextSibling;g=new Z(g,f,p);this.ib.push(g)}this.cc=new Uc(this.ib,kb(b))};Vc.prototype.gc=function(){return this.cc};Vc.prototype.hc=function(){return this.ib};\nvar Uc=function(a,b){this.ta=a;if(this.ta.length)for(var c=0,d;d=this.ta[c];c++)K(d,\"toggle\",this.Tb,p,this);this.Ha=0;this.l=p;c=\"ae-toggle ae-plus ae-action\";this.ta.length||(c+=\" ae-disabled\");this.Q=ob(\"span\",{className:c},\"Expand All\");K(this.Q,\"click\",this.Sb,p,this);b&&b.appendChild(this.Q)};Uc.prototype.Sb=function(){this.ta.length&&this.W(!this.l)};\nUc.prototype.Tb=function(a){a=a.currentTarget;this.Ha=a.l?this.Ha+1:this.Ha-1;a.l!=this.l&&(a.l?(this.l=k,Wc(this,k)):0==this.Ha&&(this.l=p,Wc(this,p)))};Uc.prototype.W=function(a){this.l=a;a=0;for(var b;b=this.ta[a];a++)b.l!=this.l&&b.W(this.l);Wc(this)};\nvar Wc=function(a,b){(b!==h?b:a.l)?(gb(a.Q,\"ae-plus\"),G(a.Q,\"ae-minus\"),rb(a.Q,\"Collapse All\")):(gb(a.Q,\"ae-minus\"),G(a.Q,\"ae-plus\"),rb(a.Q,\"Expand All\"))},Xc=function(a){this.Vb=a;this.Bb={};var b,c=ob(\"div\",{},b=ob(\"div\",{id:\"ae-stats-details-tabs\",className:\"goog-tab-bar goog-tab-bar-top\"}),ob(\"div\",{className:\"goog-tab-bar-clear\"}),a=ob(\"div\",{id:\"ae-stats-details-tabs-content\",className:\"goog-tab-content\"})),d=new Y;d.H(b);K(d,\"select\",this.yb,p,this);K(d,\"unselect\",this.yb,p,this);b=0;for(var g;g=\nthis.Vb[b];b++)if(g=kb(\"ae-stats-details-\"+g)){var f=lb(\"h2\",l,g)[0],j;j=f;var m=h;eb&&\"innerText\"in j?m=j.innerText.replace(/(\\r\\n|\\r|\\n)/g,\"\\n\"):(m=[],vb(j,m,k),m=m.join(\"\"));m=m.replace(/ \\xAD /g,\" \").replace(/\\xAD/g,\"\");m=m.replace(/\\u200B/g,\"\");eb||(m=m.replace(/ +/g,\" \"));\" \"!=m&&(m=m.replace(/^\\s*/,\"\"));j=m;pb(f);f=new Nc(j);this.Bb[x(f)]=g;d.za(f,k);a.appendChild(g);0==b?d.V(f):Rb(g,p)}kb(\"bd\").appendChild(c)};Xc.prototype.yb=function(a){var b=this.Bb[x(a.target)];Rb(b,\"select\"==a.type)};\nia(\"ae.Stats.Details.Tabs\",Xc);ia(\"goog.ui.Zippy\",Z);Z.prototype.setExpanded=Z.prototype.W;ia(\"ae.Stats.MakeZippys\",Vc);Vc.prototype.getExpandCollapse=Vc.prototype.gc;Vc.prototype.getZippys=Vc.prototype.hc;Uc.prototype.setExpanded=Uc.prototype.W;var $=function(){this.Za=[];this.cb=[]},Yc=[[5,0.2,1],[6,0.2,1.2],[5,0.25,1.25],[6,0.25,1.5],[4,0.5,2],[5,0.5,2.5],[6,0.5,3],[4,1,4],[5,1,5],[6,1,6],[4,2,8],[5,2,10]],Zc=function(a){if(0>=a)return[2,0.5,1];for(var b=1;1>a;)a*=10,b/=10;for(;10<=a;)a/=10,b*=10;for(var c=0;c');a.write('
');for(var g=0;g<=b;g++)a.write('\"\"'),a.write(''),a.write(\" \"+g*c+\"\");a.write(\"
\\n\")};\n$.prototype.fc=function(){this.cb=[];var a=Zc(this.ab),b=a[0],c=a[1],a=100/a[2];this.write('\\n');$c(this,b,c,a);for(var d=0;d\\n\\n\")}$c(this,b,c,a);this.write(\"
');0'),this.write(g.label),0\"));this.write(\"\");this.write('
');0');this.write('\"\"');0'));0 '),this.write(g.ub),this.write(\"\"));0\");this.write(\"
\\n\");return this.cb.join(\"\")};$.prototype.ec=function(a,b,c,d,g,f){this.ab=Math.max(this.ab,Math.max(b+c,b+d));this.Za.push({label:a,start:b,duration:c,$a:d,ub:g,ga:f})};ia(\"Gantt\",$);$.prototype.add_bar=$.prototype.ec;$.prototype.draw=$.prototype.fc;})();\n") - -var gantt_js = []byte("// Copyright 2009 Google Inc. All Rights Reserved.\n\n/**\n * Defines a class that can render a simple Gantt chart.\n *\n * @author guido@google.com (Guido van Rossum)\n * @author schefflerjens@google.com (Jens Scheffler)\n */\n\n/**\n * @constructor\n */\nvar Gantt = function() {\n /**\n * @type {Array}\n */\n this.bars = [];\n\n /**\n * @type {Array}\n */\n this.output = [];\n};\n\n\n/**\n * Internal fields used to render the chart.\n * Should not be modified.\n * @type {Array.}\n */\nGantt.SCALES = [[5, 0.2, 1.0],\n [6, 0.2, 1.2],\n [5, 0.25, 1.25],\n [6, 0.25, 1.5],\n [4, 0.5, 2.0],\n [5, 0.5, 2.5],\n [6, 0.5, 3.0],\n [4, 1.0, 4.0],\n [5, 1.0, 5.0],\n [6, 1.0, 6.0],\n [4, 2.0, 8.0],\n [5, 2.0, 10.0]];\n\n\n/**\n * Helper to compute the proper X axis scale.\n * Args:\n * highest: the highest value in the data series.\n *\n * Returns:\n * A tuple (howmany, spacing, limit) where howmany is the number of\n * increments, spacing is the increment to be used between successive\n * axis labels, and limit is the rounded-up highest value of the\n * axis. Within float precision, howmany * spacing == highest will\n * hold.\n *\n * The axis is assumed to always start at zero.\n */\nGantt.compute_scale = function(highest) {\n if (highest <= 0) {\n return [2, 0.5, 1.0] // Special-case if there's no data.\n }\n var scale = 1.0\n while (highest < 1.0) {\n highest *= 10.0\n scale /= 10.0\n }\n while (highest >= 10.0) {\n highest /= 10.0\n scale *= 10.0\n }\n // Now 1 <= highest < 10\n for (var i = 0; i < Gantt.SCALES.length; i++) {\n if (highest <= Gantt.SCALES[i][2]) {\n return [Gantt.SCALES[i][0], Gantt.SCALES[i][1] * scale,\n Gantt.SCALES[i][2] * scale];\n }\n }\n // Avoid the need for \"assert False\". Not actually reachable.\n return [5, 2.0 * scale, 10.0 * scale];\n};\n\n\n/**\n * URL of a transparent 1x1 GIF.\n * @type {string}\n */\nGantt.prototype.PIX = 'stats/static/pix.gif';\n\n\n/**\n * CSS class name prefix.\n * @type {string}\n */\nGantt.prototype.PREFIX = 'ae-stats-gantt-';\n\n\n/**\n * Height of one bar.\n * @type {string}\n */\nGantt.prototype.HEIGHT = '1em';\n\n\n/**\n * Height of the extra bar.\n * @type {string}\n */\nGantt.prototype.EXTRA_HEIGHT = '0.5em';\n\n\n/**\n * Background color for the bar.\n * @type {string}\n */\nGantt.prototype.BG_COLOR = '#eeeeff';\n\n\n/**\n * Color of the main bar.\n * @type {string}\n */\nGantt.prototype.COLOR = '#7777ff';\n\n\n/**\n * Color of the extra bar.\n * @type {string}\n */\nGantt.prototype.EXTRA_COLOR = '#ff6666';\n\n\n/**\n * Font size of inline_label.\n * @type {string}\n */\nGantt.prototype.INLINE_FONT_SIZE = '80%';\n\n\n/**\n * Top of inline label text.\n * @type {string}\n */\nGantt.prototype.INLINE_TOP = '0.1em';\n\n\n/**\n * Color for ticks.\n * @type {string}\n */\nGantt.prototype.TICK_COLOR = 'grey';\n\n\n/**\n * @type {number}\n */\nGantt.prototype.highest_duration = 0;\n\n\n/*\n * Appends text to the output array.\n * @param {string} text The text to append to the output.\n */\nGantt.prototype.write = function(text) {\n this.output.push(text);\n};\n\n\n/*\n * Internal helper to draw a table row showing the scale.\n * @param {number} howmany\n * @param {number} spacing\n * @param {number} scale\n */\nGantt.prototype.draw_scale = function(howmany, spacing, scale) {\n this.write('' +\n '');\n this.write('
');\n for (var i = 0; i <= howmany; i++) {\n this.write('\"\"');\n this.write('');\n this.write(' ' + (i * spacing) + ''); // TODO: number format %4g\n }\n this.write('
\\n');\n};\n\n\n/**\n * Draw the bar chart as HTML.\n */\nGantt.prototype.draw = function() {\n this.output = [];\n var scale = Gantt.compute_scale(this.highest_duration);\n var howmany = scale[0];\n var spacing = scale[1];\n var limit = scale[2];\n scale = 100.0 / limit;\n this.write('\\n');\n this.draw_scale(howmany, spacing, scale);\n for (var i = 0; i < this.bars.length; i++) {\n var bar = this.bars[i];\n this.write('\\n\\n');\n\n }\n this.draw_scale(howmany, spacing, scale);\n this.write('
');\n if (bar.label.length > 0) {\n if (bar.link_target.length > 0) {\n this.write('');\n }\n this.write(bar.label);\n if (bar.link_target.length > 0) {\n this.write('');\n }\n }\n this.write('');\n this.write('
\\n');\n\n var html = this.output.join('');\n return html;\n};\n\n\n/**\n * Add a bar to the chart.\n * All arguments representing times or durations should be integers\n * or floats expressed in seconds. The scale drawn is always\n * expressed in seconds (with limited precision).\n * @param {string} label Valid HTML or HTML-escaped text for the left column.\n * @param {number} start Start time for the event.\n * @param {number} duration Duration for the event.\n * @param {number} extra_duration Duration for the second bar; use 0 to\n * suppress.\n * @param {string} inline_label Valid HTML or HTML-escaped text drawn after the\n * bars; use '' to suppress.\n * @param {string} link_target HTML-escaped link where clicking on any element\n * will take you; use '' for no linking.\n */\nGantt.prototype.add_bar = function(label, start, duration, extra_duration,\n inline_label, link_target) {\n this.highest_duration = Math.max(\n this.highest_duration, Math.max(start + duration,\n start + extra_duration));\n this.bars.push({label: label, start: start, duration: duration,\n extra_duration: extra_duration, inline_label: inline_label,\n link_target: link_target});\n};\n\n\ngoog.exportSymbol('Gantt', Gantt);\ngoog.exportProperty(Gantt.prototype, 'add_bar', Gantt.prototype.add_bar);\ngoog.exportProperty(Gantt.prototype, 'draw', Gantt.prototype.draw);\n") - -var minus_gif = []byte("GIF89a\f\x00\f\x00\xc4\x1f\x00\xcf\xd1\xd8\xf1\xf3\xf7\xc9\xcc\xd3\xef\xf1\xf5\xd9\xdb\xe1\xd7\xd9\xdfp\u007f\xba\xee\xf0\xf4\xd8\xda\xe0\xcc\xce\xd5\xfc\xfc\xfc\xfd\xfd\xfd\xf3\xf5\xf7\xe0\xe2\xe7\xf8\xf8\xf8\xe5\xe7\xeb\xd6\xd9\xde\xe8\xe9\xed\xe8\xe9\xee\xdc\xdf\xe5\xcb\xce\xd5\xf0\xf1\xf3\xf7\xf8\xfa\xd5\xd8\xdd\xe2\xe4\xe8\xec\xee\xf0\xe7\xe9훥\xcfUf\xad\x00\x00\xcc\xff\xff\xff\xff\xff\xff!\xf9\x04\x01\x00\x00\x1f\x00,\x00\x00\x00\x00\f\x00\f\x00\x00\x05D\xe0\xb7qdIn\"\xe7\xad\xec\xca\x19j+\x93r\xbbе\xa78\xa4\xd5\xfd\xc0_\x85\xc4\b\x063\xa4\xc3`\x19h\x1e2\x11\x92f:\x95h\x1e\x98\x06iB\xe8\"\x10\x05ȥ\xc0\x19\x01\xce\x14\x81:\xf1J\x99J\xa8\x10\x00;") - -var pix_gif = []byte("GIF89a\x01\x00\x01\x00\x80\x00\x00\xff\xff\xff\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;") - -var plus_gif = []byte("GIF89a\f\x00\f\x00\xc4\x1f\x00\xee\xf0\xf4p\u007f\xba\xd8\xda\xe0\xd7\xd9\xdf\xeb\xed\xf1\xe8\xe9\xee\xec\xee\xf0\xe2\xe4\xe8\xe0\xe2\xe7\xd9\xdb\xe1\xf3\xf5\xf7\xe8\xe9\xed\xf0\xf1\xf3\xf8\xf8\xf8\xcb\xce\xd5\xf7\xf8\xfa\xfd\xfd\xfd\xd6\xd9\xde\xe5\xe7\xeb\xdc\xdf\xe5\xcc\xce\xd5\xcf\xd1\xd8\xd5\xd8\xdd\xef\xf1\xf5\xf1\xf3\xf7\xe7\xe9\xed\xc9\xccӛ\xa5\xcf\x00\x00\xcc\xff\xff\xffUf\xad\xff\xff\xff!\xf9\x04\x01\x00\x00\x1f\x00,\x00\x00\x00\x00\f\x00\f\x00\x00\x05H\xe0\xb7ydIn\xa2\u05ed\xec\xea\x05*\xcbq-\xd9\xce,d\xcbt\a5\xa4\xc7l8d\x90\x14D\xa2\x81\x04\xb8`03\f\x80\xb0 e\xae\x85YFr@\x90&\t\x81`6\x88X\x06\x9eQši\xb7)\xaf\x94\xa9\x84\n\x01\x00;") diff --git a/_third_party/github.com/mjibson/appstats/types.go b/_third_party/github.com/mjibson/appstats/types.go deleted file mode 100644 index d39a82e0..00000000 --- a/_third_party/github.com/mjibson/appstats/types.go +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package appstats - -import ( - "fmt" - "net/http" - "sort" - "strconv" - "strings" - "sync" - "time" -) - -const ( - keyPrefix = "__appstats__:" - keyPart = keyPrefix + "%06d:part" - keyFull = keyPrefix + "%06d:full" - distance = 100 - modulus = 1000 -) - -type requestStats struct { - User string - Admin bool - Method string - Path, Query string - Status int - Cost int64 - Start time.Time - Duration time.Duration - RPCStats []rpcStat - - lock sync.Mutex - wg sync.WaitGroup -} - -type stats_part requestStats - -type stats_full struct { - Header http.Header - Stats *requestStats -} - -func (r *requestStats) PartKey() string { - t := roundTime(r.Start.Nanosecond()) - return fmt.Sprintf(keyPart, t) -} - -func (r *requestStats) FullKey() string { - t := roundTime(r.Start.Nanosecond()) - return fmt.Sprintf(keyFull, t) -} - -func roundTime(i int) int { - return (i / 1000 / distance) % modulus * distance -} - -type rpcStat struct { - Service, Method string - Start time.Time - Offset time.Duration - Duration time.Duration - StackData string - In, Out string - Cost int64 -} - -func (r rpcStat) Name() string { - return r.Service + "." + r.Method -} - -func (r rpcStat) Request() string { - return r.In -} - -func (r rpcStat) Response() string { - return r.Out -} - -func (r rpcStat) Stack() stack { - s := stack{} - - if r.StackData == "" { - return s - } - - lines := strings.Split(r.StackData, "\n") - for i := 0; i < len(lines); i++ { - idx := strings.LastIndex(lines[i], " ") - if idx == -1 { - break - } - - cidx := strings.LastIndex(lines[i], ":") - lineno, _ := strconv.Atoi(lines[i][cidx+1 : idx]) - f := &frame{ - Location: lines[i][:cidx], - Lineno: lineno, - } - - if i+1 < len(lines) && strings.HasPrefix(lines[i+1], "\t") { - f.Call = strings.TrimSpace(lines[i+1]) - i++ - } - - s = append(s, f) - } - - return s[2:] -} - -type stack []*frame - -type frame struct { - Location string - Call string - Lineno int -} - -type allrequestStats []*requestStats - -func (s allrequestStats) Len() int { return len(s) } -func (s allrequestStats) Less(i, j int) bool { return s[i].Start.Sub(s[j].Start) < 0 } -func (s allrequestStats) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -type statsByName []*statByName - -func (s statsByName) Len() int { return len(s) } -func (s statsByName) Less(i, j int) bool { return s[i].Count < s[j].Count } -func (s statsByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -type statByName struct { - Name string - Count int - Cost int64 - SubStats []*statByName - Requests int - RecentReqs []int - RequestStats *requestStats - Duration time.Duration -} - -type reverse struct{ sort.Interface } - -func (r reverse) Less(i, j int) bool { return r.Interface.Less(j, i) } - -type skey struct { - a, b string -} - -type cVal struct { - count int - cost int64 -} diff --git a/_third_party/github.com/mjibson/goon/README.md b/_third_party/github.com/mjibson/goon/README.md deleted file mode 100644 index f8f5fa6b..00000000 --- a/_third_party/github.com/mjibson/goon/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# goon - -An autocaching interface to the app engine datastore for Go. Designed to be similar to the python NDB package. - -Documentation: [http://godoc.org/github.com/mjibson/goon](http://godoc.org/github.com/mjibson/goon) diff --git a/_third_party/github.com/mjibson/goon/doc.go b/_third_party/github.com/mjibson/goon/doc.go deleted file mode 100644 index 81a25fd7..00000000 --- a/_third_party/github.com/mjibson/goon/doc.go +++ /dev/null @@ -1,138 +0,0 @@ -/* -Package goon provides an autocaching interface to the app engine datastore -similar to the python NDB package. - -Goon differs from the datastore package in various ways: it remembers the -appengine Context, which need only be specified once at creation time; kinds -need not be specified as they are computed, by default, from a type's name; -keys are inferred from specially-tagged fields on types, removing the need to -pass key objects around. - -In general, the difference is that Goon's API is identical to the datastore API, -it's just shorter. - -Keys in Goon are stored in the structs themselves. Below is an example struct -with a field to specify the id (see the Key Specifications section below for -full documentation). - type User struct { - Id string `datastore:"-" goon:"id"` - Name string - } - -Thus, to get a User with id 2: - userid := 2 - g := goon.NewGoon(r) - u := &User{Id: userid} - g.Get(u) - -Key Specifications - -For both the Key and KeyError functions, src must be a S or *S for some -struct type S. The key is extracted based on various fields of S. If a field -of type int64 or string has a struct tag named goon with value "id", it is -used as the key's id. If a field of type *datastore.Key has a struct tag -named goon with value "parent", it is used as the key's parent. If a field -of type string has a struct tag named goon with value "kind", it is used -as the key's kind. The "kind" field supports an optional second parameter -which is the default kind name. If no kind field exists, the struct's name -is used. These fields should all have their datastore field marked as "-". - -Example, with kind User: - type User struct { - Id string `datastore:"-" goon:"id"` - Read time.Time - } - -Example, with kind U if _kind is the empty string: - type User struct { - _kind string `goon:"kind,U"` - Id string `datastore:"-" goon:"id"` - Read time.Time - } - -To override kind of a single entity to UserKind: - u := User{_kind: "UserKind"} - -An example with both parent and kind: - type UserData struct { - Id string `datastore:"-" goon:"id"` - _kind string `goon:"kind,UD"` - Parent *datastore.Key `datastore:"-" goon:"parent"` - Data []byte - } - -Features - -Datastore interaction with: Get, GetMulti, Put, PutMulti, Delete, DeleteMulti, Queries. - -All key-based operations backed by memory and memcache. - -Per-request, in-memory cache: fetch the same key twice, the second request is served from local memory. - -Intelligent multi support: running GetMulti correctly fetches from memory, then memcache, then the datastore; each tier only sends keys off to the next one if they were missing. - -Memcache control variance: long memcache requests are cancelled. - -Transactions use a separate context, but locally cache any results on success. - -Automatic kind naming: struct names are inferred by reflection, removing the need to manually specify key kinds. - -Simpler API than appengine/datastore. - -API comparison between goon and datastore - -put with incomplete key - -datastore: - - type Group struct { - Name string - } - c := appengine.NewContext(r) - g := &Group{Name: "name"} - k := datastore.NewIncompleteKey(c, "Group", nil) - err := datastore.Put(c, k, g) - -goon: - - type Group struct { - Id int64 `datastore:"-" goon:"id"` - Name string - } - n := goon.NewGoon(r) - g := &Group{Name: "name"} - err := n.Put(g) - -get with known key - -datastore: - - type Group struct { - Name string - } - c := appengine.NewContext(r) - g := &Group{} - k := datastore.NewKey(c, "Group", "", 1, nil) - err := datastore.Get(c, k, g) - -goon: - - type Group struct { - Id int64 `datastore:"-" goon:"id"` - Name string - } - n := goon.NewGoon(r) - g := &Group{Id: 1} - err := n.Get(g) - -Memcache Control Variance - -Memcache is generally fast. When it is slow, goon will timeout the memcache -requests and proceed to use the datastore directly. The memcache put and -get timeout variables determine how long to wait for various kinds of -requests. The default settings were determined experimentally and should -provide reasonable defaults for most applications. - -See: http://talks.golang.org/2013/highperf.slide#23 -*/ -package goon diff --git a/_third_party/github.com/mjibson/goon/entity.go b/_third_party/github.com/mjibson/goon/entity.go deleted file mode 100644 index a9c46cd2..00000000 --- a/_third_party/github.com/mjibson/goon/entity.go +++ /dev/null @@ -1,850 +0,0 @@ -/* - * Copyright (c) 2012 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package goon - -import ( - "bytes" - "container/list" - "encoding/gob" - "fmt" - "reflect" - "strings" - "sync" - "time" - - "appengine" - "appengine/datastore" -) - -type fieldInfo struct { - sliceIndex []int - fieldIndex []int -} - -type fieldMetadata struct { - name string - index int -} - -type structMetaData struct { - metaDatas []string - totalLength int -} - -// KindNameResolver takes an Entity and returns what the Kind should be for -// Datastore. -type KindNameResolver func(src interface{}) string - -// A special bootstrapping struct that contains all the datastore-supported types -// that need to be registered with gob. Using this to initialize every encoder/decoder, -// we get reusable encoders/decoders. Additionally, this cuts down on the serialized bytes length. -// https://developers.google.com/appengine/docs/go/datastore/reference -type seBootstrap struct { - v01 *datastore.Key - v02 time.Time - v03 appengine.BlobKey - v04 []*datastore.Key - v05 []time.Time - v06 []int - v07 []int8 - v08 []int16 - v09 []int32 - v10 []int64 - v11 []float32 - v12 []float64 - v13 []bool - v14 []string - v15 [][]byte -} - -type serializationEncoder struct { - buf *bytes.Buffer - enc *gob.Encoder -} - -type serializationDecoder struct { - sr *serializationReader - dec *gob.Decoder -} - -type serializationReader struct { - r *bytes.Reader -} - -func (sr *serializationReader) Read(p []byte) (n int, err error) { - return sr.r.Read(p) -} - -func (sr *serializationReader) ReadByte() (c byte, err error) { - return sr.r.ReadByte() -} - -const ( - serializationStateEmpty = 0x00 - serializationStateNormal = 0x01 -) - -var ( - timeType = reflect.TypeOf(time.Time{}) - fieldInfos = make(map[reflect.Type]map[string]*fieldInfo) - fieldMetadatas = make(map[reflect.Type][]fieldMetadata) - fieldIMLock sync.RWMutex - serializationEncoders = list.New() - serializationEncodersLock sync.Mutex - serializationDecoders = list.New() - serializationDecodersLock sync.Mutex - seBoot = seBootstrap{v01: &datastore.Key{}} - seBootBytes []byte - seBootBytesLock sync.RWMutex -) - -func init() { - // The serialization type cache bootstrapping optimization suffers from a race condition. - // Because encoding/gob uses a partial global type cache of its own, it is possible that - // some other piece of code uses encoding/gob before we do our bootstrapping. To be exact, - // inconsistent use of encoding/gob with custom types before us is what causes problems. - // Using encoding/gob after us isn't a problem. Neither is using it before us, if the usage - // always happens before us. The order of usage before us only matters if the custom types - // match a type that we have in our bootstrapping. To mostly solve this race condition, - // we bootstrap a single decoder in this init() function. However a rare edge case remains - // where the race condition can still cause trouble for us. The requirements for it are: - // 1) Some other init() function has to use encoding/gob - // 2) Be in a package that does not import goon, nor import anything that imports goon - // 3) Executes before goon's init() - // 4) That init()'s encoding/gob usage has to either: - // a) Happen inconsistently, i.e. not always happen, e.g.: - // * The usage is under a conditional, e.g. only executes when the clock is 09:00 - // * The order in which the package is presented to the compiler gets moved after goon - // * The usage is removed during a code update - // b) Register a same type as us, but in an inconsistent order between multiple executions - freeSerializationDecoder(getSerializationDecoder([]byte{})) -} - -// getFieldInfoAndMetadata returns metadata about a struct. Its main purpose is to cut down -// reflection usage on types, which is slow. Instead, metadata is generated once per type, and cached. -func getFieldInfoAndMetadata(t reflect.Type) (map[string]*fieldInfo, []fieldMetadata) { - fieldIMLock.RLock() - // Attempt to get the data for this type under an efficient read lock - fieldMap, ok := fieldInfos[t] - fms := fieldMetadatas[t] - fieldIMLock.RUnlock() - - if !ok { - fieldIMLock.Lock() - // Check again, the data could have appeared when we didn't have a lock - fieldMap, ok = fieldInfos[t] - if !ok { - // We are going to generate the data for this type - fieldMap = make(map[string]*fieldInfo, 16) - generateFieldInfoAndMetadata(t, "", make([]int, 0, 16), []int{}, fieldMap) - fieldInfos[t] = fieldMap - } - fms = fieldMetadatas[t] - fieldIMLock.Unlock() - } - - return fieldMap, fms -} - -// getFieldMetadata returns already generated, cached, metadata about a struct. -func getFieldMetadata(t reflect.Type) []fieldMetadata { - fieldIMLock.RLock() - defer fieldIMLock.RUnlock() - return fieldMetadatas[t] -} - -// generateFieldInfoAndMetadata generates metadata about the fields of a struct. -// -// NB! generateFieldInfoAndMetadata should only be called under a fieldIMLock write-lock -func generateFieldInfoAndMetadata(t reflect.Type, namePrefix string, indexPrefix, sliceIndex []int, fieldMap map[string]*fieldInfo) { - var fieldName string - fms, havefms := fieldMetadatas[t] - - numFields := t.NumField() - for i := 0; i < numFields; i++ { - tf := t.Field(i) - if tf.PkgPath != "" { - continue - } - - tag := tf.Tag.Get("datastore") - if len(tag) > 0 { - if commaPos := strings.Index(tag, ","); commaPos == -1 { - fieldName = tag - } else if commaPos == 0 { - fieldName = tf.Name - } else { - fieldName = tag[:commaPos] - } - if fieldName == "-" { - continue - } - } else { - fieldName = tf.Name - } - if !havefms { - fms = append(fms, fieldMetadata{name: fieldName, index: i}) - } - if namePrefix != "" { - fieldName = namePrefix + fieldName - } - - if tf.Type.Kind() == reflect.Slice { - elemType := tf.Type.Elem() - if elemType.Kind() == reflect.Struct && elemType != timeType { - generateFieldInfoAndMetadata(elemType, fieldName+".", make([]int, 0, 8), append(indexPrefix, i), fieldMap) - continue - } - } else if tf.Type.Kind() == reflect.Struct && tf.Type != timeType { - generateFieldInfoAndMetadata(tf.Type, fieldName+".", append(indexPrefix, i), sliceIndex, fieldMap) - continue - } - - finalIndex := append(indexPrefix, i) - fi := &fieldInfo{sliceIndex: make([]int, len(sliceIndex)), fieldIndex: make([]int, len(finalIndex))} - copy(fi.sliceIndex, sliceIndex) - copy(fi.fieldIndex, finalIndex) - fieldMap[fieldName] = fi - } - - if !havefms { - fieldMetadatas[t] = fms - } -} - -// serializeStructMetaData is a fast encoder of struct metadata, which doesn't depend on gob. -// Struct metadata is just a slice of strings, which this function converts into a series of bytes. -func serializeStructMetaData(buf []byte, smd *structMetaData) { - pos := 0 - for _, metaData := range smd.metaDatas { - copy(buf[pos:], metaData) - pos += len(metaData) - buf[pos] = '+' - pos++ - } - if pos > 0 { - buf[pos-1] = '|' - } -} - -// deserializeStructMetaData is a fast decoder of struct metadata, which doesn't depend on gob. -// It takes a slice of bytes buf, generated by serializeStructMetaData, and converts it into a slice of strings. -func deserializeStructMetaData(buf []byte) *structMetaData { - smd := &structMetaData{metaDatas: make([]string, 0, 16)} - pos, bufLen := 0, len(buf) - for i := 0; i < bufLen; i++ { - if buf[i] == '+' || buf[i] == '|' { - smd.metaDatas = append(smd.metaDatas, string(buf[pos:i])) - smd.totalLength += i - pos - pos = i + 1 - if buf[i] == '|' { - break - } - } - } - return smd -} - -// bootstrapSerializationEncoder runs the encoder through a bootstrapping process, -// which registers all datastore-supported types. This is an optimization that must -// be done only once per a reusable encoder. -// -// NB! updateSEBootBytes should only be set true if called under seBootBytesLock write-lock -func bootstrapSerializationEncoder(se *serializationEncoder, updateSEBootBytes bool) { - se.enc.Encode(seBoot.v01) - se.enc.Encode(seBoot.v02) - se.enc.Encode(seBoot.v03) - se.enc.Encode(seBoot.v04) - se.enc.Encode(seBoot.v05) - se.enc.Encode(seBoot.v06) - se.enc.Encode(seBoot.v07) - se.enc.Encode(seBoot.v08) - se.enc.Encode(seBoot.v09) - se.enc.Encode(seBoot.v10) - se.enc.Encode(seBoot.v11) - se.enc.Encode(seBoot.v12) - se.enc.Encode(seBoot.v13) - se.enc.Encode(seBoot.v14) - se.enc.Encode(seBoot.v15) - - if updateSEBootBytes { - seBootBytes = make([]byte, se.buf.Len()) - copy(seBootBytes, se.buf.Bytes()) - } - - se.buf.Reset() -} - -// bootstrapSerializationDecoder runs the decoder through a bootstrapping process, -// which registers all datastore-supported types. This is an optimization that must -// be done only once per a reusable decoder. -func bootstrapSerializationDecoder(sd *serializationDecoder) { - seBootBytesLock.RLock() - ok := len(seBootBytes) > 0 - seBootBytesLock.RUnlock() - if !ok { - seBootBytesLock.Lock() - ok = len(seBootBytes) > 0 - if !ok { - buf := bytes.NewBuffer(make([]byte, 0, 512)) - enc := gob.NewEncoder(buf) - se := &serializationEncoder{buf: buf, enc: enc} - bootstrapSerializationEncoder(se, true) - } - seBootBytesLock.Unlock() - } - - sd.sr.r = bytes.NewReader(seBootBytes) - for i := 0; i < 15; i++ { - sd.dec.Decode(nil) - } -} - -// getSerializationEncoder returns an efficient reusable encoder from a pool. -// Every encoder acquired with this function must be later freed via freeSerializationEncoder. -func getSerializationEncoder() *serializationEncoder { - serializationEncodersLock.Lock() - // Use an existing one if possible - if serializationEncoders.Len() > 0 { - defer serializationEncodersLock.Unlock() - return serializationEncoders.Remove(serializationEncoders.Front()).(*serializationEncoder) - } - serializationEncodersLock.Unlock() - // Otherwise allocate a new one - buf := bytes.NewBuffer(make([]byte, 0, 16384)) // 16 KiB initial capacity - enc := gob.NewEncoder(buf) - se := &serializationEncoder{buf: buf, enc: enc} - bootstrapSerializationEncoder(se, false) - return se -} - -// freeSerializationEncoder returns the encoder to the pool, allowing for reuse. -func freeSerializationEncoder(se *serializationEncoder) { - se.buf.Reset() - serializationEncodersLock.Lock() - serializationEncoders.PushBack(se) - // TODO: Perhaps some occasional clean-up is in order? - // Running 50 goroutines concurrently can allocate a bunch of these - // but they may not be needed again for quite some time - serializationEncodersLock.Unlock() -} - -// getSerializationDecoder returns an efficient reusable decoder from a pool. -// Every decoder acquired with this function must be later freed via freeSerializationDecoder. -func getSerializationDecoder(data []byte) *serializationDecoder { - serializationDecodersLock.Lock() - // Use an existing one if possible - if serializationDecoders.Len() > 0 { - sd := serializationDecoders.Remove(serializationDecoders.Front()).(*serializationDecoder) - serializationDecodersLock.Unlock() - sd.sr.r = bytes.NewReader(data) - return sd - } - serializationDecodersLock.Unlock() - // Otherwise allocate a new one - sr := &serializationReader{} - dec := gob.NewDecoder(sr) - sd := &serializationDecoder{sr: sr, dec: dec} - bootstrapSerializationDecoder(sd) - sd.sr.r = bytes.NewReader(data) - return sd -} - -// freeSerializationDecoder returns the decoder to the pool, allowing for reuse. -func freeSerializationDecoder(sd *serializationDecoder) { - sd.sr.r = nil // Avoid memory leaks - serializationDecodersLock.Lock() - serializationDecoders.PushBack(sd) - // TODO: Perhaps some occasional clean-up is in order? - // Running 50 goroutines concurrently can allocate a bunch of these - // but they may not be needed again for quite some time - serializationDecodersLock.Unlock() -} - -// serializeStruct takes a struct and serializes it to portable bytes. -func serializeStruct(src interface{}) ([]byte, error) { - if src == nil { - return []byte{serializationStateEmpty}, nil - } - - v := reflect.Indirect(reflect.ValueOf(src)) - t := v.Type() - k := t.Kind() - - if k != reflect.Struct { - return nil, fmt.Errorf("goon: Expected struct, got instead: %v", k) - } - - se := getSerializationEncoder() - defer freeSerializationEncoder(se) - smd := &structMetaData{metaDatas: make([]string, 0, 16)} - _, fms := getFieldInfoAndMetadata(t) // Use this function to force generation if needed - - if err := serializeStructInternal(se.enc, smd, fms, "", v); err != nil { - return nil, err - } - - bufSize := se.buf.Len() - // final size = header + all metadatas + separators for metadata + data - finalBufSize := 1 + smd.totalLength + len(smd.metaDatas) + bufSize - finalBuf := make([]byte, finalBufSize) - finalBuf[0] = byte(serializationStateNormal) // Set the header - serializeStructMetaData(finalBuf[1:], smd) // Serialize the metadata - copy(finalBuf[finalBufSize-bufSize:], se.buf.Bytes()) // Copy the actual data - - return finalBuf, nil -} - -// serializeStructInternal is a helper function for serializeStruct, mainly for easier recursion. -// It takes a bunch of metadata that describes a struct, and encodes field values with gob. -func serializeStructInternal(enc *gob.Encoder, smd *structMetaData, fms []fieldMetadata, namePrefix string, v reflect.Value) error { - var fieldName string - var metaData string - var elemType reflect.Type - - for _, fm := range fms { - vf := v.Field(fm.index) - - if namePrefix != "" { - fieldName = namePrefix + fm.name - } else { - fieldName = fm.name - } - - if vf.Kind() == reflect.Slice { - elemType = vf.Type().Elem() - if elemType != timeType { - // Unroll slices of structs - if elemType.Kind() == reflect.Struct { - if vfLen := vf.Len(); vfLen > 0 { - subFms := getFieldMetadata(elemType) - subPrefix := fieldName + "." - for j := 0; j < vfLen; j++ { - vi := vf.Index(j) - if err := serializeStructInternal(enc, smd, subFms, subPrefix, vi); err != nil { - return err - } - } - } - continue - } else if elemType.Kind() == reflect.Ptr { - // For a slice of pointers we need to check if any index is nil, - // because Gob unfortunately fails at encoding nil values - anyNil := false - vfLen := vf.Len() - for j := 0; j < vfLen; j++ { - vi := vf.Index(j) - if vi.IsNil() { - anyNil = true - break - } - } - if anyNil { - for j := 0; j < vfLen; j++ { - vi := vf.Index(j) - encodeValue := true - if vi.IsNil() { - // Gob unfortunately fails at encoding nil values - metaData = "!" + fieldName - encodeValue = false - } else { - metaData = fieldName - } - if err := serializeStructInternalEncode(enc, smd, fieldName, metaData, encodeValue, vi); err != nil { - return err - } - } - continue - } - } else if elemType.Kind().String() != elemType.Name() { - // For slices of custom non-struct types, encode them as slices of the underlying type. - // This is required to be able to re-use a global gob encoding machine, - // as custom types require the type info to be declared by gob for every encoded struct! - // NB! We don't currently update the elemType variable as an optimization! - vfLen := vf.Len() - switch elemType.Kind() { - case reflect.String: - copy := make([]string, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = vf.Index(i).String() - } - vf = reflect.ValueOf(copy) - case reflect.Bool: - copy := make([]bool, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = vf.Index(i).Bool() - } - vf = reflect.ValueOf(copy) - case reflect.Int: - copy := make([]int, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = int(vf.Index(i).Int()) - } - vf = reflect.ValueOf(copy) - case reflect.Int8: - copy := make([]int8, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = int8(vf.Index(i).Int()) - } - vf = reflect.ValueOf(copy) - case reflect.Int16: - copy := make([]int16, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = int16(vf.Index(i).Int()) - } - vf = reflect.ValueOf(copy) - case reflect.Int32: - copy := make([]int32, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = int32(vf.Index(i).Int()) - } - vf = reflect.ValueOf(copy) - case reflect.Int64: - copy := make([]int64, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = vf.Index(i).Int() - } - vf = reflect.ValueOf(copy) - case reflect.Float32: - copy := make([]float32, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = float32(vf.Index(i).Float()) - } - vf = reflect.ValueOf(copy) - case reflect.Float64: - copy := make([]float64, vfLen, vfLen) - for i := 0; i < vfLen; i++ { - copy[i] = vf.Index(i).Float() - } - vf = reflect.ValueOf(copy) - } - } - } - } else if vf.Kind() == reflect.Struct { - if vfType := vf.Type(); vfType != timeType { - if err := serializeStructInternal(enc, smd, getFieldMetadata(vfType), fieldName+".", vf); err != nil { - return err - } - continue - } - } - - encodeValue := true - if vf.Kind() == reflect.Slice && elemType.Kind() != reflect.Uint8 { - // NB! []byte is a special case and not a slice - // When decoding, if the target is a slice but metadata doesn't have the $ sign, - // then we can properly create a single value slice instead of panicing - metaData = "$" + fieldName - } else if vf.Kind() == reflect.Ptr && vf.IsNil() { - // Gob unfortunately fails at encoding nil values - metaData = "!" + fieldName - encodeValue = false - } else { - metaData = fieldName - } - - if err := serializeStructInternalEncode(enc, smd, fieldName, metaData, encodeValue, vf); err != nil { - return err - } - } - return nil -} - -// serializeStructInternalEncode takes struct field metadata and encodes the value using gob. -func serializeStructInternalEncode(enc *gob.Encoder, smd *structMetaData, fieldName, metaData string, encodeValue bool, v reflect.Value) error { - smd.metaDatas = append(smd.metaDatas, metaData) - smd.totalLength += len(metaData) - - if encodeValue { - if err := enc.EncodeValue(v); err != nil { - return fmt.Errorf("goon: Failed to encode field %v value %v - %v", fieldName, v.Interface(), err) - } - } - return nil -} - -// deserializeStruct takes portable bytes b, generated by serializeStruct, and assigns correct values to struct dst. -func deserializeStruct(dst interface{}, b []byte) error { - if len(b) == 0 { - return fmt.Errorf("goon: Expected some data to deserialize, got none.") - } - - v := reflect.Indirect(reflect.ValueOf(dst)) - t := v.Type() - k := t.Kind() - - if k != reflect.Struct { - return fmt.Errorf("goon: Expected struct, got instead: %v", k) - } - - if header := b[0]; header == serializationStateEmpty { - return datastore.ErrNoSuchEntity - } else if header != serializationStateNormal { - return fmt.Errorf("goon: Unrecognized cache header: %v", header) - } - - smd := deserializeStructMetaData(b[1:]) - dataPos := 1 + smd.totalLength + len(smd.metaDatas) - sd := getSerializationDecoder(b[dataPos:]) - defer freeSerializationDecoder(sd) - structHistory := make(map[string]map[string]bool, 8) - fieldMap, _ := getFieldInfoAndMetadata(t) - - for _, metaData := range smd.metaDatas { - fieldName, slice, zeroValue := metaData, false, false - if metaData[0] == '$' { - fieldName, slice = metaData[1:], true - } else if metaData[0] == '!' { - fieldName, zeroValue = metaData[1:], true - } - nameParts := strings.Split(fieldName, ".") - - fi, ok := fieldMap[fieldName] - if !ok { - return fmt.Errorf("goon: Could not find field %v", fieldName) - } - - if err := deserializeStructInternal(sd.dec, fi, fieldName, nameParts, slice, zeroValue, structHistory, v, t); err != nil { - return err - } - } - - return nil -} - -// deserializeStructInternal is a helper function for deserializeStruct. -// It takes a gob decoder and struct field metadata, and then assigns the correct value to the specified struct field. -func deserializeStructInternal(dec *gob.Decoder, fi *fieldInfo, fieldName string, nameParts []string, slice, zeroValue bool, structHistory map[string]map[string]bool, v reflect.Value, t reflect.Type) error { - if len(fi.sliceIndex) > 0 { - v = v.FieldByIndex(fi.sliceIndex) - t = v.Type() - - var sv reflect.Value - createNew := false - nameIdx := len(fi.sliceIndex) - absName, childName := strings.Join(nameParts[:nameIdx], "."), strings.Join(nameParts[nameIdx:], ".") - sh, ok := structHistory[absName] - if !ok || sh[childName] { - sh = make(map[string]bool, 8) - structHistory[absName] = sh - createNew = true - } else if len(sh) == 0 { - createNew = true - } - - if createNew { - structType := t.Elem() - sv = reflect.New(structType).Elem() - v.Set(reflect.Append(v, sv)) - } - - sv = v.Index(v.Len() - 1) - sh[childName] = true - - v = sv - t = v.Type() - } - - vf := v.FieldByIndex(fi.fieldIndex) - - if vf.Kind() == reflect.Slice && !slice { - elemType := vf.Type().Elem() - if elemType.Kind() == reflect.Uint8 { - if !zeroValue { - if err := dec.DecodeValue(vf); err != nil { - return fmt.Errorf("goon: Failed to decode field %v - %v", fieldName, err) - } - } - } else { - ev := reflect.New(elemType).Elem() - if !zeroValue { - if err := dec.DecodeValue(ev); err != nil { - return fmt.Errorf("goon: Failed to decode field %v - %v", fieldName, err) - } - } - vf.Set(reflect.Append(vf, ev)) - } - } else if !zeroValue { - if err := dec.DecodeValue(vf); err != nil { - return fmt.Errorf("goon: Failed to decode field %v - %v", fieldName, err) - } - } - - return nil -} - -// getStructKey returns the key of the struct based in its reflected or -// specified kind and id. The second return parameter is true if src has a -// string id. -func (g *Goon) getStructKey(src interface{}) (key *datastore.Key, hasStringId bool, err error) { - v := reflect.Indirect(reflect.ValueOf(src)) - t := v.Type() - k := t.Kind() - - if k != reflect.Struct { - err = fmt.Errorf("goon: Expected struct, got instead: %v", k) - return - } - - var parent *datastore.Key - var stringID string - var intID int64 - var kind string - - for i := 0; i < v.NumField(); i++ { - tf := t.Field(i) - vf := v.Field(i) - - tag := tf.Tag.Get("goon") - tagValues := strings.Split(tag, ",") - if len(tagValues) > 0 { - tagValue := tagValues[0] - if tagValue == "id" { - switch vf.Kind() { - case reflect.Int64: - if intID != 0 || stringID != "" { - err = fmt.Errorf("goon: Only one field may be marked id") - return - } - intID = vf.Int() - case reflect.String: - if intID != 0 || stringID != "" { - err = fmt.Errorf("goon: Only one field may be marked id") - return - } - stringID = vf.String() - hasStringId = true - default: - err = fmt.Errorf("goon: ID field must be int64 or string in %v", t.Name()) - return - } - } else if tagValue == "kind" { - if vf.Kind() == reflect.String { - if kind != "" { - err = fmt.Errorf("goon: Only one field may be marked kind") - return - } - kind = vf.String() - if kind == "" && len(tagValues) > 1 && tagValues[1] != "" { - kind = tagValues[1] - } - } - } else if tagValue == "parent" { - dskeyType := reflect.TypeOf(&datastore.Key{}) - if vf.Type().ConvertibleTo(dskeyType) { - if parent != nil { - err = fmt.Errorf("goon: Only one field may be marked parent") - return - } - parent = vf.Convert(dskeyType).Interface().(*datastore.Key) - } - } - } - } - - // if kind has not been manually set, fetch it from src's type - if kind == "" { - kind = g.KindNameResolver(src) - } - key = datastore.NewKey(g.Context, kind, stringID, intID, parent) - return -} - -// DefaultKindName is the default implementation to determine the Kind -// an Entity has. Returns the basic Type of the src (no package name included). -func DefaultKindName(src interface{}) string { - v := reflect.ValueOf(src) - v = reflect.Indirect(v) - t := v.Type() - return t.Name() -} - -func (g *Goon) setStructKey(src interface{}, key *datastore.Key) error { - v := reflect.ValueOf(src) - t := v.Type() - k := t.Kind() - - if k != reflect.Ptr { - return fmt.Errorf("goon: Expected pointer to struct, got instead: %v", k) - } - - v = reflect.Indirect(v) - t = v.Type() - k = t.Kind() - - if k != reflect.Struct { - return fmt.Errorf(fmt.Sprintf("goon: Expected struct, got instead: %v", k)) - } - - idSet := false - kindSet := false - parentSet := false - for i := 0; i < v.NumField(); i++ { - tf := t.Field(i) - vf := v.Field(i) - - if !vf.CanSet() { - continue - } - - tag := tf.Tag.Get("goon") - tagValues := strings.Split(tag, ",") - if len(tagValues) > 0 { - tagValue := tagValues[0] - if tagValue == "id" { - if idSet { - return fmt.Errorf("goon: Only one field may be marked id") - } - - switch vf.Kind() { - case reflect.Int64: - vf.SetInt(key.IntID()) - idSet = true - case reflect.String: - vf.SetString(key.StringID()) - idSet = true - } - } else if tagValue == "kind" { - if kindSet { - return fmt.Errorf("goon: Only one field may be marked kind") - } - if vf.Kind() == reflect.String { - if (len(tagValues) <= 1 || key.Kind() != tagValues[1]) && g.KindNameResolver(src) != key.Kind() { - vf.Set(reflect.ValueOf(key.Kind())) - } - kindSet = true - } - } else if tagValue == "parent" { - if parentSet { - return fmt.Errorf("goon: Only one field may be marked parent") - } - dskeyType := reflect.TypeOf(&datastore.Key{}) - vfType := vf.Type() - if vfType.ConvertibleTo(dskeyType) { - vf.Set(reflect.ValueOf(key.Parent()).Convert(vfType)) - parentSet = true - } - } - } - } - - if !idSet { - return fmt.Errorf("goon: Could not set id field") - } - - return nil -} diff --git a/_third_party/github.com/mjibson/goon/goon.go b/_third_party/github.com/mjibson/goon/goon.go deleted file mode 100644 index 087c6e84..00000000 --- a/_third_party/github.com/mjibson/goon/goon.go +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Copyright (c) 2012 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package goon - -import ( - "bytes" - "fmt" - "net/http" - "path/filepath" - "reflect" - "runtime" - "sync" - "time" - - "appengine" - "appengine/datastore" - "appengine/memcache" -) - -var ( - // LogErrors issues appengine.Context.Errorf on any error. - LogErrors = true - // LogTimeoutErrors issues appengine.Context.Warningf on memcache timeout errors. - LogTimeoutErrors = false - - // MemcachePutTimeoutThreshold is the number of bytes at which the memcache - // timeout uses the large setting. - MemcachePutTimeoutThreshold = 1024 * 50 - // MemcachePutTimeoutSmall is the amount of time to wait during memcache - // Put operations before aborting them and using the datastore. - MemcachePutTimeoutSmall = time.Millisecond * 5 - // MemcachePutTimeoutLarge is the amount of time to wait for large memcache - // Put requests. - MemcachePutTimeoutLarge = time.Millisecond * 15 - // MemcacheGetTimeout is the amount of time to wait for all memcache Get - // requests. - MemcacheGetTimeout = time.Millisecond * 10 -) - -// Goon holds the app engine context and the request memory cache. -type Goon struct { - Context appengine.Context - cache map[string]interface{} - cacheLock sync.RWMutex // protect the cache from concurrent goroutines to speed up RPC access - inTransaction bool - toSet map[string]interface{} - toDelete map[string]bool - toDeleteMC map[string]bool - // KindNameResolver is used to determine what Kind to give an Entity. - // Defaults to DefaultKindName - KindNameResolver KindNameResolver -} - -func memkey(k *datastore.Key) string { - // Versioning, so that incompatible changes to the cache system won't cause problems - return "g2:" + k.Encode() -} - -// NewGoon creates a new Goon object from the given request. -func NewGoon(r *http.Request) *Goon { - return FromContext(appengine.NewContext(r)) -} - -// FromContext creates a new Goon object from the given appengine Context. -// Useful with profiling packages like appstats. -func FromContext(c appengine.Context) *Goon { - return &Goon{ - Context: c, - cache: make(map[string]interface{}), - KindNameResolver: DefaultKindName, - } -} - -func (g *Goon) error(err error) { - if !LogErrors { - return - } - _, filename, line, ok := runtime.Caller(1) - if ok { - g.Context.Errorf("goon - %s:%d - %v", filepath.Base(filename), line, err) - } else { - g.Context.Errorf("goon - %v", err) - } -} - -func (g *Goon) timeoutError(err error) { - if LogTimeoutErrors { - g.Context.Warningf("goon memcache timeout: %v", err) - } -} - -func (g *Goon) extractKeys(src interface{}, putRequest bool) ([]*datastore.Key, error) { - v := reflect.Indirect(reflect.ValueOf(src)) - if v.Kind() != reflect.Slice { - return nil, fmt.Errorf("goon: value must be a slice or pointer-to-slice") - } - l := v.Len() - - keys := make([]*datastore.Key, l) - for i := 0; i < l; i++ { - vi := v.Index(i) - key, hasStringId, err := g.getStructKey(vi.Interface()) - if err != nil { - return nil, err - } - if !putRequest && key.Incomplete() { - return nil, fmt.Errorf("goon: cannot find a key for struct - %v", vi.Interface()) - } else if putRequest && key.Incomplete() && hasStringId { - return nil, fmt.Errorf("goon: empty string id on put") - } - keys[i] = key - } - return keys, nil -} - -// Key is the same as KeyError, except nil is returned on error or if the key -// is incomplete. -func (g *Goon) Key(src interface{}) *datastore.Key { - if k, err := g.KeyError(src); err == nil { - return k - } - return nil -} - -// Kind returns src's datastore Kind or "" on error. -func (g *Goon) Kind(src interface{}) string { - if k, err := g.KeyError(src); err == nil { - return k.Kind() - } - return "" -} - -// KeyError returns the key of src based on its properties. -func (g *Goon) KeyError(src interface{}) (*datastore.Key, error) { - key, _, err := g.getStructKey(src) - return key, err -} - -// RunInTransaction runs f in a transaction. It calls f with a transaction -// context tg that f should use for all App Engine operations. Neither cache nor -// memcache are used or set during a transaction. -// -// Otherwise similar to appengine/datastore.RunInTransaction: -// https://developers.google.com/appengine/docs/go/datastore/reference#RunInTransaction -func (g *Goon) RunInTransaction(f func(tg *Goon) error, opts *datastore.TransactionOptions) error { - var ng *Goon - err := datastore.RunInTransaction(g.Context, func(tc appengine.Context) error { - ng = &Goon{ - Context: tc, - inTransaction: true, - toSet: make(map[string]interface{}), - toDelete: make(map[string]bool), - toDeleteMC: make(map[string]bool), - KindNameResolver: g.KindNameResolver, - } - return f(ng) - }, opts) - - if err == nil { - if len(ng.toDeleteMC) > 0 { - var memkeys []string - for k := range ng.toDeleteMC { - memkeys = append(memkeys, k) - } - memcache.DeleteMulti(g.Context, memkeys) - } - - g.cacheLock.Lock() - defer g.cacheLock.Unlock() - for k, v := range ng.toSet { - g.cache[k] = v - } - - for k := range ng.toDelete { - delete(g.cache, k) - } - } else { - g.error(err) - } - - return err -} - -// Put saves the entity src into the datastore based on src's key k. If k -// is an incomplete key, the returned key will be a unique key generated by -// the datastore. -func (g *Goon) Put(src interface{}) (*datastore.Key, error) { - ks, err := g.PutMulti([]interface{}{src}) - if err != nil { - if me, ok := err.(appengine.MultiError); ok { - return nil, me[0] - } - return nil, err - } - return ks[0], nil -} - -const putMultiLimit = 500 - -// PutMulti is a batch version of Put. -// -// src must be a *[]S, *[]*S, *[]I, []S, []*S, or []I, for some struct type S, -// or some interface type I. If *[]I or []I, each element must be a struct pointer. -func (g *Goon) PutMulti(src interface{}) ([]*datastore.Key, error) { - keys, err := g.extractKeys(src, true) // allow incomplete keys on a Put request - if err != nil { - return nil, err - } - - var memkeys []string - for _, key := range keys { - if !key.Incomplete() { - memkeys = append(memkeys, memkey(key)) - } - } - - // Memcache needs to be updated after the datastore to prevent a common race condition, - // where a concurrent request will fetch the not-yet-updated data from the datastore - // and populate memcache with it. - if g.inTransaction { - for _, mk := range memkeys { - g.toDeleteMC[mk] = true - } - } else { - defer memcache.DeleteMulti(g.Context, memkeys) - } - - v := reflect.Indirect(reflect.ValueOf(src)) - multiErr, any := make(appengine.MultiError, len(keys)), false - goroutines := (len(keys)-1)/putMultiLimit + 1 - var wg sync.WaitGroup - wg.Add(goroutines) - for i := 0; i < goroutines; i++ { - go func(i int) { - defer wg.Done() - lo := i * putMultiLimit - hi := (i + 1) * putMultiLimit - if hi > len(keys) { - hi = len(keys) - } - rkeys, pmerr := datastore.PutMulti(g.Context, keys[lo:hi], v.Slice(lo, hi).Interface()) - if pmerr != nil { - any = true // this flag tells PutMulti to return multiErr later - merr, ok := pmerr.(appengine.MultiError) - if !ok { - g.error(pmerr) - for j := lo; j < hi; j++ { - multiErr[j] = pmerr - } - return - } - copy(multiErr[lo:hi], merr) - } - - for i, key := range keys[lo:hi] { - if multiErr[lo+i] != nil { - continue // there was an error writing this value, go to next - } - vi := v.Index(lo + i).Interface() - if key.Incomplete() { - g.setStructKey(vi, rkeys[i]) - keys[i] = rkeys[i] - } - if g.inTransaction { - mk := memkey(rkeys[i]) - delete(g.toDelete, mk) - g.toSet[mk] = vi - } else { - g.putMemory(vi) - } - } - }(i) - } - wg.Wait() - if any { - return keys, realError(multiErr) - } - return keys, nil -} - -func (g *Goon) putMemoryMulti(src interface{}, exists []byte) { - v := reflect.Indirect(reflect.ValueOf(src)) - for i := 0; i < v.Len(); i++ { - if exists[i] == 0 { - continue - } - g.putMemory(v.Index(i).Interface()) - } -} - -func (g *Goon) putMemory(src interface{}) { - key, _, _ := g.getStructKey(src) - g.cacheLock.Lock() - defer g.cacheLock.Unlock() - g.cache[memkey(key)] = src -} - -// FlushLocalCache clears the local memory cache. -func (g *Goon) FlushLocalCache() { - g.cacheLock.Lock() - g.cache = make(map[string]interface{}) - g.cacheLock.Unlock() -} - -func (g *Goon) putMemcache(srcs []interface{}, exists []byte) error { - items := make([]*memcache.Item, len(srcs)) - payloadSize := 0 - for i, src := range srcs { - toSerialize := src - if exists[i] == 0 { - toSerialize = nil - } - data, err := serializeStruct(toSerialize) - if err != nil { - g.error(err) - return err - } - key, _, err := g.getStructKey(src) - if err != nil { - return err - } - // payloadSize will overflow if we push 2+ gigs on a 32bit machine - payloadSize += len(data) - items[i] = &memcache.Item{ - Key: memkey(key), - Value: data, - } - } - memcacheTimeout := MemcachePutTimeoutSmall - if payloadSize >= MemcachePutTimeoutThreshold { - memcacheTimeout = MemcachePutTimeoutLarge - } - errc := make(chan error) - go func() { - errc <- memcache.SetMulti(appengine.Timeout(g.Context, memcacheTimeout), items) - }() - g.putMemoryMulti(srcs, exists) - err := <-errc - if appengine.IsTimeoutError(err) { - g.timeoutError(err) - err = nil - } else if err != nil { - g.error(err) - } - return err -} - -// Get loads the entity based on dst's key into dst -// If there is no such entity for the key, Get returns -// datastore.ErrNoSuchEntity. -func (g *Goon) Get(dst interface{}) error { - set := reflect.ValueOf(dst) - if set.Kind() != reflect.Ptr { - return fmt.Errorf("goon: expected pointer to a struct, got %#v", dst) - } - if !set.CanSet() { - set = set.Elem() - } - dsts := []interface{}{dst} - if err := g.GetMulti(dsts); err != nil { - // Look for an embedded error if it's multi - if me, ok := err.(appengine.MultiError); ok { - return me[0] - } - // Not multi, normal error - return err - } - set.Set(reflect.Indirect(reflect.ValueOf(dsts[0]))) - return nil -} - -const getMultiLimit = 1000 - -// GetMulti is a batch version of Get. -// -// dst must be a *[]S, *[]*S, *[]I, []S, []*S, or []I, for some struct type S, -// or some interface type I. If *[]I or []I, each element must be a struct pointer. -func (g *Goon) GetMulti(dst interface{}) error { - keys, err := g.extractKeys(dst, false) // don't allow incomplete keys on a Get request - if err != nil { - return err - } - - v := reflect.Indirect(reflect.ValueOf(dst)) - - if g.inTransaction { - // todo: support getMultiLimit in transactions - return datastore.GetMulti(g.Context, keys, v.Interface()) - } - - var dskeys []*datastore.Key - var dsdst []interface{} - var dixs []int - - var memkeys []string - var mixs []int - - g.cacheLock.RLock() - for i, key := range keys { - m := memkey(key) - vi := v.Index(i) - - if vi.Kind() == reflect.Struct { - vi = vi.Addr() - } - - if s, present := g.cache[m]; present { - if vi.Kind() == reflect.Interface { - vi = vi.Elem() - } - - reflect.Indirect(vi).Set(reflect.Indirect(reflect.ValueOf(s))) - } else { - memkeys = append(memkeys, m) - mixs = append(mixs, i) - dskeys = append(dskeys, key) - dsdst = append(dsdst, vi.Interface()) - dixs = append(dixs, i) - } - } - g.cacheLock.RUnlock() - - if len(memkeys) == 0 { - return nil - } - - multiErr, any := make(appengine.MultiError, len(keys)), false - - memvalues, err := memcache.GetMulti(appengine.Timeout(g.Context, MemcacheGetTimeout), memkeys) - if appengine.IsTimeoutError(err) { - g.timeoutError(err) - err = nil - } else if err != nil { - g.error(err) // timing out or another error from memcache isn't something to fail over, but do log it - // No memvalues found, prepare the datastore fetch list already prepared above - } else if len(memvalues) > 0 { - // since memcache fetch was successful, reset the datastore fetch list and repopulate it - dskeys = dskeys[:0] - dsdst = dsdst[:0] - dixs = dixs[:0] - // we only want to check the returned map if there weren't any errors - // unlike the datastore, memcache will return a smaller map with no error if some of the keys were missed - - for i, m := range memkeys { - d := v.Index(mixs[i]).Interface() - if v.Index(mixs[i]).Kind() == reflect.Struct { - d = v.Index(mixs[i]).Addr().Interface() - } - if s, present := memvalues[m]; present { - err := deserializeStruct(d, s.Value) - if err == datastore.ErrNoSuchEntity { - any = true // this flag tells GetMulti to return multiErr later - multiErr[mixs[i]] = err - } else if err != nil { - g.error(err) - return err - } else { - g.putMemory(d) - } - } else { - dskeys = append(dskeys, keys[mixs[i]]) - dsdst = append(dsdst, d) - dixs = append(dixs, mixs[i]) - } - } - if len(dskeys) == 0 { - if any { - return realError(multiErr) - } - return nil - } - } - - goroutines := (len(dskeys)-1)/getMultiLimit + 1 - var wg sync.WaitGroup - wg.Add(goroutines) - for i := 0; i < goroutines; i++ { - go func(i int) { - defer wg.Done() - var toCache []interface{} - var exists []byte - lo := i * getMultiLimit - hi := (i + 1) * getMultiLimit - if hi > len(dskeys) { - hi = len(dskeys) - } - gmerr := datastore.GetMulti(g.Context, dskeys[lo:hi], dsdst[lo:hi]) - if gmerr != nil { - any = true // this flag tells GetMulti to return multiErr later - merr, ok := gmerr.(appengine.MultiError) - if !ok { - g.error(gmerr) - for j := lo; j < hi; j++ { - multiErr[j] = gmerr - } - return - } - for i, idx := range dixs[lo:hi] { - if merr[i] == nil { - toCache = append(toCache, dsdst[lo+i]) - exists = append(exists, 1) - } else { - if merr[i] == datastore.ErrNoSuchEntity { - toCache = append(toCache, dsdst[lo+i]) - exists = append(exists, 0) - } - multiErr[idx] = merr[i] - } - } - } else { - toCache = append(toCache, dsdst[lo:hi]...) - exists = append(exists, bytes.Repeat([]byte{1}, hi-lo)...) - } - if len(toCache) > 0 { - if err := g.putMemcache(toCache, exists); err != nil { - g.error(err) - // since putMemcache() gives no guarantee it will actually store the data in memcache - // we log and swallow this error - } - - } - }(i) - } - wg.Wait() - if any { - return realError(multiErr) - } - return nil -} - -// Delete deletes the entity for the given key. -func (g *Goon) Delete(key *datastore.Key) error { - keys := []*datastore.Key{key} - err := g.DeleteMulti(keys) - if me, ok := err.(appengine.MultiError); ok { - return me[0] - } - return err -} - -const deleteMultiLimit = 500 - -// Returns a single error if each error in MultiError is the same -// otherwise, returns multiError or nil (if multiError is empty) -func realError(multiError appengine.MultiError) error { - if len(multiError) == 0 { - return nil - } - init := multiError[0] - for i := 1; i < len(multiError); i++ { - // since type error could hold structs, pointers, etc, - // the only way to compare non-nil errors is by their string output - if init == nil || multiError[i] == nil { - if init != multiError[i] { - return multiError - } - } else if init.Error() != multiError[i].Error() { - return multiError - } - } - // all errors are the same - // some errors are *always* returned in MultiError form from the datastore - if _, ok := init.(*datastore.ErrFieldMismatch); ok { // returned in GetMulti - return multiError - } - if init == datastore.ErrInvalidEntityType || // returned in GetMulti - init == datastore.ErrNoSuchEntity { // returned in GetMulti - return multiError - } - // datastore.ErrInvalidKey is returned as a single error in PutMulti - return init -} - -// DeleteMulti is a batch version of Delete. -func (g *Goon) DeleteMulti(keys []*datastore.Key) error { - if len(keys) == 0 { - return nil - // not an error, and it was "successful", so return nil - } - memkeys := make([]string, len(keys)) - - g.cacheLock.Lock() - for i, k := range keys { - mk := memkey(k) - memkeys[i] = mk - - if g.inTransaction { - delete(g.toSet, mk) - g.toDelete[mk] = true - } else { - delete(g.cache, mk) - } - } - g.cacheLock.Unlock() - - // Memcache needs to be updated after the datastore to prevent a common race condition, - // where a concurrent request will fetch the not-yet-updated data from the datastore - // and populate memcache with it. - if g.inTransaction { - for _, mk := range memkeys { - g.toDeleteMC[mk] = true - } - } else { - defer memcache.DeleteMulti(g.Context, memkeys) - } - - multiErr, any := make(appengine.MultiError, len(keys)), false - goroutines := (len(keys)-1)/deleteMultiLimit + 1 - var wg sync.WaitGroup - wg.Add(goroutines) - for i := 0; i < goroutines; i++ { - go func(i int) { - defer wg.Done() - lo := i * deleteMultiLimit - hi := (i + 1) * deleteMultiLimit - if hi > len(keys) { - hi = len(keys) - } - dmerr := datastore.DeleteMulti(g.Context, keys[lo:hi]) - if dmerr != nil { - any = true // this flag tells DeleteMulti to return multiErr later - merr, ok := dmerr.(appengine.MultiError) - if !ok { - g.error(dmerr) - for j := lo; j < hi; j++ { - multiErr[j] = dmerr - } - return - } - copy(multiErr[lo:hi], merr) - } - }(i) - } - wg.Wait() - if any { - return realError(multiErr) - } - return nil -} - -// NotFound returns true if err is an appengine.MultiError and err[idx] is a datastore.ErrNoSuchEntity. -func NotFound(err error, idx int) bool { - if merr, ok := err.(appengine.MultiError); ok { - return idx < len(merr) && merr[idx] == datastore.ErrNoSuchEntity - } - return false -} diff --git a/_third_party/github.com/mjibson/goon/goon_test.go b/_third_party/github.com/mjibson/goon/goon_test.go deleted file mode 100644 index d0f03e82..00000000 --- a/_third_party/github.com/mjibson/goon/goon_test.go +++ /dev/null @@ -1,2090 +0,0 @@ -/* - * Copyright (c) 2013 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package goon - -import ( - "reflect" - "sync" - "testing" - "time" - - "appengine" - "appengine/aetest" - "appengine/datastore" - "appengine/memcache" -) - -// *[]S, *[]*S, *[]I, []S, []*S, []I -const ( - ivTypePtrToSliceOfStructs = iota - ivTypePtrToSliceOfPtrsToStruct - ivTypePtrToSliceOfInterfaces - ivTypeSliceOfStructs - ivTypeSliceOfPtrsToStruct - ivTypeSliceOfInterfaces - ivTypeTotal -) - -const ( - ivModeDatastore = iota - ivModeMemcache - ivModeMemcacheAndDatastore - ivModeLocalcache - ivModeLocalcacheAndMemcache - ivModeLocalcacheAndDatastore - ivModeLocalcacheAndMemcacheAndDatastore - ivModeTotal -) - -// Have a bunch of different supported types to detect any wild errors -// https://developers.google.com/appengine/docs/go/datastore/reference -type ivItem struct { - Id int64 `datastore:"-" goon:"id"` - Int int `datastore:"int,noindex"` - Int8 int8 `datastore:"int8,noindex"` - Int16 int16 `datastore:"int16,noindex"` - Int32 int32 `datastore:"int32,noindex"` - Int64 int64 `datastore:"int64,noindex"` - Float32 float32 `datastore:"float32,noindex"` - Float64 float64 `datastore:"float64,noindex"` - Bool bool `datastore:"bool,noindex"` - String string `datastore:"string,noindex"` - CustomTypes ivItemCustom `datastore:"custom,noindex"` - SliceTypes ivItemSlice `datastore:"slice,noindex"` - ByteSlice []byte `datastore:"byte_slice,noindex"` - BSSlice [][]byte `datastore:"bs_slice,noindex"` - Time time.Time `datastore:"time,noindex"` - TimeSlice []time.Time `datastore:"time_slice,noindex"` - NoIndex int `datastore:",noindex"` - Casual string - Ζεύς string - Key *datastore.Key - ChildKey *datastore.Key - ZeroKey *datastore.Key - KeySlice []*datastore.Key - KeySliceNil []*datastore.Key - BlobKey appengine.BlobKey - BKSlice []appengine.BlobKey - Sub ivItemSub - Subs []ivItemSubs - ZZZV []ivZZZV -} - -type ivItemInt int -type ivItemInt8 int8 -type ivItemInt16 int16 -type ivItemInt32 int32 -type ivItemInt64 int64 -type ivItemFloat32 float32 -type ivItemFloat64 float64 -type ivItemBool bool -type ivItemString string - -type ivItemDeepInt ivItemInt - -type ivItemCustom struct { - Int ivItemInt - Int8 ivItemInt8 - Int16 ivItemInt16 - Int32 ivItemInt32 - Int64 ivItemInt64 - Float32 ivItemFloat32 - Float64 ivItemFloat64 - Bool ivItemBool - String ivItemString - DeepInt ivItemDeepInt -} - -type ivItemSlice struct { - Int []int - Int8 []int8 - Int16 []int16 - Int32 []int32 - Int64 []int64 - Float32 []float32 - Float64 []float64 - Bool []bool - String []string - IntC []ivItemInt - Int8C []ivItemInt8 - Int16C []ivItemInt16 - Int32C []ivItemInt32 - Int64C []ivItemInt64 - Float32C []ivItemFloat32 - Float64C []ivItemFloat64 - BoolC []ivItemBool - StringC []ivItemString - DeepInt []ivItemDeepInt -} - -type ivItemSub struct { - Data string `datastore:"data,noindex"` - Ints []int `datastore:"ints,noindex"` -} - -type ivItemSubs struct { - Data string `datastore:"data,noindex"` - Extra string `datastore:",noindex"` -} - -type ivZZZV struct { - Key *datastore.Key `datastore:"key,noindex"` - Data string `datastore:"data,noindex"` -} - -func (ivi *ivItem) ForInterface() {} - -type ivItemI interface { - ForInterface() -} - -var ivItems []ivItem - -func initializeIvItems(c appengine.Context) { - t1 := time.Now().Truncate(time.Microsecond) - t2 := t1.Add(time.Second * 1) - t3 := t1.Add(time.Second * 2) - - ivItems = []ivItem{ - {Id: 1, Int: 123, Int8: 77, Int16: 13001, Int32: 1234567890, Int64: 123456789012345, - Float32: (float32(10) / float32(3)), Float64: (float64(10000000) / float64(9998)), - Bool: true, String: "one", - CustomTypes: ivItemCustom{Int: 123, Int8: 77, Int16: 13001, Int32: 1234567890, Int64: 123456789012345, - Float32: ivItemFloat32(float32(10) / float32(3)), Float64: ivItemFloat64(float64(10000000) / float64(9998)), - Bool: true, String: "one", DeepInt: 1}, - SliceTypes: ivItemSlice{Int: []int{1, 2}, Int8: []int8{1, 2}, Int16: []int16{1, 2}, Int32: []int32{1, 2}, Int64: []int64{1, 2}, - Float32: []float32{1.0, 2.0}, Float64: []float64{1.0, 2.0}, Bool: []bool{true, false}, String: []string{"one", "two"}, - IntC: []ivItemInt{1, 2}, Int8C: []ivItemInt8{1, 2}, Int16C: []ivItemInt16{1, 2}, Int32C: []ivItemInt32{1, 2}, Int64C: []ivItemInt64{1, 2}, - Float32C: []ivItemFloat32{1.0, 2.0}, Float64C: []ivItemFloat64{1.0, 2.0}, - BoolC: []ivItemBool{true, false}, StringC: []ivItemString{"one", "two"}, DeepInt: []ivItemDeepInt{1, 2}}, - ByteSlice: []byte{0xDE, 0xAD}, BSSlice: [][]byte{{0x01, 0x02}, {0x03, 0x04}}, - Time: t1, TimeSlice: []time.Time{t1, t2, t3}, NoIndex: 1, - Casual: "clothes", Ζεύς: "Zeus", - Key: datastore.NewKey(c, "Fruit", "Apple", 0, nil), - ChildKey: datastore.NewKey(c, "Person", "Jane", 0, datastore.NewKey(c, "Person", "John", 0, datastore.NewKey(c, "Person", "Jack", 0, nil))), - KeySlice: []*datastore.Key{datastore.NewKey(c, "Key", "", 1, nil), datastore.NewKey(c, "Key", "", 2, nil), datastore.NewKey(c, "Key", "", 3, nil)}, - KeySliceNil: []*datastore.Key{datastore.NewKey(c, "Number", "", 1, nil), nil, datastore.NewKey(c, "Number", "", 2, nil)}, - BlobKey: "fake #1", BKSlice: []appengine.BlobKey{"fake #1.1", "fake #1.2"}, - Sub: ivItemSub{Data: "yay #1", Ints: []int{1, 2, 3}}, - Subs: []ivItemSubs{ - {Data: "sub #1.1", Extra: "xtra #1.1"}, - {Data: "sub #1.2", Extra: "xtra #1.2"}, - {Data: "sub #1.3", Extra: "xtra #1.3"}}, - ZZZV: []ivZZZV{{Data: "None"}, {Key: datastore.NewKey(c, "Fruit", "Banana", 0, nil)}}}, - {Id: 2, Int: 124, Int8: 78, Int16: 13002, Int32: 1234567891, Int64: 123456789012346, - Float32: (float32(10) / float32(3)), Float64: (float64(10000000) / float64(9998)), - Bool: true, String: "two", - CustomTypes: ivItemCustom{Int: 124, Int8: 78, Int16: 13002, Int32: 1234567891, Int64: 123456789012346, - Float32: ivItemFloat32(float32(10) / float32(3)), Float64: ivItemFloat64(float64(10000000) / float64(9998)), - Bool: true, String: "two", DeepInt: 2}, - SliceTypes: ivItemSlice{Int: []int{1, 2}, Int8: []int8{1, 2}, Int16: []int16{1, 2}, Int32: []int32{1, 2}, Int64: []int64{1, 2}, - Float32: []float32{1.0, 2.0}, Float64: []float64{1.0, 2.0}, Bool: []bool{true, false}, String: []string{"one", "two"}, - IntC: []ivItemInt{1, 2}, Int8C: []ivItemInt8{1, 2}, Int16C: []ivItemInt16{1, 2}, Int32C: []ivItemInt32{1, 2}, Int64C: []ivItemInt64{1, 2}, - Float32C: []ivItemFloat32{1.0, 2.0}, Float64C: []ivItemFloat64{1.0, 2.0}, - BoolC: []ivItemBool{true, false}, StringC: []ivItemString{"one", "two"}, DeepInt: []ivItemDeepInt{1, 2}}, - ByteSlice: []byte{0xBE, 0xEF}, BSSlice: [][]byte{{0x05, 0x06}, {0x07, 0x08}}, - Time: t2, TimeSlice: []time.Time{t2, t3, t1}, NoIndex: 2, - Casual: "manners", Ζεύς: "Alcmene", - Key: datastore.NewKey(c, "Fruit", "Banana", 0, nil), - ChildKey: datastore.NewKey(c, "Person", "Jane", 0, datastore.NewKey(c, "Person", "John", 0, datastore.NewKey(c, "Person", "Jack", 0, nil))), - KeySlice: []*datastore.Key{datastore.NewKey(c, "Key", "", 4, nil), datastore.NewKey(c, "Key", "", 5, nil), datastore.NewKey(c, "Key", "", 6, nil)}, - KeySliceNil: []*datastore.Key{datastore.NewKey(c, "Number", "", 3, nil), nil, datastore.NewKey(c, "Number", "", 4, nil)}, - BlobKey: "fake #2", BKSlice: []appengine.BlobKey{"fake #2.1", "fake #2.2"}, - Sub: ivItemSub{Data: "yay #2", Ints: []int{4, 5, 6}}, - Subs: []ivItemSubs{ - {Data: "sub #2.1", Extra: "xtra #2.1"}, - {Data: "sub #2.2", Extra: "xtra #2.2"}, - {Data: "sub #2.3", Extra: "xtra #2.3"}}, - ZZZV: []ivZZZV{{Data: "None"}, {Key: datastore.NewKey(c, "Fruit", "Banana", 0, nil)}}}, - {Id: 3, Int: 125, Int8: 79, Int16: 13003, Int32: 1234567892, Int64: 123456789012347, - Float32: (float32(10) / float32(3)), Float64: (float64(10000000) / float64(9998)), - Bool: true, String: "tri", - CustomTypes: ivItemCustom{Int: 125, Int8: 79, Int16: 13003, Int32: 1234567892, Int64: 123456789012347, - Float32: ivItemFloat32(float32(10) / float32(3)), Float64: ivItemFloat64(float64(10000000) / float64(9998)), - Bool: true, String: "tri", DeepInt: 3}, - SliceTypes: ivItemSlice{Int: []int{1, 2}, Int8: []int8{1, 2}, Int16: []int16{1, 2}, Int32: []int32{1, 2}, Int64: []int64{1, 2}, - Float32: []float32{1.0, 2.0}, Float64: []float64{1.0, 2.0}, Bool: []bool{true, false}, String: []string{"one", "two"}, - IntC: []ivItemInt{1, 2}, Int8C: []ivItemInt8{1, 2}, Int16C: []ivItemInt16{1, 2}, Int32C: []ivItemInt32{1, 2}, Int64C: []ivItemInt64{1, 2}, - Float32C: []ivItemFloat32{1.0, 2.0}, Float64C: []ivItemFloat64{1.0, 2.0}, - BoolC: []ivItemBool{true, false}, StringC: []ivItemString{"one", "two"}, DeepInt: []ivItemDeepInt{1, 2}}, - ByteSlice: []byte{0xF0, 0x0D}, BSSlice: [][]byte{{0x09, 0x0A}, {0x0B, 0x0C}}, - Time: t3, TimeSlice: []time.Time{t3, t1, t2}, NoIndex: 3, - Casual: "weather", Ζεύς: "Hercules", - Key: datastore.NewKey(c, "Fruit", "Cherry", 0, nil), - ChildKey: datastore.NewKey(c, "Person", "Jane", 0, datastore.NewKey(c, "Person", "John", 0, datastore.NewKey(c, "Person", "Jack", 0, nil))), - KeySlice: []*datastore.Key{datastore.NewKey(c, "Key", "", 7, nil), datastore.NewKey(c, "Key", "", 8, nil), datastore.NewKey(c, "Key", "", 9, nil)}, - KeySliceNil: []*datastore.Key{datastore.NewKey(c, "Number", "", 5, nil), nil, datastore.NewKey(c, "Number", "", 6, nil)}, - BlobKey: "fake #3", BKSlice: []appengine.BlobKey{"fake #3.1", "fake #3.2"}, - Sub: ivItemSub{Data: "yay #3", Ints: []int{7, 8, 9}}, - Subs: []ivItemSubs{ - {Data: "sub #3.1", Extra: "xtra #3.1"}, - {Data: "sub #3.2", Extra: "xtra #3.2"}, - {Data: "sub #3.3", Extra: "xtra #3.3"}}, - ZZZV: []ivZZZV{{Data: "None"}, {Key: datastore.NewKey(c, "Fruit", "Banana", 0, nil)}}}} -} - -func getIVItemCopy(g *Goon, index int) *ivItem { - // All basic value types are copied easily - ivi := ivItems[index] - - // .. but pointer based types require extra work - ivi.SliceTypes.Int = []int{} - for _, v := range ivItems[index].SliceTypes.Int { - ivi.SliceTypes.Int = append(ivi.SliceTypes.Int, v) - } - - ivi.SliceTypes.Int8 = []int8{} - for _, v := range ivItems[index].SliceTypes.Int8 { - ivi.SliceTypes.Int8 = append(ivi.SliceTypes.Int8, v) - } - - ivi.SliceTypes.Int16 = []int16{} - for _, v := range ivItems[index].SliceTypes.Int16 { - ivi.SliceTypes.Int16 = append(ivi.SliceTypes.Int16, v) - } - - ivi.SliceTypes.Int32 = []int32{} - for _, v := range ivItems[index].SliceTypes.Int32 { - ivi.SliceTypes.Int32 = append(ivi.SliceTypes.Int32, v) - } - - ivi.SliceTypes.Int64 = []int64{} - for _, v := range ivItems[index].SliceTypes.Int64 { - ivi.SliceTypes.Int64 = append(ivi.SliceTypes.Int64, v) - } - - ivi.SliceTypes.Float32 = []float32{} - for _, v := range ivItems[index].SliceTypes.Float32 { - ivi.SliceTypes.Float32 = append(ivi.SliceTypes.Float32, v) - } - - ivi.SliceTypes.Float64 = []float64{} - for _, v := range ivItems[index].SliceTypes.Float64 { - ivi.SliceTypes.Float64 = append(ivi.SliceTypes.Float64, v) - } - - ivi.SliceTypes.Bool = []bool{} - for _, v := range ivItems[index].SliceTypes.Bool { - ivi.SliceTypes.Bool = append(ivi.SliceTypes.Bool, v) - } - - ivi.SliceTypes.String = []string{} - for _, v := range ivItems[index].SliceTypes.String { - ivi.SliceTypes.String = append(ivi.SliceTypes.String, v) - } - - ivi.SliceTypes.IntC = []ivItemInt{} - for _, v := range ivItems[index].SliceTypes.IntC { - ivi.SliceTypes.IntC = append(ivi.SliceTypes.IntC, v) - } - - ivi.SliceTypes.Int8C = []ivItemInt8{} - for _, v := range ivItems[index].SliceTypes.Int8C { - ivi.SliceTypes.Int8C = append(ivi.SliceTypes.Int8C, v) - } - - ivi.SliceTypes.Int16C = []ivItemInt16{} - for _, v := range ivItems[index].SliceTypes.Int16C { - ivi.SliceTypes.Int16C = append(ivi.SliceTypes.Int16C, v) - } - - ivi.SliceTypes.Int32C = []ivItemInt32{} - for _, v := range ivItems[index].SliceTypes.Int32C { - ivi.SliceTypes.Int32C = append(ivi.SliceTypes.Int32C, v) - } - - ivi.SliceTypes.Int64C = []ivItemInt64{} - for _, v := range ivItems[index].SliceTypes.Int64C { - ivi.SliceTypes.Int64C = append(ivi.SliceTypes.Int64C, v) - } - - ivi.SliceTypes.Float32C = []ivItemFloat32{} - for _, v := range ivItems[index].SliceTypes.Float32C { - ivi.SliceTypes.Float32C = append(ivi.SliceTypes.Float32C, v) - } - - ivi.SliceTypes.Float64C = []ivItemFloat64{} - for _, v := range ivItems[index].SliceTypes.Float64C { - ivi.SliceTypes.Float64C = append(ivi.SliceTypes.Float64C, v) - } - - ivi.SliceTypes.BoolC = []ivItemBool{} - for _, v := range ivItems[index].SliceTypes.BoolC { - ivi.SliceTypes.BoolC = append(ivi.SliceTypes.BoolC, v) - } - - ivi.SliceTypes.StringC = []ivItemString{} - for _, v := range ivItems[index].SliceTypes.StringC { - ivi.SliceTypes.StringC = append(ivi.SliceTypes.StringC, v) - } - - ivi.SliceTypes.DeepInt = []ivItemDeepInt{} - for _, v := range ivItems[index].SliceTypes.DeepInt { - ivi.SliceTypes.DeepInt = append(ivi.SliceTypes.DeepInt, v) - } - - ivi.ByteSlice = []byte{} - for _, v := range ivItems[index].ByteSlice { - ivi.ByteSlice = append(ivi.ByteSlice, v) - } - - ivi.BSSlice = [][]byte{} - for _, v := range ivItems[index].BSSlice { - vCopy := []byte{} - for _, v := range v { - vCopy = append(vCopy, v) - } - ivi.BSSlice = append(ivi.BSSlice, vCopy) - } - - ivi.TimeSlice = []time.Time{} - for _, v := range ivItems[index].TimeSlice { - ivi.TimeSlice = append(ivi.TimeSlice, v) - } - - ivi.Key = datastore.NewKey(g.Context, ivItems[index].Key.Kind(), ivItems[index].Key.StringID(), ivItems[index].Key.IntID(), nil) - - ivi.ChildKey = datastore.NewKey(g.Context, ivItems[index].ChildKey.Kind(), ivItems[index].ChildKey.StringID(), ivItems[index].ChildKey.IntID(), - datastore.NewKey(g.Context, ivItems[index].ChildKey.Parent().Kind(), ivItems[index].ChildKey.Parent().StringID(), ivItems[index].ChildKey.Parent().IntID(), - datastore.NewKey(g.Context, ivItems[index].ChildKey.Parent().Parent().Kind(), ivItems[index].ChildKey.Parent().Parent().StringID(), ivItems[index].ChildKey.Parent().Parent().IntID(), nil))) - - ivi.KeySlice = []*datastore.Key{} - for _, key := range ivItems[index].KeySlice { - ivi.KeySlice = append(ivi.KeySlice, datastore.NewKey(g.Context, key.Kind(), key.StringID(), key.IntID(), nil)) - } - - ivi.KeySliceNil = []*datastore.Key{} - for _, key := range ivItems[index].KeySliceNil { - if key == nil { - ivi.KeySliceNil = append(ivi.KeySliceNil, nil) - } else { - ivi.KeySliceNil = append(ivi.KeySliceNil, datastore.NewKey(g.Context, key.Kind(), key.StringID(), key.IntID(), nil)) - } - } - - ivi.BKSlice = []appengine.BlobKey{} - for _, v := range ivItems[index].BKSlice { - ivi.BKSlice = append(ivi.BKSlice, v) - } - - ivi.Sub = ivItemSub{} - ivi.Sub.Data = ivItems[index].Sub.Data - for _, v := range ivItems[index].Sub.Ints { - ivi.Sub.Ints = append(ivi.Sub.Ints, v) - } - - ivi.Subs = []ivItemSubs{} - for _, sub := range ivItems[index].Subs { - ivi.Subs = append(ivi.Subs, ivItemSubs{Data: sub.Data, Extra: sub.Extra}) - } - - ivi.ZZZV = []ivZZZV{} - for _, zzzv := range ivItems[index].ZZZV { - ivi.ZZZV = append(ivi.ZZZV, ivZZZV{Key: zzzv.Key, Data: zzzv.Data}) - } - - return &ivi -} - -func getInputVarietySrc(t *testing.T, g *Goon, ivType int, indices ...int) interface{} { - if ivType >= ivTypeTotal { - t.Fatalf("Invalid input variety type! %v >= %v", ivType, ivTypeTotal) - return nil - } - - var result interface{} - - switch ivType { - case ivTypePtrToSliceOfStructs: - s := []ivItem{} - for _, index := range indices { - s = append(s, *getIVItemCopy(g, index)) - } - result = &s - case ivTypePtrToSliceOfPtrsToStruct: - s := []*ivItem{} - for _, index := range indices { - s = append(s, getIVItemCopy(g, index)) - } - result = &s - case ivTypePtrToSliceOfInterfaces: - s := []ivItemI{} - for _, index := range indices { - s = append(s, getIVItemCopy(g, index)) - } - result = &s - case ivTypeSliceOfStructs: - s := []ivItem{} - for _, index := range indices { - s = append(s, *getIVItemCopy(g, index)) - } - result = s - case ivTypeSliceOfPtrsToStruct: - s := []*ivItem{} - for _, index := range indices { - s = append(s, getIVItemCopy(g, index)) - } - result = s - case ivTypeSliceOfInterfaces: - s := []ivItemI{} - for _, index := range indices { - s = append(s, getIVItemCopy(g, index)) - } - result = s - } - - return result -} - -func getInputVarietyDst(t *testing.T, ivType int) interface{} { - if ivType >= ivTypeTotal { - t.Fatalf("Invalid input variety type! %v >= %v", ivType, ivTypeTotal) - return nil - } - - var result interface{} - - switch ivType { - case ivTypePtrToSliceOfStructs: - result = &[]ivItem{{Id: ivItems[0].Id}, {Id: ivItems[1].Id}, {Id: ivItems[2].Id}} - case ivTypePtrToSliceOfPtrsToStruct: - result = &[]*ivItem{{Id: ivItems[0].Id}, {Id: ivItems[1].Id}, {Id: ivItems[2].Id}} - case ivTypePtrToSliceOfInterfaces: - result = &[]ivItemI{&ivItem{Id: ivItems[0].Id}, &ivItem{Id: ivItems[1].Id}, &ivItem{Id: ivItems[2].Id}} - case ivTypeSliceOfStructs: - result = []ivItem{{Id: ivItems[0].Id}, {Id: ivItems[1].Id}, {Id: ivItems[2].Id}} - case ivTypeSliceOfPtrsToStruct: - result = []*ivItem{{Id: ivItems[0].Id}, {Id: ivItems[1].Id}, {Id: ivItems[2].Id}} - case ivTypeSliceOfInterfaces: - result = []ivItemI{&ivItem{Id: ivItems[0].Id}, &ivItem{Id: ivItems[1].Id}, &ivItem{Id: ivItems[2].Id}} - } - - return result -} - -func getPrettyIVMode(ivMode int) string { - result := "N/A" - - switch ivMode { - case ivModeDatastore: - result = "DS" - case ivModeMemcache: - result = "MC" - case ivModeMemcacheAndDatastore: - result = "DS+MC" - case ivModeLocalcache: - result = "LC" - case ivModeLocalcacheAndMemcache: - result = "MC+LC" - case ivModeLocalcacheAndDatastore: - result = "DS+LC" - case ivModeLocalcacheAndMemcacheAndDatastore: - result = "DS+MC+LC" - } - - return result -} - -func getPrettyIVType(ivType int) string { - result := "N/A" - - switch ivType { - case ivTypePtrToSliceOfStructs: - result = "*[]S" - case ivTypePtrToSliceOfPtrsToStruct: - result = "*[]*S" - case ivTypePtrToSliceOfInterfaces: - result = "*[]I" - case ivTypeSliceOfStructs: - result = "[]S" - case ivTypeSliceOfPtrsToStruct: - result = "[]*S" - case ivTypeSliceOfInterfaces: - result = "[]I" - } - - return result -} - -func ivWipe(t *testing.T, g *Goon, prettyInfo string) { - // Make sure the datastore is clear of any previous tests - // TODO: Batch this once goon gets more convenient batch delete support - for _, ivi := range ivItems { - if err := g.Delete(g.Key(ivi)); err != nil { - t.Errorf("%s > Unexpected error on delete - %v", prettyInfo, err) - } - } - - // Make sure the caches are clear, so any caching is done by our specific test - g.FlushLocalCache() - memcache.Flush(g.Context) -} - -func ivGetMulti(t *testing.T, g *Goon, ref, dst interface{}, prettyInfo string) error { - // Get our data back and make sure it's correct - if err := g.GetMulti(dst); err != nil { - t.Errorf("%s > Unexpected error on GetMulti - %v", prettyInfo, err) - return err - } else { - dstLen := reflect.Indirect(reflect.ValueOf(dst)).Len() - refLen := reflect.Indirect(reflect.ValueOf(ref)).Len() - - if dstLen != refLen { - t.Errorf("%s > Unexpected dst len (%v) doesn't match ref len (%v)", prettyInfo, dstLen, refLen) - } else if !reflect.DeepEqual(ref, dst) { - t.Errorf("%s > Expected - %v, %v, %v - got %v, %v, %v", prettyInfo, - reflect.Indirect(reflect.ValueOf(ref)).Index(0).Interface(), - reflect.Indirect(reflect.ValueOf(ref)).Index(1).Interface(), - reflect.Indirect(reflect.ValueOf(ref)).Index(2).Interface(), - reflect.Indirect(reflect.ValueOf(dst)).Index(0).Interface(), - reflect.Indirect(reflect.ValueOf(dst)).Index(1).Interface(), - reflect.Indirect(reflect.ValueOf(dst)).Index(2).Interface()) - } - } - - return nil -} - -func validateInputVariety(t *testing.T, g *Goon, srcType, dstType, mode int) { - if mode >= ivModeTotal { - t.Fatalf("Invalid input variety mode! %v >= %v", mode, ivModeTotal) - return - } - - // Generate a nice debug info string for clear logging - prettyInfo := getPrettyIVType(srcType) + " " + getPrettyIVType(dstType) + " " + getPrettyIVMode(mode) - - // This function just gets the entities based on a predefined list, helper for cache population - loadIVItem := func(indices ...int) { - for _, index := range indices { - ivi := &ivItem{Id: ivItems[index].Id} - if err := g.Get(ivi); err != nil { - t.Errorf("%s > Unexpected error on get - %v", prettyInfo, err) - } else if !reflect.DeepEqual(ivItems[index], *ivi) { - t.Errorf("%s > Expected - %v, got %v", prettyInfo, ivItems[index], *ivi) - } - } - } - - // Start with a clean slate - ivWipe(t, g, prettyInfo) - - // Generate test data with the specified types - src := getInputVarietySrc(t, g, srcType, 0, 1, 2) - ref := getInputVarietySrc(t, g, dstType, 0, 1, 2) - dst := getInputVarietyDst(t, dstType) - - // Save our test data - if _, err := g.PutMulti(src); err != nil { - t.Errorf("%s > Unexpected error on PutMulti - %v", prettyInfo, err) - } - - // Clear the caches, as we're going to precisely set the caches via Get - g.FlushLocalCache() - memcache.Flush(g.Context) - - // Set the caches into proper state based on given mode - switch mode { - case ivModeDatastore: - // Caches already clear - case ivModeMemcache: - loadIVItem(0, 1, 2) // Left in memcache - g.FlushLocalCache() - case ivModeMemcacheAndDatastore: - loadIVItem(0, 1) // Left in memcache - g.FlushLocalCache() - case ivModeLocalcache: - loadIVItem(0, 1, 2) // Left in local cache - case ivModeLocalcacheAndMemcache: - loadIVItem(0) // Left in memcache - g.FlushLocalCache() - loadIVItem(1, 2) // Left in local cache - case ivModeLocalcacheAndDatastore: - loadIVItem(0, 1) // Left in local cache - case ivModeLocalcacheAndMemcacheAndDatastore: - loadIVItem(0) // Left in memcache - g.FlushLocalCache() - loadIVItem(1) // Left in local cache - } - - // Get our data back and make sure it's correct - ivGetMulti(t, g, ref, dst, prettyInfo) -} - -func validateInputVarietyTXNPut(t *testing.T, g *Goon, srcType, dstType, mode int) { - if mode >= ivModeTotal { - t.Fatalf("Invalid input variety mode! %v >= %v", mode, ivModeTotal) - return - } - - // The following modes are redundant with the current goon transaction implementation - switch mode { - case ivModeMemcache: - return - case ivModeMemcacheAndDatastore: - return - case ivModeLocalcacheAndMemcache: - return - case ivModeLocalcacheAndMemcacheAndDatastore: - return - } - - // Generate a nice debug info string for clear logging - prettyInfo := getPrettyIVType(srcType) + " " + getPrettyIVType(dstType) + " " + getPrettyIVMode(mode) + " TXNPut" - - // Start with a clean slate - ivWipe(t, g, prettyInfo) - - // Generate test data with the specified types - src := getInputVarietySrc(t, g, srcType, 0, 1, 2) - ref := getInputVarietySrc(t, g, dstType, 0, 1, 2) - dst := getInputVarietyDst(t, dstType) - - // Save our test data - if err := g.RunInTransaction(func(tg *Goon) error { - _, err := tg.PutMulti(src) - return err - }, &datastore.TransactionOptions{XG: true}); err != nil { - t.Errorf("%s > Unexpected error on PutMulti - %v", prettyInfo, err) - } - - // Set the caches into proper state based on given mode - switch mode { - case ivModeDatastore: - g.FlushLocalCache() - memcache.Flush(g.Context) - case ivModeLocalcache: - // Entities already in local cache - case ivModeLocalcacheAndDatastore: - g.FlushLocalCache() - memcache.Flush(g.Context) - - subSrc := getInputVarietySrc(t, g, srcType, 0) - - if err := g.RunInTransaction(func(tg *Goon) error { - _, err := tg.PutMulti(subSrc) - return err - }, &datastore.TransactionOptions{XG: true}); err != nil { - t.Errorf("%s > Unexpected error on PutMulti - %v", prettyInfo, err) - } - } - - // Get our data back and make sure it's correct - ivGetMulti(t, g, ref, dst, prettyInfo) -} - -func validateInputVarietyTXNGet(t *testing.T, g *Goon, srcType, dstType, mode int) { - if mode >= ivModeTotal { - t.Fatalf("Invalid input variety mode! %v >= %v", mode, ivModeTotal) - return - } - - // The following modes are redundant with the current goon transaction implementation - switch mode { - case ivModeMemcache: - return - case ivModeMemcacheAndDatastore: - return - case ivModeLocalcache: - return - case ivModeLocalcacheAndMemcache: - return - case ivModeLocalcacheAndDatastore: - return - case ivModeLocalcacheAndMemcacheAndDatastore: - return - } - - // Generate a nice debug info string for clear logging - prettyInfo := getPrettyIVType(srcType) + " " + getPrettyIVType(dstType) + " " + getPrettyIVMode(mode) + " TXNGet" - - // Start with a clean slate - ivWipe(t, g, prettyInfo) - - // Generate test data with the specified types - src := getInputVarietySrc(t, g, srcType, 0, 1, 2) - ref := getInputVarietySrc(t, g, dstType, 0, 1, 2) - dst := getInputVarietyDst(t, dstType) - - // Save our test data - if _, err := g.PutMulti(src); err != nil { - t.Errorf("%s > Unexpected error on PutMulti - %v", prettyInfo, err) - } - - // Set the caches into proper state based on given mode - // TODO: Instead of clear, fill the caches with invalid data, because we're supposed to always fetch from the datastore - switch mode { - case ivModeDatastore: - g.FlushLocalCache() - memcache.Flush(g.Context) - } - - // Get our data back and make sure it's correct - if err := g.RunInTransaction(func(tg *Goon) error { - return ivGetMulti(t, tg, ref, dst, prettyInfo) - }, &datastore.TransactionOptions{XG: true}); err != nil { - t.Errorf("%s > Unexpected error on transaction - %v", prettyInfo, err) - } -} - -func TestInputVariety(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - g := FromContext(c) - - initializeIvItems(c) - - for srcType := 0; srcType < ivTypeTotal; srcType++ { - for dstType := 0; dstType < ivTypeTotal; dstType++ { - for mode := 0; mode < ivModeTotal; mode++ { - validateInputVariety(t, g, srcType, dstType, mode) - validateInputVarietyTXNPut(t, g, srcType, dstType, mode) - validateInputVarietyTXNGet(t, g, srcType, dstType, mode) - } - } - } -} - -type MigrationA struct { - _kind string `goon:"kind,Migration"` - Id int64 `datastore:"-" goon:"id"` - Number int32 `datastore:"number,noindex"` - Word string `datastore:"word,noindex"` - Car string `datastore:"car,noindex"` - Holiday time.Time `datastore:"holiday,noindex"` - α int `datastore:",noindex"` - Level MigrationIntA `datastore:"level,noindex"` - Floor MigrationIntA `datastore:"floor,noindex"` - Sub MigrationSub `datastore:"sub,noindex"` - Son MigrationPerson `datastore:"son,noindex"` - Daughter MigrationPerson `datastore:"daughter,noindex"` - Parents []MigrationPerson `datastore:"parents,noindex"` - DeepSlice MigrationDeepA `datastore:"deep,noindex"` - ZZs []ZigZag `datastore:"zigzag,noindex"` - ZeroKey *datastore.Key `datastore:",noindex"` - File []byte -} - -type MigrationSub struct { - Data string `datastore:"data,noindex"` - Noise []int `datastore:"noise,noindex"` - Sub MigrationSubSub `datastore:"sub,noindex"` -} - -type MigrationSubSub struct { - Data string `datastore:"data,noindex"` -} - -type MigrationPerson struct { - Name string `datastore:"name,noindex"` - Age int `datastore:"age,noindex"` -} - -type MigrationDeepA struct { - Deep MigrationDeepB `datastore:"deep,noindex"` -} - -type MigrationDeepB struct { - Deep MigrationDeepC `datastore:"deep,noindex"` -} - -type MigrationDeepC struct { - Slice []int `datastore:"slice,noindex"` -} - -type ZigZag struct { - Zig int `datastore:"zig,noindex"` - Zag int `datastore:"zag,noindex"` -} - -type ZigZags struct { - Zig []int `datastore:"zig,noindex"` - Zag []int `datastore:"zag,noindex"` -} - -type MigrationIntA int -type MigrationIntB int - -type MigrationB struct { - _kind string `goon:"kind,Migration"` - Identification int64 `datastore:"-" goon:"id"` - FancyNumber int32 `datastore:"number,noindex"` - Slang string `datastore:"word,noindex"` - Cars []string `datastore:"car,noindex"` - Holidays []time.Time `datastore:"holiday,noindex"` - β int `datastore:"α,noindex"` - Level MigrationIntB `datastore:"level,noindex"` - Floors []MigrationIntB `datastore:"floor,noindex"` - Animal string `datastore:"sub.data,noindex"` - Music []int `datastore:"sub.noise,noindex"` - Flower string `datastore:"sub.sub.data,noindex"` - Sons []MigrationPerson `datastore:"son,noindex"` - DaughterName string `datastore:"daughter.name,noindex"` - DaughterAge int `datastore:"daughter.age,noindex"` - OldFolks []MigrationPerson `datastore:"parents,noindex"` - FarSlice MigrationDeepA `datastore:"deep,noindex"` - ZZs ZigZags `datastore:"zigzag,noindex"` - Keys []*datastore.Key `datastore:"ZeroKey,noindex"` - Files [][]byte `datastore:"File,noindex"` -} - -func TestMigration(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - g := FromContext(c) - - // Create & save an entity with the original structure - migA := &MigrationA{Id: 1, Number: 123, Word: "rabbit", Car: "BMW", - Holiday: time.Now().Truncate(time.Microsecond), α: 1, Level: 9001, Floor: 5, - Sub: MigrationSub{Data: "fox", Noise: []int{1, 2, 3}, Sub: MigrationSubSub{Data: "rose"}}, - Son: MigrationPerson{Name: "John", Age: 5}, Daughter: MigrationPerson{Name: "Nancy", Age: 6}, - Parents: []MigrationPerson{{Name: "Sven", Age: 56}, {Name: "Sonya", Age: 49}}, - DeepSlice: MigrationDeepA{Deep: MigrationDeepB{Deep: MigrationDeepC{Slice: []int{1, 2, 3}}}}, - ZZs: []ZigZag{{Zig: 1}, {Zag: 1}}, File: []byte{0xF0, 0x0D}} - if _, err := g.Put(migA); err != nil { - t.Errorf("Unexpected error on Put: %v", err) - } - - // Clear the local cache, because we want this data in memcache - g.FlushLocalCache() - - // Get it back, so it's in the cache - migA = &MigrationA{Id: 1} - if err := g.Get(migA); err != nil { - t.Errorf("Unexpected error on Get: %v", err) - } - - // Clear the local cache, because it doesn't need to support migration - g.FlushLocalCache() - - // Test whether memcache supports migration - verifyMigration(t, g, migA, "MC") - - // Clear all the caches - g.FlushLocalCache() - memcache.Flush(c) - - // Test whether datastore supports migration - verifyMigration(t, g, migA, "DS") -} - -func verifyMigration(t *testing.T, g *Goon, migA *MigrationA, debugInfo string) { - migB := &MigrationB{Identification: migA.Id} - if err := g.Get(migB); err != nil { - t.Errorf("%v > Unexpected error on Get: %v", debugInfo, err) - } else if migA.Id != migB.Identification { - t.Errorf("%v > Ids don't match: %v != %v", debugInfo, migA.Id, migB.Identification) - } else if migA.Number != migB.FancyNumber { - t.Errorf("%v > Numbers don't match: %v != %v", debugInfo, migA.Number, migB.FancyNumber) - } else if migA.Word != migB.Slang { - t.Errorf("%v > Words don't match: %v != %v", debugInfo, migA.Word, migB.Slang) - } else if len(migB.Cars) != 1 { - t.Errorf("%v > Expected 1 car! Got: %v", debugInfo, len(migB.Cars)) - } else if migA.Car != migB.Cars[0] { - t.Errorf("%v > Cars don't match: %v != %v", debugInfo, migA.Car, migB.Cars[0]) - } else if len(migB.Holidays) != 1 { - t.Errorf("%v > Expected 1 holiday! Got: %v", debugInfo, len(migB.Holidays)) - } else if migA.Holiday != migB.Holidays[0] { - t.Errorf("%v > Holidays don't match: %v != %v", debugInfo, migA.Holiday, migB.Holidays[0]) - } else if migA.α != migB.β { - t.Errorf("%v > Greek doesn't match: %v != %v", debugInfo, migA.α, migB.β) - } else if int(migA.Level) != int(migB.Level) { - t.Errorf("%v > Level doesn't match: %v != %v", debugInfo, migA.Level, migB.Level) - } else if len(migB.Floors) != 1 { - t.Errorf("%v > Expected 1 floor! Got: %v", debugInfo, len(migB.Floors)) - } else if int(migA.Floor) != int(migB.Floors[0]) { - t.Errorf("%v > Floor doesn't match: %v != %v", debugInfo, migA.Floor, migB.Floors[0]) - } else if migA.Sub.Data != migB.Animal { - t.Errorf("%v > Animal doesn't match: %v != %v", debugInfo, migA.Sub.Data, migB.Animal) - } else if !reflect.DeepEqual(migA.Sub.Noise, migB.Music) { - t.Errorf("%v > Music doesn't match: %v != %v", debugInfo, migA.Sub.Noise, migB.Music) - } else if migA.Sub.Sub.Data != migB.Flower { - t.Errorf("%v > Flower doesn't match: %v != %v", debugInfo, migA.Sub.Sub.Data, migB.Flower) - } else if len(migB.Sons) != 1 { - t.Errorf("%v > Expected 1 son! Got: %v", debugInfo, len(migB.Sons)) - } else if migA.Son.Name != migB.Sons[0].Name { - t.Errorf("%v > Son names don't match: %v != %v", debugInfo, migA.Son.Name, migB.Sons[0].Name) - } else if migA.Son.Age != migB.Sons[0].Age { - t.Errorf("%v > Son ages don't match: %v != %v", debugInfo, migA.Son.Age, migB.Sons[0].Age) - } else if migA.Daughter.Name != migB.DaughterName { - t.Errorf("%v > Daughter names don't match: %v != %v", debugInfo, migA.Daughter.Name, migB.DaughterName) - } else if migA.Daughter.Age != migB.DaughterAge { - t.Errorf("%v > Daughter ages don't match: %v != %v", debugInfo, migA.Daughter.Age, migB.DaughterAge) - } else if !reflect.DeepEqual(migA.Parents, migB.OldFolks) { - t.Errorf("%v > Parents don't match: %v != %v", debugInfo, migA.Parents, migB.OldFolks) - } else if !reflect.DeepEqual(migA.DeepSlice, migB.FarSlice) { - t.Errorf("%v > Deep slice doesn't match: %v != %v", debugInfo, migA.DeepSlice, migB.FarSlice) - } else if len(migB.ZZs.Zig) != 2 { - t.Errorf("%v > Expected 2 Zigs, got: %v", debugInfo, len(migB.ZZs.Zig)) - } else if len(migB.ZZs.Zag) != 2 { - t.Errorf("%v > Expected 2 Zags, got: %v", debugInfo, len(migB.ZZs.Zag)) - } else if migA.ZZs[0].Zig != migB.ZZs.Zig[0] { - t.Errorf("%v > Invalid zig #1: %v != %v", debugInfo, migA.ZZs[0].Zig, migB.ZZs.Zig[0]) - } else if migA.ZZs[1].Zig != migB.ZZs.Zig[1] { - t.Errorf("%v > Invalid zig #2: %v != %v", debugInfo, migA.ZZs[1].Zig, migB.ZZs.Zig[1]) - } else if migA.ZZs[0].Zag != migB.ZZs.Zag[0] { - t.Errorf("%v > Invalid zag #1: %v != %v", debugInfo, migA.ZZs[0].Zag, migB.ZZs.Zag[0]) - } else if migA.ZZs[1].Zag != migB.ZZs.Zag[1] { - t.Errorf("%v > Invalid zag #2: %v != %v", debugInfo, migA.ZZs[1].Zag, migB.ZZs.Zag[1]) - } else if len(migB.Keys) != 1 { - t.Errorf("%v > Expected 1 keys, got %v", debugInfo, len(migB.Keys)) - } else if len(migB.Files) != 1 { - t.Errorf("%v > Expected 1 file, got %v", debugInfo, len(migB.Files)) - } else if !reflect.DeepEqual(migA.File, migB.Files[0]) { - t.Errorf("%v > Files don't match: %v != %v", debugInfo, migA.File, migB.Files[0]) - } -} - -func TestTXNRace(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - g := FromContext(c) - - // Create & store some test data - hid := &HasId{Id: 1, Name: "foo"} - if _, err := g.Put(hid); err != nil { - t.Errorf("Unexpected error on Put %v", err) - } - - // Get this data back, to populate caches - if err := g.Get(hid); err != nil { - t.Errorf("Unexpected error on Get %v", err) - } - - // Clear the local cache, as we are testing for proper memcache usage - g.FlushLocalCache() - - // Update the test data inside a transction - if err := g.RunInTransaction(func(tg *Goon) error { - // Get the current data - thid := &HasId{Id: 1} - if err := tg.Get(thid); err != nil { - t.Errorf("Unexpected error on TXN Get %v", err) - return err - } - - // Update the data - thid.Name = "bar" - if _, err := tg.Put(thid); err != nil { - t.Errorf("Unexpected error on TXN Put %v", err) - return err - } - - // Concurrent request emulation - // We are running this inside the transaction block to always get the correct timing for testing. - // In the real world, this concurrent request may run in another instance. - // The transaction block may contain multiple other operations after the preceding Put(), - // allowing for ample time for the concurrent request to run before the transaction is committed. - if err := g.Get(hid); err != nil { - t.Errorf("Unexpected error on Get %v", err) - } else if hid.Name != "foo" { - t.Errorf("Expected 'foo', got %v", hid.Name) - } - - // Commit the transaction - return nil - }, &datastore.TransactionOptions{XG: false}); err != nil { - t.Errorf("Unexpected error with TXN - %v", err) - } - - // Clear the local cache, as we are testing for proper memcache usage - g.FlushLocalCache() - - // Get the data back again, to confirm it was changed in the transaction - if err := g.Get(hid); err != nil { - t.Errorf("Unexpected error on Get %v", err) - } else if hid.Name != "bar" { - t.Errorf("Expected 'bar', got %v", hid.Name) - } - - // Clear the local cache, as we are testing for proper memcache usage - g.FlushLocalCache() - - // Delete the test data inside a transction - if err := g.RunInTransaction(func(tg *Goon) error { - thid := &HasId{Id: 1} - if err := tg.Delete(tg.Key(thid)); err != nil { - t.Errorf("Unexpected error on TXN Delete %v", err) - return err - } - - // Concurrent request emulation - if err := g.Get(hid); err != nil { - t.Errorf("Unexpected error on Get %v", err) - } else if hid.Name != "bar" { - t.Errorf("Expected 'bar', got %v", hid.Name) - } - - // Commit the transaction - return nil - }, &datastore.TransactionOptions{XG: false}); err != nil { - t.Errorf("Unexpected error with TXN - %v", err) - } - - // Clear the local cache, as we are testing for proper memcache usage - g.FlushLocalCache() - - // Attempt to get the data back again, to confirm it was deleted in the transaction - if err := g.Get(hid); err != datastore.ErrNoSuchEntity { - t.Errorf("Expected ErrNoSuchEntity, got %v", err) - } -} - -func TestNegativeCacheHit(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - g := FromContext(c) - - hid := &HasId{Id: 1} - - if err := g.Get(hid); err != datastore.ErrNoSuchEntity { - t.Errorf("Expected ErrNoSuchEntity, got %v", err) - } - - // Do a sneaky save straight to the datastore - if _, err := datastore.Put(c, datastore.NewKey(c, "HasId", "", 1, nil), &HasId{Id: 1, Name: "one"}); err != nil { - t.Errorf("Unexpected error on datastore.Put: %v", err) - } - - // Get the entity again via goon, to make sure we cached the non-existance - if err := g.Get(hid); err != datastore.ErrNoSuchEntity { - t.Errorf("Expected ErrNoSuchEntity, got %v", err) - } -} - -func TestCaches(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - g := FromContext(c) - - // Put *struct{} - phid := &HasId{Name: "cacheFail"} - _, err = g.Put(phid) - if err != nil { - t.Errorf("Unexpected error on put - %v", err) - } - - // fetch *struct{} from cache - ghid := &HasId{Id: phid.Id} - err = g.Get(ghid) - if err != nil { - t.Errorf("Unexpected error on get - %v", err) - } - if !reflect.DeepEqual(phid, ghid) { - t.Errorf("Expected - %v, got %v", phid, ghid) - } - - // fetch []struct{} from cache - ghids := []HasId{{Id: phid.Id}} - err = g.GetMulti(&ghids) - if err != nil { - t.Errorf("Unexpected error on get - %v", err) - } - if !reflect.DeepEqual(*phid, ghids[0]) { - t.Errorf("Expected - %v, got %v", *phid, ghids[0]) - } - - // Now flush localcache and fetch them again - g.FlushLocalCache() - // fetch *struct{} from memcache - ghid = &HasId{Id: phid.Id} - err = g.Get(ghid) - if err != nil { - t.Errorf("Unexpected error on get - %v", err) - } - if !reflect.DeepEqual(phid, ghid) { - t.Errorf("Expected - %v, got %v", phid, ghid) - } - - g.FlushLocalCache() - // fetch []struct{} from memcache - ghids = []HasId{{Id: phid.Id}} - err = g.GetMulti(&ghids) - if err != nil { - t.Errorf("Unexpected error on get - %v", err) - } - if !reflect.DeepEqual(*phid, ghids[0]) { - t.Errorf("Expected - %v, got %v", *phid, ghids[0]) - } -} - -func TestGoon(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - n := FromContext(c) - - // Don't want any of these tests to hit the timeout threshold on the devapp server - MemcacheGetTimeout = time.Second - MemcachePutTimeoutLarge = time.Second - MemcachePutTimeoutSmall = time.Second - - // key tests - noid := NoId{} - if k, err := n.KeyError(noid); err == nil && !k.Incomplete() { - t.Error("expected incomplete on noid") - } - if n.Key(noid) == nil { - t.Error("expected to find a key") - } - - var keyTests = []keyTest{ - { - HasDefaultKind{}, - datastore.NewKey(c, "DefaultKind", "", 0, nil), - }, - { - HasId{Id: 1}, - datastore.NewKey(c, "HasId", "", 1, nil), - }, - { - HasKind{Id: 1, Kind: "OtherKind"}, - datastore.NewKey(c, "OtherKind", "", 1, nil), - }, - - { - HasDefaultKind{Id: 1, Kind: "OtherKind"}, - datastore.NewKey(c, "OtherKind", "", 1, nil), - }, - { - HasDefaultKind{Id: 1}, - datastore.NewKey(c, "DefaultKind", "", 1, nil), - }, - { - HasString{Id: "new"}, - datastore.NewKey(c, "HasString", "new", 0, nil), - }, - } - - for _, kt := range keyTests { - if k, err := n.KeyError(kt.obj); err != nil { - t.Errorf("error: %v", err) - } else if !k.Equal(kt.key) { - t.Errorf("keys not equal") - } - } - - if _, err := n.KeyError(TwoId{IntId: 1, StringId: "1"}); err == nil { - t.Errorf("expected key error") - } - - // datastore tests - keys, _ := datastore.NewQuery("HasId").KeysOnly().GetAll(c, nil) - datastore.DeleteMulti(c, keys) - memcache.Flush(c) - if err := n.Get(&HasId{Id: 0}); err == nil { - t.Errorf("ds: expected error, we're fetching from the datastore on an incomplete key!") - } - if err := n.Get(&HasId{Id: 1}); err != datastore.ErrNoSuchEntity { - t.Errorf("ds: expected no such entity") - } - // run twice to make sure autocaching works correctly - if err := n.Get(&HasId{Id: 1}); err != datastore.ErrNoSuchEntity { - t.Errorf("ds: expected no such entity") - } - es := []*HasId{ - {Id: 1, Name: "one"}, - {Id: 2, Name: "two"}, - } - var esk []*datastore.Key - for _, e := range es { - esk = append(esk, n.Key(e)) - } - nes := []*HasId{ - {Id: 1}, - {Id: 2}, - } - if err := n.GetMulti(es); err == nil { - t.Errorf("ds: expected error") - } else if !NotFound(err, 0) { - t.Errorf("ds: not found error 0") - } else if !NotFound(err, 1) { - t.Errorf("ds: not found error 1") - } else if NotFound(err, 2) { - t.Errorf("ds: not found error 2") - } - - if keys, err := n.PutMulti(es); err != nil { - t.Errorf("put: unexpected error") - } else if len(keys) != len(esk) { - t.Errorf("put: got unexpected number of keys") - } else { - for i, k := range keys { - if !k.Equal(esk[i]) { - t.Errorf("put: got unexpected keys") - } - } - } - if err := n.GetMulti(nes); err != nil { - t.Errorf("put: unexpected error") - } else if *es[0] != *nes[0] || *es[1] != *nes[1] { - t.Errorf("put: bad results") - } else { - nesk0 := n.Key(nes[0]) - if !nesk0.Equal(datastore.NewKey(c, "HasId", "", 1, nil)) { - t.Errorf("put: bad key") - } - nesk1 := n.Key(nes[1]) - if !nesk1.Equal(datastore.NewKey(c, "HasId", "", 2, nil)) { - t.Errorf("put: bad key") - } - } - if _, err := n.Put(HasId{Id: 3}); err == nil { - t.Errorf("put: expected error") - } - // force partial fetch from memcache and then datastore - memcache.Flush(c) - if err := n.Get(nes[0]); err != nil { - t.Errorf("get: unexpected error") - } - if err := n.GetMulti(nes); err != nil { - t.Errorf("get: unexpected error") - } - - // put a HasId resource, then test pulling it from memory, memcache, and datastore - hi := &HasId{Name: "hasid"} // no id given, should be automatically created by the datastore - if _, err := n.Put(hi); err != nil { - t.Errorf("put: unexpected error - %v", err) - } - if n.Key(hi) == nil { - t.Errorf("key should not be nil") - } else if n.Key(hi).Incomplete() { - t.Errorf("key should not be incomplete") - } - - hi2 := &HasId{Id: hi.Id} - if err := n.Get(hi2); err != nil { - t.Errorf("get: unexpected error - %v", err) - } - if hi2.Name != hi.Name { - t.Errorf("Could not fetch HasId object from memory - %#v != %#v, memory=%#v", hi, hi2, n.cache[memkey(n.Key(hi2))]) - } - - hi3 := &HasId{Id: hi.Id} - delete(n.cache, memkey(n.Key(hi))) - if err := n.Get(hi3); err != nil { - t.Errorf("get: unexpected error - %v", err) - } - if hi3.Name != hi.Name { - t.Errorf("Could not fetch HasId object from memory - %#v != %#v", hi, hi3) - } - - hi4 := &HasId{Id: hi.Id} - delete(n.cache, memkey(n.Key(hi4))) - if memcache.Flush(n.Context) != nil { - t.Errorf("Unable to flush memcache") - } - if err := n.Get(hi4); err != nil { - t.Errorf("get: unexpected error - %v", err) - } - if hi4.Name != hi.Name { - t.Errorf("Could not fetch HasId object from datastore- %#v != %#v", hi, hi4) - } - - // Now do the opposite also using hi - // Test pulling from local cache and memcache when datastore result is different - // Note that this shouldn't happen with real goon usage, - // but this tests that goon isn't still pulling from the datastore (or memcache) unnecessarily - // hi in datastore Name = hasid - hiPull := &HasId{Id: hi.Id} - n.cacheLock.Lock() - n.cache[memkey(n.Key(hi))].(*HasId).Name = "changedincache" - n.cacheLock.Unlock() - if err := n.Get(hiPull); err != nil { - t.Errorf("get: unexpected error - %v", err) - } - if hiPull.Name != "changedincache" { - t.Errorf("hiPull.Name should be 'changedincache' but got %s", hiPull.Name) - } - - hiPush := &HasId{Id: hi.Id, Name: "changedinmemcache"} - n.putMemcache([]interface{}{hiPush}, []byte{1}) - n.cacheLock.Lock() - delete(n.cache, memkey(n.Key(hi))) - n.cacheLock.Unlock() - - hiPull = &HasId{Id: hi.Id} - if err := n.Get(hiPull); err != nil { - t.Errorf("get: unexpected error - %v", err) - } - if hiPull.Name != "changedinmemcache" { - t.Errorf("hiPull.Name should be 'changedinmemcache' but got %s", hiPull.Name) - } - - // Since the datastore can't assign a key to a String ID, test to make sure goon stops it from happening - hasString := new(HasString) - _, err = n.Put(hasString) - if err == nil { - t.Errorf("Cannot put an incomplete string Id object as the datastore will populate an int64 id instead- %v", hasString) - } - hasString.Id = "hello" - _, err = n.Put(hasString) - if err != nil { - t.Errorf("Error putting hasString object - %v", hasString) - } - - // Test queries! - - // Test that zero result queries work properly - qiZRes := []QueryItem{} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem"), &qiZRes); err != nil { - t.Errorf("GetAll Zero: unexpected error: %v", err) - } else if len(dskeys) != 0 { - t.Errorf("GetAll Zero: expected 0 keys, got %v", len(dskeys)) - } - - // Create some entities that we will query for - if getKeys, err := n.PutMulti([]*QueryItem{{Id: 1, Data: "one"}, {Id: 2, Data: "two"}}); err != nil { - t.Errorf("PutMulti: unexpected error: %v", err) - } else { - // do a datastore Get by *Key so that data is written to the datstore and indexes generated before subsequent query - if err := datastore.GetMulti(c, getKeys, make([]QueryItem, 2)); err != nil { - t.Error(err) - } - } - - // Clear the local memory cache, because we want to test it being filled correctly by GetAll - n.FlushLocalCache() - - // Get the entity using a slice of structs - qiSRes := []QueryItem{} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "one"), &qiSRes); err != nil { - t.Errorf("GetAll SoS: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll SoS: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 1 { - t.Errorf("GetAll SoS: expected key IntID to be 1, got %v", dskeys[0].IntID()) - } else if len(qiSRes) != 1 { - t.Errorf("GetAll SoS: expected 1 result, got %v", len(qiSRes)) - } else if qiSRes[0].Id != 1 { - t.Errorf("GetAll SoS: expected entity id to be 1, got %v", qiSRes[0].Id) - } else if qiSRes[0].Data != "one" { - t.Errorf("GetAll SoS: expected entity data to be 'one', got '%v'", qiSRes[0].Data) - } - - // Get the entity using normal Get to test local cache (provided the local cache actually got saved) - qiS := &QueryItem{Id: 1} - if err := n.Get(qiS); err != nil { - t.Errorf("Get SoS: unexpected error: %v", err) - } else if qiS.Id != 1 { - t.Errorf("Get SoS: expected entity id to be 1, got %v", qiS.Id) - } else if qiS.Data != "one" { - t.Errorf("Get SoS: expected entity data to be 'one', got '%v'", qiS.Data) - } - - // Clear the local memory cache, because we want to test it being filled correctly by GetAll - n.FlushLocalCache() - - // Get the entity using a slice of pointers to struct - qiPRes := []*QueryItem{} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "one"), &qiPRes); err != nil { - t.Errorf("GetAll SoPtS: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll SoPtS: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 1 { - t.Errorf("GetAll SoPtS: expected key IntID to be 1, got %v", dskeys[0].IntID()) - } else if len(qiPRes) != 1 { - t.Errorf("GetAll SoPtS: expected 1 result, got %v", len(qiPRes)) - } else if qiPRes[0].Id != 1 { - t.Errorf("GetAll SoPtS: expected entity id to be 1, got %v", qiPRes[0].Id) - } else if qiPRes[0].Data != "one" { - t.Errorf("GetAll SoPtS: expected entity data to be 'one', got '%v'", qiPRes[0].Data) - } - - // Get the entity using normal Get to test local cache (provided the local cache actually got saved) - qiP := &QueryItem{Id: 1} - if err := n.Get(qiP); err != nil { - t.Errorf("Get SoPtS: unexpected error: %v", err) - } else if qiP.Id != 1 { - t.Errorf("Get SoPtS: expected entity id to be 1, got %v", qiP.Id) - } else if qiP.Data != "one" { - t.Errorf("Get SoPtS: expected entity data to be 'one', got '%v'", qiP.Data) - } - - // Clear the local memory cache, because we want to test it being filled correctly by Next - n.FlushLocalCache() - - // Get the entity using an iterator - qiIt := n.Run(datastore.NewQuery("QueryItem").Filter("data=", "one")) - - qiItRes := &QueryItem{} - if dskey, err := qiIt.Next(qiItRes); err != nil { - t.Errorf("Next: unexpected error: %v", err) - } else if dskey.IntID() != 1 { - t.Errorf("Next: expected key IntID to be 1, got %v", dskey.IntID()) - } else if qiItRes.Id != 1 { - t.Errorf("Next: expected entity id to be 1, got %v", qiItRes.Id) - } else if qiItRes.Data != "one" { - t.Errorf("Next: expected entity data to be 'one', got '%v'", qiItRes.Data) - } - - // Make sure the iterator ends correctly - if _, err := qiIt.Next(&QueryItem{}); err != datastore.Done { - t.Errorf("Next: expected iterator to end with the error datastore.Done, got %v", err) - } - - // Get the entity using normal Get to test local cache (provided the local cache actually got saved) - qiI := &QueryItem{Id: 1} - if err := n.Get(qiI); err != nil { - t.Errorf("Get Iterator: unexpected error: %v", err) - } else if qiI.Id != 1 { - t.Errorf("Get Iterator: expected entity id to be 1, got %v", qiI.Id) - } else if qiI.Data != "one" { - t.Errorf("Get Iterator: expected entity data to be 'one', got '%v'", qiI.Data) - } - - // Clear the local memory cache, because we want to test it not being filled incorrectly when supplying a non-zero slice - n.FlushLocalCache() - - // Get the entity using a non-zero slice of structs - qiNZSRes := []QueryItem{{Id: 1, Data: "invalid cache"}} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "two"), &qiNZSRes); err != nil { - t.Errorf("GetAll NZSoS: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll NZSoS: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 2 { - t.Errorf("GetAll NZSoS: expected key IntID to be 2, got %v", dskeys[0].IntID()) - } else if len(qiNZSRes) != 2 { - t.Errorf("GetAll NZSoS: expected slice len to be 2, got %v", len(qiNZSRes)) - } else if qiNZSRes[0].Id != 1 { - t.Errorf("GetAll NZSoS: expected entity id to be 1, got %v", qiNZSRes[0].Id) - } else if qiNZSRes[0].Data != "invalid cache" { - t.Errorf("GetAll NZSoS: expected entity data to be 'invalid cache', got '%v'", qiNZSRes[0].Data) - } else if qiNZSRes[1].Id != 2 { - t.Errorf("GetAll NZSoS: expected entity id to be 2, got %v", qiNZSRes[1].Id) - } else if qiNZSRes[1].Data != "two" { - t.Errorf("GetAll NZSoS: expected entity data to be 'two', got '%v'", qiNZSRes[1].Data) - } - - // Get the entities using normal GetMulti to test local cache - qiNZSs := []QueryItem{{Id: 1}, {Id: 2}} - if err := n.GetMulti(qiNZSs); err != nil { - t.Errorf("GetMulti NZSoS: unexpected error: %v", err) - } else if len(qiNZSs) != 2 { - t.Errorf("GetMulti NZSoS: expected slice len to be 2, got %v", len(qiNZSs)) - } else if qiNZSs[0].Id != 1 { - t.Errorf("GetMulti NZSoS: expected entity id to be 1, got %v", qiNZSs[0].Id) - } else if qiNZSs[0].Data != "one" { - t.Errorf("GetMulti NZSoS: expected entity data to be 'one', got '%v'", qiNZSs[0].Data) - } else if qiNZSs[1].Id != 2 { - t.Errorf("GetMulti NZSoS: expected entity id to be 2, got %v", qiNZSs[1].Id) - } else if qiNZSs[1].Data != "two" { - t.Errorf("GetMulti NZSoS: expected entity data to be 'two', got '%v'", qiNZSs[1].Data) - } - - // Clear the local memory cache, because we want to test it not being filled incorrectly when supplying a non-zero slice - n.FlushLocalCache() - - // Get the entity using a non-zero slice of pointers to struct - qiNZPRes := []*QueryItem{{Id: 1, Data: "invalid cache"}} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "two"), &qiNZPRes); err != nil { - t.Errorf("GetAll NZSoPtS: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll NZSoPtS: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 2 { - t.Errorf("GetAll NZSoPtS: expected key IntID to be 2, got %v", dskeys[0].IntID()) - } else if len(qiNZPRes) != 2 { - t.Errorf("GetAll NZSoPtS: expected slice len to be 2, got %v", len(qiNZPRes)) - } else if qiNZPRes[0].Id != 1 { - t.Errorf("GetAll NZSoPtS: expected entity id to be 1, got %v", qiNZPRes[0].Id) - } else if qiNZPRes[0].Data != "invalid cache" { - t.Errorf("GetAll NZSoPtS: expected entity data to be 'invalid cache', got '%v'", qiNZPRes[0].Data) - } else if qiNZPRes[1].Id != 2 { - t.Errorf("GetAll NZSoPtS: expected entity id to be 2, got %v", qiNZPRes[1].Id) - } else if qiNZPRes[1].Data != "two" { - t.Errorf("GetAll NZSoPtS: expected entity data to be 'two', got '%v'", qiNZPRes[1].Data) - } - - // Get the entities using normal GetMulti to test local cache - qiNZPs := []*QueryItem{{Id: 1}, {Id: 2}} - if err := n.GetMulti(qiNZPs); err != nil { - t.Errorf("GetMulti NZSoPtS: unexpected error: %v", err) - } else if len(qiNZPs) != 2 { - t.Errorf("GetMulti NZSoPtS: expected slice len to be 2, got %v", len(qiNZPs)) - } else if qiNZPs[0].Id != 1 { - t.Errorf("GetMulti NZSoPtS: expected entity id to be 1, got %v", qiNZPs[0].Id) - } else if qiNZPs[0].Data != "one" { - t.Errorf("GetMulti NZSoPtS: expected entity data to be 'one', got '%v'", qiNZPs[0].Data) - } else if qiNZPs[1].Id != 2 { - t.Errorf("GetMulti NZSoPtS: expected entity id to be 2, got %v", qiNZPs[1].Id) - } else if qiNZPs[1].Data != "two" { - t.Errorf("GetMulti NZSoPtS: expected entity data to be 'two', got '%v'", qiNZPs[1].Data) - } - - // Clear the local memory cache, because we want to test it not being filled incorrectly by a keys-only query - n.FlushLocalCache() - - // Test the simplest keys-only query - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "one").KeysOnly(), nil); err != nil { - t.Errorf("GetAll KeysOnly: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll KeysOnly: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 1 { - t.Errorf("GetAll KeysOnly: expected key IntID to be 1, got %v", dskeys[0].IntID()) - } - - // Get the entity using normal Get to test that the local cache wasn't filled with incomplete data - qiKO := &QueryItem{Id: 1} - if err := n.Get(qiKO); err != nil { - t.Errorf("Get KeysOnly: unexpected error: %v", err) - } else if qiKO.Id != 1 { - t.Errorf("Get KeysOnly: expected entity id to be 1, got %v", qiKO.Id) - } else if qiKO.Data != "one" { - t.Errorf("Get KeysOnly: expected entity data to be 'one', got '%v'", qiKO.Data) - } - - // Clear the local memory cache, because we want to test it not being filled incorrectly by a keys-only query - n.FlushLocalCache() - - // Test the keys-only query with slice of structs - qiKOSRes := []QueryItem{} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "one").KeysOnly(), &qiKOSRes); err != nil { - t.Errorf("GetAll KeysOnly SoS: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll KeysOnly SoS: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 1 { - t.Errorf("GetAll KeysOnly SoS: expected key IntID to be 1, got %v", dskeys[0].IntID()) - } else if len(qiKOSRes) != 1 { - t.Errorf("GetAll KeysOnly SoS: expected 1 result, got %v", len(qiKOSRes)) - } else if k := reflect.TypeOf(qiKOSRes[0]).Kind(); k != reflect.Struct { - t.Errorf("GetAll KeysOnly SoS: expected struct, got %v", k) - } else if qiKOSRes[0].Id != 1 { - t.Errorf("GetAll KeysOnly SoS: expected entity id to be 1, got %v", qiKOSRes[0].Id) - } else if qiKOSRes[0].Data != "" { - t.Errorf("GetAll KeysOnly SoS: expected entity data to be empty, got '%v'", qiKOSRes[0].Data) - } - - // Get the entity using normal Get to test that the local cache wasn't filled with incomplete data - if err := n.GetMulti(qiKOSRes); err != nil { - t.Errorf("Get KeysOnly SoS: unexpected error: %v", err) - } else if qiKOSRes[0].Id != 1 { - t.Errorf("Get KeysOnly SoS: expected entity id to be 1, got %v", qiKOSRes[0].Id) - } else if qiKOSRes[0].Data != "one" { - t.Errorf("Get KeysOnly SoS: expected entity data to be 'one', got '%v'", qiKOSRes[0].Data) - } - - // Clear the local memory cache, because we want to test it not being filled incorrectly by a keys-only query - n.FlushLocalCache() - - // Test the keys-only query with slice of pointers to struct - qiKOPRes := []*QueryItem{} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "one").KeysOnly(), &qiKOPRes); err != nil { - t.Errorf("GetAll KeysOnly SoPtS: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll KeysOnly SoPtS: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 1 { - t.Errorf("GetAll KeysOnly SoPtS: expected key IntID to be 1, got %v", dskeys[0].IntID()) - } else if len(qiKOPRes) != 1 { - t.Errorf("GetAll KeysOnly SoPtS: expected 1 result, got %v", len(qiKOPRes)) - } else if k := reflect.TypeOf(qiKOPRes[0]).Kind(); k != reflect.Ptr { - t.Errorf("GetAll KeysOnly SoPtS: expected pointer, got %v", k) - } else if qiKOPRes[0].Id != 1 { - t.Errorf("GetAll KeysOnly SoPtS: expected entity id to be 1, got %v", qiKOPRes[0].Id) - } else if qiKOPRes[0].Data != "" { - t.Errorf("GetAll KeysOnly SoPtS: expected entity data to be empty, got '%v'", qiKOPRes[0].Data) - } - - // Get the entity using normal Get to test that the local cache wasn't filled with incomplete data - if err := n.GetMulti(qiKOPRes); err != nil { - t.Errorf("Get KeysOnly SoPtS: unexpected error: %v", err) - } else if qiKOPRes[0].Id != 1 { - t.Errorf("Get KeysOnly SoPtS: expected entity id to be 1, got %v", qiKOPRes[0].Id) - } else if qiKOPRes[0].Data != "one" { - t.Errorf("Get KeysOnly SoPtS: expected entity data to be 'one', got '%v'", qiKOPRes[0].Data) - } - - // Clear the local memory cache, because we want to test it not being filled incorrectly when supplying a non-zero slice - n.FlushLocalCache() - - // Test the keys-only query with non-zero slice of structs - qiKONZSRes := []QueryItem{{Id: 1, Data: "invalid cache"}} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "two").KeysOnly(), &qiKONZSRes); err != nil { - t.Errorf("GetAll KeysOnly NZSoS: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll KeysOnly NZSoS: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 2 { - t.Errorf("GetAll KeysOnly NZSoS: expected key IntID to be 2, got %v", dskeys[0].IntID()) - } else if len(qiKONZSRes) != 2 { - t.Errorf("GetAll KeysOnly NZSoS: expected slice len to be 2, got %v", len(qiKONZSRes)) - } else if qiKONZSRes[0].Id != 1 { - t.Errorf("GetAll KeysOnly NZSoS: expected entity id to be 1, got %v", qiKONZSRes[0].Id) - } else if qiKONZSRes[0].Data != "invalid cache" { - t.Errorf("GetAll KeysOnly NZSoS: expected entity data to be 'invalid cache', got '%v'", qiKONZSRes[0].Data) - } else if k := reflect.TypeOf(qiKONZSRes[1]).Kind(); k != reflect.Struct { - t.Errorf("GetAll KeysOnly NZSoS: expected struct, got %v", k) - } else if qiKONZSRes[1].Id != 2 { - t.Errorf("GetAll KeysOnly NZSoS: expected entity id to be 2, got %v", qiKONZSRes[1].Id) - } else if qiKONZSRes[1].Data != "" { - t.Errorf("GetAll KeysOnly NZSoS: expected entity data to be empty, got '%v'", qiKONZSRes[1].Data) - } - - // Get the entities using normal GetMulti to test local cache - if err := n.GetMulti(qiKONZSRes); err != nil { - t.Errorf("GetMulti NZSoS: unexpected error: %v", err) - } else if len(qiKONZSRes) != 2 { - t.Errorf("GetMulti NZSoS: expected slice len to be 2, got %v", len(qiKONZSRes)) - } else if qiKONZSRes[0].Id != 1 { - t.Errorf("GetMulti NZSoS: expected entity id to be 1, got %v", qiKONZSRes[0].Id) - } else if qiKONZSRes[0].Data != "one" { - t.Errorf("GetMulti NZSoS: expected entity data to be 'one', got '%v'", qiKONZSRes[0].Data) - } else if qiKONZSRes[1].Id != 2 { - t.Errorf("GetMulti NZSoS: expected entity id to be 2, got %v", qiKONZSRes[1].Id) - } else if qiKONZSRes[1].Data != "two" { - t.Errorf("GetMulti NZSoS: expected entity data to be 'two', got '%v'", qiKONZSRes[1].Data) - } - - // Clear the local memory cache, because we want to test it not being filled incorrectly when supplying a non-zero slice - n.FlushLocalCache() - - // Test the keys-only query with non-zero slice of pointers to struct - qiKONZPRes := []*QueryItem{{Id: 1, Data: "invalid cache"}} - if dskeys, err := n.GetAll(datastore.NewQuery("QueryItem").Filter("data=", "two").KeysOnly(), &qiKONZPRes); err != nil { - t.Errorf("GetAll KeysOnly NZSoPtS: unexpected error: %v", err) - } else if len(dskeys) != 1 { - t.Errorf("GetAll KeysOnly NZSoPtS: expected 1 key, got %v", len(dskeys)) - } else if dskeys[0].IntID() != 2 { - t.Errorf("GetAll KeysOnly NZSoPtS: expected key IntID to be 2, got %v", dskeys[0].IntID()) - } else if len(qiKONZPRes) != 2 { - t.Errorf("GetAll KeysOnly NZSoPtS: expected slice len to be 2, got %v", len(qiKONZPRes)) - } else if qiKONZPRes[0].Id != 1 { - t.Errorf("GetAll KeysOnly NZSoPtS: expected entity id to be 1, got %v", qiKONZPRes[0].Id) - } else if qiKONZPRes[0].Data != "invalid cache" { - t.Errorf("GetAll KeysOnly NZSoPtS: expected entity data to be 'invalid cache', got '%v'", qiKONZPRes[0].Data) - } else if k := reflect.TypeOf(qiKONZPRes[1]).Kind(); k != reflect.Ptr { - t.Errorf("GetAll KeysOnly NZSoPtS: expected pointer, got %v", k) - } else if qiKONZPRes[1].Id != 2 { - t.Errorf("GetAll KeysOnly NZSoPtS: expected entity id to be 2, got %v", qiKONZPRes[1].Id) - } else if qiKONZPRes[1].Data != "" { - t.Errorf("GetAll KeysOnly NZSoPtS: expected entity data to be empty, got '%v'", qiKONZPRes[1].Data) - } - - // Get the entities using normal GetMulti to test local cache - if err := n.GetMulti(qiKONZPRes); err != nil { - t.Errorf("GetMulti NZSoPtS: unexpected error: %v", err) - } else if len(qiKONZPRes) != 2 { - t.Errorf("GetMulti NZSoPtS: expected slice len to be 2, got %v", len(qiKONZPRes)) - } else if qiKONZPRes[0].Id != 1 { - t.Errorf("GetMulti NZSoPtS: expected entity id to be 1, got %v", qiKONZPRes[0].Id) - } else if qiKONZPRes[0].Data != "one" { - t.Errorf("GetMulti NZSoPtS: expected entity data to be 'one', got '%v'", qiKONZPRes[0].Data) - } else if qiKONZPRes[1].Id != 2 { - t.Errorf("GetMulti NZSoPtS: expected entity id to be 2, got %v", qiKONZPRes[1].Id) - } else if qiKONZPRes[1].Data != "two" { - t.Errorf("GetMulti NZSoPtS: expected entity data to be 'two', got '%v'", qiKONZPRes[1].Data) - } -} - -type keyTest struct { - obj interface{} - key *datastore.Key -} - -type NoId struct { -} - -type HasId struct { - Id int64 `datastore:"-" goon:"id"` - Name string -} - -type HasKind struct { - Id int64 `datastore:"-" goon:"id"` - Kind string `datastore:"-" goon:"kind"` - Name string -} - -type HasDefaultKind struct { - Id int64 `datastore:"-" goon:"id"` - Kind string `datastore:"-" goon:"kind,DefaultKind"` - Name string -} - -type QueryItem struct { - Id int64 `datastore:"-" goon:"id"` - Data string `datastore:"data"` -} - -type HasString struct { - Id string `datastore:"-" goon:"id"` -} - -type TwoId struct { - IntId int64 `goon:"id"` - StringId string `goon:"id"` -} - -type PutGet struct { - ID int64 `datastore:"-" goon:"id"` - Value int32 -} - -// Commenting out for issue https://code.google.com/p/googleappengine/issues/detail?id=10493 -//func TestMemcachePutTimeout(t *testing.T) { -// c, err := aetest.NewContext(nil) -// if err != nil { -// t.Fatalf("Could not start aetest - %v", err) -// } -// defer c.Close() -// g := FromContext(c) -// MemcachePutTimeoutSmall = time.Second -// // put a HasId resource, then test pulling it from memory, memcache, and datastore -// hi := &HasId{Name: "hasid"} // no id given, should be automatically created by the datastore -// if _, err := g.Put(hi); err != nil { -// t.Errorf("put: unexpected error - %v", err) -// } - -// MemcachePutTimeoutSmall = 0 -// MemcacheGetTimeout = 0 -// if err := g.putMemcache([]interface{}{hi}); !appengine.IsTimeoutError(err) { -// t.Errorf("Request should timeout - err = %v", err) -// } -// MemcachePutTimeoutSmall = time.Second -// MemcachePutTimeoutThreshold = 0 -// MemcachePutTimeoutLarge = 0 -// if err := g.putMemcache([]interface{}{hi}); !appengine.IsTimeoutError(err) { -// t.Errorf("Request should timeout - err = %v", err) -// } - -// MemcachePutTimeoutLarge = time.Second -// if err := g.putMemcache([]interface{}{hi}); err != nil { -// t.Errorf("putMemcache: unexpected error - %v", err) -// } - -// g.FlushLocalCache() -// memcache.Flush(c) -// // time out Get -// MemcacheGetTimeout = 0 -// // time out Put too -// MemcachePutTimeoutSmall = 0 -// MemcachePutTimeoutThreshold = 0 -// MemcachePutTimeoutLarge = 0 -// hiResult := &HasId{Id: hi.Id} -// if err := g.Get(hiResult); err != nil { -// t.Errorf("Request should not timeout cause we'll fetch from the datastore but got error %v", err) -// // Put timing out should also error, but it won't be returned here, just logged -// } -// if !reflect.DeepEqual(hi, hiResult) { -// t.Errorf("Fetched object isn't accurate - want %v, fetched %v", hi, hiResult) -// } - -// hiResult = &HasId{Id: hi.Id} -// g.FlushLocalCache() -// MemcacheGetTimeout = time.Second -// if err := g.Get(hiResult); err != nil { -// t.Errorf("Request should not timeout cause we'll fetch from memcache successfully but got error %v", err) -// } -// if !reflect.DeepEqual(hi, hiResult) { -// t.Errorf("Fetched object isn't accurate - want %v, fetched %v", hi, hiResult) -// } -//} - -// This test won't fail but if run with -race flag, it will show known race conditions -// Using multiple goroutines per http request is recommended here: -// http://talks.golang.org/2013/highperf.slide#22 -func TestRace(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - g := FromContext(c) - - var hasIdSlice []*HasId - for x := 1; x <= 4000; x++ { - hasIdSlice = append(hasIdSlice, &HasId{Id: int64(x), Name: "Race"}) - } - _, err = g.PutMulti(hasIdSlice) - if err != nil { - t.Fatalf("Could not put Race entities - %v", err) - } - hasIdSlice = hasIdSlice[:0] - for x := 1; x <= 4000; x++ { - hasIdSlice = append(hasIdSlice, &HasId{Id: int64(x)}) - } - var wg sync.WaitGroup - wg.Add(3) - go func() { - err := g.Get(hasIdSlice[0]) - if err != nil { - t.Errorf("Error fetching id #0 - %v", err) - } - wg.Done() - }() - go func() { - err := g.GetMulti(hasIdSlice[1:1500]) - if err != nil { - t.Errorf("Error fetching ids 1 through 1499 - %v", err) - } - wg.Done() - }() - go func() { - err := g.GetMulti(hasIdSlice[1500:]) - if err != nil { - t.Errorf("Error fetching id #1500 through 4000 - %v", err) - } - wg.Done() - }() - wg.Wait() - for x, hi := range hasIdSlice { - if hi.Name != "Race" { - t.Errorf("Object #%d not fetched properly, fetched instead - %v", x, hi) - } - } -} - -func TestPutGet(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - g := FromContext(c) - - key, err := g.Put(&PutGet{ID: 12, Value: 15}) - if err != nil { - t.Fatal(err) - } - if key.IntID() != 12 { - t.Fatal("ID should be 12 but is", key.IntID()) - } - - // Datastore Get - dsPutGet := &PutGet{} - err = datastore.Get(c, - datastore.NewKey(c, "PutGet", "", 12, nil), dsPutGet) - if err != nil { - t.Fatal(err) - } - if dsPutGet.Value != 15 { - t.Fatal("dsPutGet.Value should be 15 but is", - dsPutGet.Value) - } - - // Goon Get - goonPutGet := &PutGet{ID: 12} - err = g.Get(goonPutGet) - if err != nil { - t.Fatal(err) - } - if goonPutGet.ID != 12 { - t.Fatal("goonPutGet.ID should be 12 but is", goonPutGet.ID) - } - if goonPutGet.Value != 15 { - t.Fatal("goonPutGet.Value should be 15 but is", - goonPutGet.Value) - } -} - -func prefixKindName(src interface{}) string { - return "prefix." + DefaultKindName(src) -} - -func TestCustomKindName(t *testing.T) { - opts := &aetest.Options{StronglyConsistentDatastore: true} - c, err := aetest.NewContext(opts) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - g := FromContext(c) - - hi := HasId{Name: "Foo"} - - //gate - if kind := g.Kind(hi); kind != "HasId" { - t.Fatal("HasId King should not have a prefix, but instead is, ", kind) - } - - g.KindNameResolver = prefixKindName - - if kind := g.Kind(hi); kind != "prefix.HasId" { - t.Fatal("HasId King should have a prefix, but instead is, ", kind) - } - - _, err = g.Put(&hi) - - if err != nil { - t.Fatal("Should be able to put a record: ", err) - } - - reget1 := []HasId{} - query := datastore.NewQuery("prefix.HasId") - query.GetAll(c, ®et1) - - if len(reget1) != 1 { - t.Fatal("Should have 1 record stored in datastore ", reget1) - } - - if reget1[0].Name != "Foo" { - t.Fatal("Name should be Foo ", reget1[0].Name) - } -} - -func TestMultis(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - n := FromContext(c) - - testAmounts := []int{1, 999, 1000, 1001, 1999, 2000, 2001, 2510} - for _, x := range testAmounts { - memcache.Flush(c) - objects := make([]*HasId, x) - for y := 0; y < x; y++ { - objects[y] = &HasId{Id: int64(y + 1)} - } - if _, err := n.PutMulti(objects); err != nil { - t.Fatalf("Error in PutMulti for %d objects - %v", x, err) - } - n.FlushLocalCache() // Put just put them in the local cache, get rid of it before doing the Get - if err := n.GetMulti(objects); err != nil { - t.Fatalf("Error in GetMulti - %v", err) - } - } - - // do it again, but only write numbers divisible by 100 - for _, x := range testAmounts { - memcache.Flush(c) - getobjects := make([]*HasId, 0, x) - putobjects := make([]*HasId, 0, x/100+1) - keys := make([]*datastore.Key, x) - for y := 0; y < x; y++ { - keys[y] = datastore.NewKey(c, "HasId", "", int64(y+1), nil) - } - if err := n.DeleteMulti(keys); err != nil { - t.Fatalf("Error deleting keys - %v", err) - } - for y := 0; y < x; y++ { - getobjects = append(getobjects, &HasId{Id: int64(y + 1)}) - if y%100 == 0 { - putobjects = append(putobjects, &HasId{Id: int64(y + 1)}) - } - } - - _, err := n.PutMulti(putobjects) - if err != nil { - t.Fatalf("Error in PutMulti for %d objects - %v", x, err) - } - n.FlushLocalCache() // Put just put them in the local cache, get rid of it before doing the Get - err = n.GetMulti(getobjects) - if err == nil && x != 1 { // a test size of 1 has no objects divisible by 100, so there's no cache miss to return - t.Errorf("Should be receiving a multiError on %d objects, but got no errors", x) - continue - } - - merr, ok := err.(appengine.MultiError) - if ok { - if len(merr) != len(getobjects) { - t.Errorf("Should have received a MultiError object of length %d but got length %d instead", len(getobjects), len(merr)) - } - for x := range merr { - switch { // record good conditions, fail in other conditions - case merr[x] == nil && x%100 == 0: - case merr[x] != nil && x%100 != 0: - default: - t.Errorf("Found bad condition on object[%d] and error %v", x+1, merr[x]) - } - } - } else if x != 1 { - t.Errorf("Did not return a multierror on fetch but when fetching %d objects, received - %v", x, merr) - } - } -} - -type root struct { - Id int64 `datastore:"-" goon:"id"` - Data int -} - -type normalChild struct { - Id int64 `datastore:"-" goon:"id"` - Parent *datastore.Key `datastore:"-" goon:"parent"` - Data int -} - -type coolKey *datastore.Key - -type derivedChild struct { - Id int64 `datastore:"-" goon:"id"` - Parent coolKey `datastore:"-" goon:"parent"` - Data int -} - -func TestParents(t *testing.T) { - c, err := aetest.NewContext(nil) - if err != nil { - t.Fatalf("Could not start aetest - %v", err) - } - defer c.Close() - n := FromContext(c) - - r := &root{1, 10} - rootKey, err := n.Put(r) - if err != nil { - t.Fatalf("couldn't Put(%+v)", r) - } - - // Put exercises both get and set, since Id is uninitialized - nc := &normalChild{0, rootKey, 20} - nk, err := n.Put(nc) - if err != nil { - t.Fatalf("couldn't Put(%+v)", nc) - } - if nc.Parent == rootKey { - t.Fatalf("derived parent key pointer value didn't change") - } - if !(*datastore.Key)(nc.Parent).Equal(rootKey) { - t.Fatalf("parent of key not equal '%s' v '%s'! ", (*datastore.Key)(nc.Parent), rootKey) - } - if !nk.Parent().Equal(rootKey) { - t.Fatalf("parent of key not equal '%s' v '%s'! ", nk, rootKey) - } - - dc := &derivedChild{0, (coolKey)(rootKey), 12} - dk, err := n.Put(dc) - if err != nil { - t.Fatalf("couldn't Put(%+v)", dc) - } - if dc.Parent == rootKey { - t.Fatalf("derived parent key pointer value didn't change") - } - if !(*datastore.Key)(dc.Parent).Equal(rootKey) { - t.Fatalf("parent of key not equal '%s' v '%s'! ", (*datastore.Key)(dc.Parent), rootKey) - } - if !dk.Parent().Equal(rootKey) { - t.Fatalf("parent of key not equal '%s' v '%s'! ", dk, rootKey) - } -} diff --git a/_third_party/github.com/mjibson/goon/query.go b/_third_party/github.com/mjibson/goon/query.go deleted file mode 100644 index 1b4acca9..00000000 --- a/_third_party/github.com/mjibson/goon/query.go +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2012 Matt Jibson - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package goon - -import ( - "fmt" - "reflect" - - "appengine/datastore" -) - -// Count returns the number of results for the query. -func (g *Goon) Count(q *datastore.Query) (int, error) { - return q.Count(g.Context) -} - -// GetAll runs the query and returns all the keys that match the query, as well -// as appending the values to dst, setting the goon key fields of dst, and -// caching the returned data in local memory. -// -// For "keys-only" queries dst can be nil, however if it is not, then GetAll -// appends zero value structs to dst, only setting the goon key fields. -// No data is cached with "keys-only" queries. -// -// See: https://developers.google.com/appengine/docs/go/datastore/reference#Query.GetAll -func (g *Goon) GetAll(q *datastore.Query, dst interface{}) ([]*datastore.Key, error) { - v := reflect.ValueOf(dst) - vLenBefore := 0 - - if dst != nil { - if v.Kind() != reflect.Ptr { - return nil, fmt.Errorf("goon: Expected dst to be a pointer to a slice or nil, got instead: %v", v.Kind()) - } - - v = v.Elem() - if v.Kind() != reflect.Slice { - return nil, fmt.Errorf("goon: Expected dst to be a pointer to a slice or nil, got instead: %v", v.Kind()) - } - - vLenBefore = v.Len() - } - - keys, err := q.GetAll(g.Context, dst) - if err != nil { - g.error(err) - return nil, err - } - if dst == nil || len(keys) == 0 { - return keys, nil - } - - keysOnly := ((v.Len() - vLenBefore) != len(keys)) - updateCache := !g.inTransaction && !keysOnly - - // If this is a keys-only query, we need to fill the slice with zero value elements - if keysOnly { - elemType := v.Type().Elem() - ptr := false - if elemType.Kind() == reflect.Ptr { - elemType = elemType.Elem() - ptr = true - } - - if elemType.Kind() != reflect.Struct { - return keys, fmt.Errorf("goon: Expected struct, got instead: %v", elemType.Kind()) - } - - for i := 0; i < len(keys); i++ { - ev := reflect.New(elemType) - if !ptr { - ev = ev.Elem() - } - - v.Set(reflect.Append(v, ev)) - } - } - - if updateCache { - g.cacheLock.Lock() - defer g.cacheLock.Unlock() - } - - for i, k := range keys { - var e interface{} - vi := v.Index(vLenBefore + i) - if vi.Kind() == reflect.Ptr { - e = vi.Interface() - } else { - e = vi.Addr().Interface() - } - - if err := g.setStructKey(e, k); err != nil { - return nil, err - } - - if updateCache { - // Cache lock is handled before the for loop - g.cache[memkey(k)] = e - } - } - - return keys, nil -} - -// Run runs the query. -func (g *Goon) Run(q *datastore.Query) *Iterator { - return &Iterator{ - g: g, - i: q.Run(g.Context), - } -} - -// Iterator is the result of running a query. -type Iterator struct { - g *Goon - i *datastore.Iterator -} - -// Cursor returns a cursor for the iterator's current location. -func (t *Iterator) Cursor() (datastore.Cursor, error) { - return t.i.Cursor() -} - -// Next returns the entity of the next result. When there are no more results, -// datastore.Done is returned as the error. If dst is null (for a keys-only -// query), nil is returned as the entity. -// -// If the query is not keys only and dst is non-nil, it also loads the entity -// stored for that key into the struct pointer dst, with the same semantics -// and possible errors as for the Get function. This result is cached in memory. -// -// If the query is keys only, dst must be passed as nil. Otherwise the cache -// will be populated with empty entities since there is no way to detect the -// case of a keys-only query. -// -// Refer to appengine/datastore.Iterator.Next: -// https://developers.google.com/appengine/docs/go/datastore/reference#Iterator.Next -func (t *Iterator) Next(dst interface{}) (*datastore.Key, error) { - k, err := t.i.Next(dst) - if err != nil { - return k, err - } - - if dst != nil { - // Update the struct to have correct key info - t.g.setStructKey(dst, k) - - if !t.g.inTransaction { - t.g.cacheLock.Lock() - t.g.cache[memkey(k)] = dst - t.g.cacheLock.Unlock() - } - } - - return k, err -} diff --git a/_third_party/golang.org/x/net/html/atom/atom.go b/_third_party/golang.org/x/net/html/atom/atom.go deleted file mode 100644 index b064dbcf..00000000 --- a/_third_party/golang.org/x/net/html/atom/atom.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package atom provides integer codes (also known as atoms) for a fixed set of -// frequently occurring HTML strings: tag names and attribute keys such as "p" -// and "id". -// -// Sharing an atom's name between all elements with the same tag can result in -// fewer string allocations when tokenizing and parsing HTML. Integer -// comparisons are also generally faster than string comparisons. -// -// The value of an atom's particular code is not guaranteed to stay the same -// between versions of this package. Neither is any ordering guaranteed: -// whether atom.H1 < atom.H2 may also change. The codes are not guaranteed to -// be dense. The only guarantees are that e.g. looking up "div" will yield -// atom.Div, calling atom.Div.String will return "div", and atom.Div != 0. -package atom // import "github.com/mjibson/goread/_third_party/golang.org/x/net/html/atom" - -// Atom is an integer code for a string. The zero value maps to "". -type Atom uint32 - -// String returns the atom's name. -func (a Atom) String() string { - start := uint32(a >> 8) - n := uint32(a & 0xff) - if start+n > uint32(len(atomText)) { - return "" - } - return atomText[start : start+n] -} - -func (a Atom) string() string { - return atomText[a>>8 : a>>8+a&0xff] -} - -// fnv computes the FNV hash with an arbitrary starting value h. -func fnv(h uint32, s []byte) uint32 { - for i := range s { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -func match(s string, t []byte) bool { - for i, c := range t { - if s[i] != c { - return false - } - } - return true -} - -// Lookup returns the atom whose name is s. It returns zero if there is no -// such atom. The lookup is case sensitive. -func Lookup(s []byte) Atom { - if len(s) == 0 || len(s) > maxAtomLen { - return 0 - } - h := fnv(hash0, s) - if a := table[h&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { - return a - } - if a := table[(h>>16)&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { - return a - } - return 0 -} - -// String returns a string whose contents are equal to s. In that sense, it is -// equivalent to string(s) but may be more efficient. -func String(s []byte) string { - if a := Lookup(s); a != 0 { - return a.String() - } - return string(s) -} diff --git a/_third_party/golang.org/x/net/html/atom/atom_test.go b/_third_party/golang.org/x/net/html/atom/atom_test.go deleted file mode 100644 index 6e33704d..00000000 --- a/_third_party/golang.org/x/net/html/atom/atom_test.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package atom - -import ( - "sort" - "testing" -) - -func TestKnown(t *testing.T) { - for _, s := range testAtomList { - if atom := Lookup([]byte(s)); atom.String() != s { - t.Errorf("Lookup(%q) = %#x (%q)", s, uint32(atom), atom.String()) - } - } -} - -func TestHits(t *testing.T) { - for _, a := range table { - if a == 0 { - continue - } - got := Lookup([]byte(a.String())) - if got != a { - t.Errorf("Lookup(%q) = %#x, want %#x", a.String(), uint32(got), uint32(a)) - } - } -} - -func TestMisses(t *testing.T) { - testCases := []string{ - "", - "\x00", - "\xff", - "A", - "DIV", - "Div", - "dIV", - "aa", - "a\x00", - "ab", - "abb", - "abbr0", - "abbr ", - " abbr", - " a", - "acceptcharset", - "acceptCharset", - "accept_charset", - "h0", - "h1h2", - "h7", - "onClick", - "λ", - // The following string has the same hash (0xa1d7fab7) as "onmouseover". - "\x00\x00\x00\x00\x00\x50\x18\xae\x38\xd0\xb7", - } - for _, tc := range testCases { - got := Lookup([]byte(tc)) - if got != 0 { - t.Errorf("Lookup(%q): got %d, want 0", tc, got) - } - } -} - -func TestForeignObject(t *testing.T) { - const ( - afo = Foreignobject - afO = ForeignObject - sfo = "foreignobject" - sfO = "foreignObject" - ) - if got := Lookup([]byte(sfo)); got != afo { - t.Errorf("Lookup(%q): got %#v, want %#v", sfo, got, afo) - } - if got := Lookup([]byte(sfO)); got != afO { - t.Errorf("Lookup(%q): got %#v, want %#v", sfO, got, afO) - } - if got := afo.String(); got != sfo { - t.Errorf("Atom(%#v).String(): got %q, want %q", afo, got, sfo) - } - if got := afO.String(); got != sfO { - t.Errorf("Atom(%#v).String(): got %q, want %q", afO, got, sfO) - } -} - -func BenchmarkLookup(b *testing.B) { - sortedTable := make([]string, 0, len(table)) - for _, a := range table { - if a != 0 { - sortedTable = append(sortedTable, a.String()) - } - } - sort.Strings(sortedTable) - - x := make([][]byte, 1000) - for i := range x { - x[i] = []byte(sortedTable[i%len(sortedTable)]) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - for _, s := range x { - Lookup(s) - } - } -} diff --git a/_third_party/golang.org/x/net/html/atom/gen.go b/_third_party/golang.org/x/net/html/atom/gen.go deleted file mode 100644 index 6bfa8660..00000000 --- a/_third_party/golang.org/x/net/html/atom/gen.go +++ /dev/null @@ -1,648 +0,0 @@ -// Copyright 2012 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 ignore - -package main - -// This program generates table.go and table_test.go. -// Invoke as -// -// go run gen.go |gofmt >table.go -// go run gen.go -test |gofmt >table_test.go - -import ( - "flag" - "fmt" - "math/rand" - "os" - "sort" - "strings" -) - -// identifier converts s to a Go exported identifier. -// It converts "div" to "Div" and "accept-charset" to "AcceptCharset". -func identifier(s string) string { - b := make([]byte, 0, len(s)) - cap := true - for _, c := range s { - if c == '-' { - cap = true - continue - } - if cap && 'a' <= c && c <= 'z' { - c -= 'a' - 'A' - } - cap = false - b = append(b, byte(c)) - } - return string(b) -} - -var test = flag.Bool("test", false, "generate table_test.go") - -func main() { - flag.Parse() - - var all []string - all = append(all, elements...) - all = append(all, attributes...) - all = append(all, eventHandlers...) - all = append(all, extra...) - sort.Strings(all) - - if *test { - fmt.Printf("// generated by go run gen.go -test; DO NOT EDIT\n\n") - fmt.Printf("package atom\n\n") - fmt.Printf("var testAtomList = []string{\n") - for _, s := range all { - fmt.Printf("\t%q,\n", s) - } - fmt.Printf("}\n") - return - } - - // uniq - lists have dups - // compute max len too - maxLen := 0 - w := 0 - for _, s := range all { - if w == 0 || all[w-1] != s { - if maxLen < len(s) { - maxLen = len(s) - } - all[w] = s - w++ - } - } - all = all[:w] - - // Find hash that minimizes table size. - var best *table - for i := 0; i < 1000000; i++ { - if best != nil && 1<<(best.k-1) < len(all) { - break - } - h := rand.Uint32() - for k := uint(0); k <= 16; k++ { - if best != nil && k >= best.k { - break - } - var t table - if t.init(h, k, all) { - best = &t - break - } - } - } - if best == nil { - fmt.Fprintf(os.Stderr, "failed to construct string table\n") - os.Exit(1) - } - - // Lay out strings, using overlaps when possible. - layout := append([]string{}, all...) - - // Remove strings that are substrings of other strings - for changed := true; changed; { - changed = false - for i, s := range layout { - if s == "" { - continue - } - for j, t := range layout { - if i != j && t != "" && strings.Contains(s, t) { - changed = true - layout[j] = "" - } - } - } - } - - // Join strings where one suffix matches another prefix. - for { - // Find best i, j, k such that layout[i][len-k:] == layout[j][:k], - // maximizing overlap length k. - besti := -1 - bestj := -1 - bestk := 0 - for i, s := range layout { - if s == "" { - continue - } - for j, t := range layout { - if i == j { - continue - } - for k := bestk + 1; k <= len(s) && k <= len(t); k++ { - if s[len(s)-k:] == t[:k] { - besti = i - bestj = j - bestk = k - } - } - } - } - if bestk > 0 { - layout[besti] += layout[bestj][bestk:] - layout[bestj] = "" - continue - } - break - } - - text := strings.Join(layout, "") - - atom := map[string]uint32{} - for _, s := range all { - off := strings.Index(text, s) - if off < 0 { - panic("lost string " + s) - } - atom[s] = uint32(off<<8 | len(s)) - } - - // Generate the Go code. - fmt.Printf("// generated by go run gen.go; DO NOT EDIT\n\n") - fmt.Printf("package atom\n\nconst (\n") - for _, s := range all { - fmt.Printf("\t%s Atom = %#x\n", identifier(s), atom[s]) - } - fmt.Printf(")\n\n") - - fmt.Printf("const hash0 = %#x\n\n", best.h0) - fmt.Printf("const maxAtomLen = %d\n\n", maxLen) - - fmt.Printf("var table = [1<<%d]Atom{\n", best.k) - for i, s := range best.tab { - if s == "" { - continue - } - fmt.Printf("\t%#x: %#x, // %s\n", i, atom[s], s) - } - fmt.Printf("}\n") - datasize := (1 << best.k) * 4 - - fmt.Printf("const atomText =\n") - textsize := len(text) - for len(text) > 60 { - fmt.Printf("\t%q +\n", text[:60]) - text = text[60:] - } - fmt.Printf("\t%q\n\n", text) - - fmt.Fprintf(os.Stderr, "%d atoms; %d string bytes + %d tables = %d total data\n", len(all), textsize, datasize, textsize+datasize) -} - -type byLen []string - -func (x byLen) Less(i, j int) bool { return len(x[i]) > len(x[j]) } -func (x byLen) Swap(i, j int) { x[i], x[j] = x[j], x[i] } -func (x byLen) Len() int { return len(x) } - -// fnv computes the FNV hash with an arbitrary starting value h. -func fnv(h uint32, s string) uint32 { - for i := 0; i < len(s); i++ { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -// A table represents an attempt at constructing the lookup table. -// The lookup table uses cuckoo hashing, meaning that each string -// can be found in one of two positions. -type table struct { - h0 uint32 - k uint - mask uint32 - tab []string -} - -// hash returns the two hashes for s. -func (t *table) hash(s string) (h1, h2 uint32) { - h := fnv(t.h0, s) - h1 = h & t.mask - h2 = (h >> 16) & t.mask - return -} - -// init initializes the table with the given parameters. -// h0 is the initial hash value, -// k is the number of bits of hash value to use, and -// x is the list of strings to store in the table. -// init returns false if the table cannot be constructed. -func (t *table) init(h0 uint32, k uint, x []string) bool { - t.h0 = h0 - t.k = k - t.tab = make([]string, 1< len(t.tab) { - return false - } - s := t.tab[i] - h1, h2 := t.hash(s) - j := h1 + h2 - i - if t.tab[j] != "" && !t.push(j, depth+1) { - return false - } - t.tab[j] = s - return true -} - -// The lists of element names and attribute keys were taken from -// https://html.spec.whatwg.org/multipage/indices.html#index -// as of the "HTML Living Standard - Last Updated 21 February 2015" version. - -var elements = []string{ - "a", - "abbr", - "address", - "area", - "article", - "aside", - "audio", - "b", - "base", - "bdi", - "bdo", - "blockquote", - "body", - "br", - "button", - "canvas", - "caption", - "cite", - "code", - "col", - "colgroup", - "command", - "data", - "datalist", - "dd", - "del", - "details", - "dfn", - "dialog", - "div", - "dl", - "dt", - "em", - "embed", - "fieldset", - "figcaption", - "figure", - "footer", - "form", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "hgroup", - "hr", - "html", - "i", - "iframe", - "img", - "input", - "ins", - "kbd", - "keygen", - "label", - "legend", - "li", - "link", - "map", - "mark", - "menu", - "menuitem", - "meta", - "meter", - "nav", - "noscript", - "object", - "ol", - "optgroup", - "option", - "output", - "p", - "param", - "pre", - "progress", - "q", - "rp", - "rt", - "ruby", - "s", - "samp", - "script", - "section", - "select", - "small", - "source", - "span", - "strong", - "style", - "sub", - "summary", - "sup", - "table", - "tbody", - "td", - "template", - "textarea", - "tfoot", - "th", - "thead", - "time", - "title", - "tr", - "track", - "u", - "ul", - "var", - "video", - "wbr", -} - -// https://html.spec.whatwg.org/multipage/indices.html#attributes-3 - -var attributes = []string{ - "abbr", - "accept", - "accept-charset", - "accesskey", - "action", - "alt", - "async", - "autocomplete", - "autofocus", - "autoplay", - "challenge", - "charset", - "checked", - "cite", - "class", - "cols", - "colspan", - "command", - "content", - "contenteditable", - "contextmenu", - "controls", - "coords", - "crossorigin", - "data", - "datetime", - "default", - "defer", - "dir", - "dirname", - "disabled", - "download", - "draggable", - "dropzone", - "enctype", - "for", - "form", - "formaction", - "formenctype", - "formmethod", - "formnovalidate", - "formtarget", - "headers", - "height", - "hidden", - "high", - "href", - "hreflang", - "http-equiv", - "icon", - "id", - "inputmode", - "ismap", - "itemid", - "itemprop", - "itemref", - "itemscope", - "itemtype", - "keytype", - "kind", - "label", - "lang", - "list", - "loop", - "low", - "manifest", - "max", - "maxlength", - "media", - "mediagroup", - "method", - "min", - "minlength", - "multiple", - "muted", - "name", - "novalidate", - "open", - "optimum", - "pattern", - "ping", - "placeholder", - "poster", - "preload", - "radiogroup", - "readonly", - "rel", - "required", - "reversed", - "rows", - "rowspan", - "sandbox", - "spellcheck", - "scope", - "scoped", - "seamless", - "selected", - "shape", - "size", - "sizes", - "sortable", - "sorted", - "span", - "src", - "srcdoc", - "srclang", - "start", - "step", - "style", - "tabindex", - "target", - "title", - "translate", - "type", - "typemustmatch", - "usemap", - "value", - "width", - "wrap", -} - -var eventHandlers = []string{ - "onabort", - "onautocomplete", - "onautocompleteerror", - "onafterprint", - "onbeforeprint", - "onbeforeunload", - "onblur", - "oncancel", - "oncanplay", - "oncanplaythrough", - "onchange", - "onclick", - "onclose", - "oncontextmenu", - "oncuechange", - "ondblclick", - "ondrag", - "ondragend", - "ondragenter", - "ondragleave", - "ondragover", - "ondragstart", - "ondrop", - "ondurationchange", - "onemptied", - "onended", - "onerror", - "onfocus", - "onhashchange", - "oninput", - "oninvalid", - "onkeydown", - "onkeypress", - "onkeyup", - "onlanguagechange", - "onload", - "onloadeddata", - "onloadedmetadata", - "onloadstart", - "onmessage", - "onmousedown", - "onmousemove", - "onmouseout", - "onmouseover", - "onmouseup", - "onmousewheel", - "onoffline", - "ononline", - "onpagehide", - "onpageshow", - "onpause", - "onplay", - "onplaying", - "onpopstate", - "onprogress", - "onratechange", - "onreset", - "onresize", - "onscroll", - "onseeked", - "onseeking", - "onselect", - "onshow", - "onsort", - "onstalled", - "onstorage", - "onsubmit", - "onsuspend", - "ontimeupdate", - "ontoggle", - "onunload", - "onvolumechange", - "onwaiting", -} - -// extra are ad-hoc values not covered by any of the lists above. -var extra = []string{ - "align", - "annotation", - "annotation-xml", - "applet", - "basefont", - "bgsound", - "big", - "blink", - "center", - "color", - "desc", - "face", - "font", - "foreignObject", // HTML is case-insensitive, but SVG-embedded-in-HTML is case-sensitive. - "foreignobject", - "frame", - "frameset", - "image", - "isindex", - "listing", - "malignmark", - "marquee", - "math", - "mglyph", - "mi", - "mn", - "mo", - "ms", - "mtext", - "nobr", - "noembed", - "noframes", - "plaintext", - "prompt", - "public", - "spacer", - "strike", - "svg", - "system", - "tt", - "xmp", -} diff --git a/_third_party/golang.org/x/net/html/atom/table.go b/_third_party/golang.org/x/net/html/atom/table.go deleted file mode 100644 index 2605ba31..00000000 --- a/_third_party/golang.org/x/net/html/atom/table.go +++ /dev/null @@ -1,713 +0,0 @@ -// generated by go run gen.go; DO NOT EDIT - -package atom - -const ( - A Atom = 0x1 - Abbr Atom = 0x4 - Accept Atom = 0x2106 - AcceptCharset Atom = 0x210e - Accesskey Atom = 0x3309 - Action Atom = 0x1f606 - Address Atom = 0x4f307 - Align Atom = 0x1105 - Alt Atom = 0x4503 - Annotation Atom = 0x1670a - AnnotationXml Atom = 0x1670e - Applet Atom = 0x2b306 - Area Atom = 0x2fa04 - Article Atom = 0x38807 - Aside Atom = 0x8305 - Async Atom = 0x7b05 - Audio Atom = 0xa605 - Autocomplete Atom = 0x1fc0c - Autofocus Atom = 0xb309 - Autoplay Atom = 0xce08 - B Atom = 0x101 - Base Atom = 0xd604 - Basefont Atom = 0xd608 - Bdi Atom = 0x1a03 - Bdo Atom = 0xe703 - Bgsound Atom = 0x11807 - Big Atom = 0x12403 - Blink Atom = 0x12705 - Blockquote Atom = 0x12c0a - Body Atom = 0x2f04 - Br Atom = 0x202 - Button Atom = 0x13606 - Canvas Atom = 0x7f06 - Caption Atom = 0x1bb07 - Center Atom = 0x5b506 - Challenge Atom = 0x21f09 - Charset Atom = 0x2807 - Checked Atom = 0x32807 - Cite Atom = 0x3c804 - Class Atom = 0x4de05 - Code Atom = 0x14904 - Col Atom = 0x15003 - Colgroup Atom = 0x15008 - Color Atom = 0x15d05 - Cols Atom = 0x16204 - Colspan Atom = 0x16207 - Command Atom = 0x17507 - Content Atom = 0x42307 - Contenteditable Atom = 0x4230f - Contextmenu Atom = 0x3310b - Controls Atom = 0x18808 - Coords Atom = 0x19406 - Crossorigin Atom = 0x19f0b - Data Atom = 0x44a04 - Datalist Atom = 0x44a08 - Datetime Atom = 0x23c08 - Dd Atom = 0x26702 - Default Atom = 0x8607 - Defer Atom = 0x14b05 - Del Atom = 0x3ef03 - Desc Atom = 0x4db04 - Details Atom = 0x4807 - Dfn Atom = 0x6103 - Dialog Atom = 0x1b06 - Dir Atom = 0x6903 - Dirname Atom = 0x6907 - Disabled Atom = 0x10c08 - Div Atom = 0x11303 - Dl Atom = 0x11e02 - Download Atom = 0x40008 - Draggable Atom = 0x17b09 - Dropzone Atom = 0x39108 - Dt Atom = 0x50902 - Em Atom = 0x6502 - Embed Atom = 0x6505 - Enctype Atom = 0x21107 - Face Atom = 0x5b304 - Fieldset Atom = 0x1b008 - Figcaption Atom = 0x1b80a - Figure Atom = 0x1cc06 - Font Atom = 0xda04 - Footer Atom = 0x8d06 - For Atom = 0x1d803 - ForeignObject Atom = 0x1d80d - Foreignobject Atom = 0x1e50d - Form Atom = 0x1f204 - Formaction Atom = 0x1f20a - Formenctype Atom = 0x20d0b - Formmethod Atom = 0x2280a - Formnovalidate Atom = 0x2320e - Formtarget Atom = 0x2470a - Frame Atom = 0x9a05 - Frameset Atom = 0x9a08 - H1 Atom = 0x26e02 - H2 Atom = 0x29402 - H3 Atom = 0x2a702 - H4 Atom = 0x2e902 - H5 Atom = 0x2f302 - H6 Atom = 0x50b02 - Head Atom = 0x2d504 - Header Atom = 0x2d506 - Headers Atom = 0x2d507 - Height Atom = 0x25106 - Hgroup Atom = 0x25906 - Hidden Atom = 0x26506 - High Atom = 0x26b04 - Hr Atom = 0x27002 - Href Atom = 0x27004 - Hreflang Atom = 0x27008 - Html Atom = 0x25504 - HttpEquiv Atom = 0x2780a - I Atom = 0x601 - Icon Atom = 0x42204 - Id Atom = 0x8502 - Iframe Atom = 0x29606 - Image Atom = 0x29c05 - Img Atom = 0x2a103 - Input Atom = 0x3e805 - Inputmode Atom = 0x3e809 - Ins Atom = 0x1a803 - Isindex Atom = 0x2a907 - Ismap Atom = 0x2b005 - Itemid Atom = 0x33c06 - Itemprop Atom = 0x3c908 - Itemref Atom = 0x5ad07 - Itemscope Atom = 0x2b909 - Itemtype Atom = 0x2c308 - Kbd Atom = 0x1903 - Keygen Atom = 0x3906 - Keytype Atom = 0x53707 - Kind Atom = 0x10904 - Label Atom = 0xf005 - Lang Atom = 0x27404 - Legend Atom = 0x18206 - Li Atom = 0x1202 - Link Atom = 0x12804 - List Atom = 0x44e04 - Listing Atom = 0x44e07 - Loop Atom = 0xf404 - Low Atom = 0x11f03 - Malignmark Atom = 0x100a - Manifest Atom = 0x5f108 - Map Atom = 0x2b203 - Mark Atom = 0x1604 - Marquee Atom = 0x2cb07 - Math Atom = 0x2d204 - Max Atom = 0x2e103 - Maxlength Atom = 0x2e109 - Media Atom = 0x6e05 - Mediagroup Atom = 0x6e0a - Menu Atom = 0x33804 - Menuitem Atom = 0x33808 - Meta Atom = 0x45d04 - Meter Atom = 0x24205 - Method Atom = 0x22c06 - Mglyph Atom = 0x2a206 - Mi Atom = 0x2eb02 - Min Atom = 0x2eb03 - Minlength Atom = 0x2eb09 - Mn Atom = 0x23502 - Mo Atom = 0x3ed02 - Ms Atom = 0x2bc02 - Mtext Atom = 0x2f505 - Multiple Atom = 0x30308 - Muted Atom = 0x30b05 - Name Atom = 0x6c04 - Nav Atom = 0x3e03 - Nobr Atom = 0x5704 - Noembed Atom = 0x6307 - Noframes Atom = 0x9808 - Noscript Atom = 0x3d208 - Novalidate Atom = 0x2360a - Object Atom = 0x1ec06 - Ol Atom = 0xc902 - Onabort Atom = 0x13a07 - Onafterprint Atom = 0x1c00c - Onautocomplete Atom = 0x1fa0e - Onautocompleteerror Atom = 0x1fa13 - Onbeforeprint Atom = 0x6040d - Onbeforeunload Atom = 0x4e70e - Onblur Atom = 0xaa06 - Oncancel Atom = 0xe908 - Oncanplay Atom = 0x28509 - Oncanplaythrough Atom = 0x28510 - Onchange Atom = 0x3a708 - Onclick Atom = 0x31007 - Onclose Atom = 0x31707 - Oncontextmenu Atom = 0x32f0d - Oncuechange Atom = 0x3420b - Ondblclick Atom = 0x34d0a - Ondrag Atom = 0x35706 - Ondragend Atom = 0x35709 - Ondragenter Atom = 0x3600b - Ondragleave Atom = 0x36b0b - Ondragover Atom = 0x3760a - Ondragstart Atom = 0x3800b - Ondrop Atom = 0x38f06 - Ondurationchange Atom = 0x39f10 - Onemptied Atom = 0x39609 - Onended Atom = 0x3af07 - Onerror Atom = 0x3b607 - Onfocus Atom = 0x3bd07 - Onhashchange Atom = 0x3da0c - Oninput Atom = 0x3e607 - Oninvalid Atom = 0x3f209 - Onkeydown Atom = 0x3fb09 - Onkeypress Atom = 0x4080a - Onkeyup Atom = 0x41807 - Onlanguagechange Atom = 0x43210 - Onload Atom = 0x44206 - Onloadeddata Atom = 0x4420c - Onloadedmetadata Atom = 0x45510 - Onloadstart Atom = 0x46b0b - Onmessage Atom = 0x47609 - Onmousedown Atom = 0x47f0b - Onmousemove Atom = 0x48a0b - Onmouseout Atom = 0x4950a - Onmouseover Atom = 0x4a20b - Onmouseup Atom = 0x4ad09 - Onmousewheel Atom = 0x4b60c - Onoffline Atom = 0x4c209 - Ononline Atom = 0x4cb08 - Onpagehide Atom = 0x4d30a - Onpageshow Atom = 0x4fe0a - Onpause Atom = 0x50d07 - Onplay Atom = 0x51706 - Onplaying Atom = 0x51709 - Onpopstate Atom = 0x5200a - Onprogress Atom = 0x52a0a - Onratechange Atom = 0x53e0c - Onreset Atom = 0x54a07 - Onresize Atom = 0x55108 - Onscroll Atom = 0x55f08 - Onseeked Atom = 0x56708 - Onseeking Atom = 0x56f09 - Onselect Atom = 0x57808 - Onshow Atom = 0x58206 - Onsort Atom = 0x58b06 - Onstalled Atom = 0x59509 - Onstorage Atom = 0x59e09 - Onsubmit Atom = 0x5a708 - Onsuspend Atom = 0x5bb09 - Ontimeupdate Atom = 0xdb0c - Ontoggle Atom = 0x5c408 - Onunload Atom = 0x5cc08 - Onvolumechange Atom = 0x5d40e - Onwaiting Atom = 0x5e209 - Open Atom = 0x3cf04 - Optgroup Atom = 0xf608 - Optimum Atom = 0x5eb07 - Option Atom = 0x60006 - Output Atom = 0x49c06 - P Atom = 0xc01 - Param Atom = 0xc05 - Pattern Atom = 0x5107 - Ping Atom = 0x7704 - Placeholder Atom = 0xc30b - Plaintext Atom = 0xfd09 - Poster Atom = 0x15706 - Pre Atom = 0x25e03 - Preload Atom = 0x25e07 - Progress Atom = 0x52c08 - Prompt Atom = 0x5fa06 - Public Atom = 0x41e06 - Q Atom = 0x13101 - Radiogroup Atom = 0x30a - Readonly Atom = 0x2fb08 - Rel Atom = 0x25f03 - Required Atom = 0x1d008 - Reversed Atom = 0x5a08 - Rows Atom = 0x9204 - Rowspan Atom = 0x9207 - Rp Atom = 0x1c602 - Rt Atom = 0x13f02 - Ruby Atom = 0xaf04 - S Atom = 0x2c01 - Samp Atom = 0x4e04 - Sandbox Atom = 0xbb07 - Scope Atom = 0x2bd05 - Scoped Atom = 0x2bd06 - Script Atom = 0x3d406 - Seamless Atom = 0x31c08 - Section Atom = 0x4e207 - Select Atom = 0x57a06 - Selected Atom = 0x57a08 - Shape Atom = 0x4f905 - Size Atom = 0x55504 - Sizes Atom = 0x55505 - Small Atom = 0x18f05 - Sortable Atom = 0x58d08 - Sorted Atom = 0x19906 - Source Atom = 0x1aa06 - Spacer Atom = 0x2db06 - Span Atom = 0x9504 - Spellcheck Atom = 0x3230a - Src Atom = 0x3c303 - Srcdoc Atom = 0x3c306 - Srclang Atom = 0x41107 - Start Atom = 0x38605 - Step Atom = 0x5f704 - Strike Atom = 0x53306 - Strong Atom = 0x55906 - Style Atom = 0x61105 - Sub Atom = 0x5a903 - Summary Atom = 0x61607 - Sup Atom = 0x61d03 - Svg Atom = 0x62003 - System Atom = 0x62306 - Tabindex Atom = 0x46308 - Table Atom = 0x42d05 - Target Atom = 0x24b06 - Tbody Atom = 0x2e05 - Td Atom = 0x4702 - Template Atom = 0x62608 - Textarea Atom = 0x2f608 - Tfoot Atom = 0x8c05 - Th Atom = 0x22e02 - Thead Atom = 0x2d405 - Time Atom = 0xdd04 - Title Atom = 0xa105 - Tr Atom = 0x10502 - Track Atom = 0x10505 - Translate Atom = 0x14009 - Tt Atom = 0x5302 - Type Atom = 0x21404 - Typemustmatch Atom = 0x2140d - U Atom = 0xb01 - Ul Atom = 0x8a02 - Usemap Atom = 0x51106 - Value Atom = 0x4005 - Var Atom = 0x11503 - Video Atom = 0x28105 - Wbr Atom = 0x12103 - Width Atom = 0x50705 - Wrap Atom = 0x58704 - Xmp Atom = 0xc103 -) - -const hash0 = 0xc17da63e - -const maxAtomLen = 19 - -var table = [1 << 9]Atom{ - 0x1: 0x48a0b, // onmousemove - 0x2: 0x5e209, // onwaiting - 0x3: 0x1fa13, // onautocompleteerror - 0x4: 0x5fa06, // prompt - 0x7: 0x5eb07, // optimum - 0x8: 0x1604, // mark - 0xa: 0x5ad07, // itemref - 0xb: 0x4fe0a, // onpageshow - 0xc: 0x57a06, // select - 0xd: 0x17b09, // draggable - 0xe: 0x3e03, // nav - 0xf: 0x17507, // command - 0x11: 0xb01, // u - 0x14: 0x2d507, // headers - 0x15: 0x44a08, // datalist - 0x17: 0x4e04, // samp - 0x1a: 0x3fb09, // onkeydown - 0x1b: 0x55f08, // onscroll - 0x1c: 0x15003, // col - 0x20: 0x3c908, // itemprop - 0x21: 0x2780a, // http-equiv - 0x22: 0x61d03, // sup - 0x24: 0x1d008, // required - 0x2b: 0x25e07, // preload - 0x2c: 0x6040d, // onbeforeprint - 0x2d: 0x3600b, // ondragenter - 0x2e: 0x50902, // dt - 0x2f: 0x5a708, // onsubmit - 0x30: 0x27002, // hr - 0x31: 0x32f0d, // oncontextmenu - 0x33: 0x29c05, // image - 0x34: 0x50d07, // onpause - 0x35: 0x25906, // hgroup - 0x36: 0x7704, // ping - 0x37: 0x57808, // onselect - 0x3a: 0x11303, // div - 0x3b: 0x1fa0e, // onautocomplete - 0x40: 0x2eb02, // mi - 0x41: 0x31c08, // seamless - 0x42: 0x2807, // charset - 0x43: 0x8502, // id - 0x44: 0x5200a, // onpopstate - 0x45: 0x3ef03, // del - 0x46: 0x2cb07, // marquee - 0x47: 0x3309, // accesskey - 0x49: 0x8d06, // footer - 0x4a: 0x44e04, // list - 0x4b: 0x2b005, // ismap - 0x51: 0x33804, // menu - 0x52: 0x2f04, // body - 0x55: 0x9a08, // frameset - 0x56: 0x54a07, // onreset - 0x57: 0x12705, // blink - 0x58: 0xa105, // title - 0x59: 0x38807, // article - 0x5b: 0x22e02, // th - 0x5d: 0x13101, // q - 0x5e: 0x3cf04, // open - 0x5f: 0x2fa04, // area - 0x61: 0x44206, // onload - 0x62: 0xda04, // font - 0x63: 0xd604, // base - 0x64: 0x16207, // colspan - 0x65: 0x53707, // keytype - 0x66: 0x11e02, // dl - 0x68: 0x1b008, // fieldset - 0x6a: 0x2eb03, // min - 0x6b: 0x11503, // var - 0x6f: 0x2d506, // header - 0x70: 0x13f02, // rt - 0x71: 0x15008, // colgroup - 0x72: 0x23502, // mn - 0x74: 0x13a07, // onabort - 0x75: 0x3906, // keygen - 0x76: 0x4c209, // onoffline - 0x77: 0x21f09, // challenge - 0x78: 0x2b203, // map - 0x7a: 0x2e902, // h4 - 0x7b: 0x3b607, // onerror - 0x7c: 0x2e109, // maxlength - 0x7d: 0x2f505, // mtext - 0x7e: 0xbb07, // sandbox - 0x7f: 0x58b06, // onsort - 0x80: 0x100a, // malignmark - 0x81: 0x45d04, // meta - 0x82: 0x7b05, // async - 0x83: 0x2a702, // h3 - 0x84: 0x26702, // dd - 0x85: 0x27004, // href - 0x86: 0x6e0a, // mediagroup - 0x87: 0x19406, // coords - 0x88: 0x41107, // srclang - 0x89: 0x34d0a, // ondblclick - 0x8a: 0x4005, // value - 0x8c: 0xe908, // oncancel - 0x8e: 0x3230a, // spellcheck - 0x8f: 0x9a05, // frame - 0x91: 0x12403, // big - 0x94: 0x1f606, // action - 0x95: 0x6903, // dir - 0x97: 0x2fb08, // readonly - 0x99: 0x42d05, // table - 0x9a: 0x61607, // summary - 0x9b: 0x12103, // wbr - 0x9c: 0x30a, // radiogroup - 0x9d: 0x6c04, // name - 0x9f: 0x62306, // system - 0xa1: 0x15d05, // color - 0xa2: 0x7f06, // canvas - 0xa3: 0x25504, // html - 0xa5: 0x56f09, // onseeking - 0xac: 0x4f905, // shape - 0xad: 0x25f03, // rel - 0xae: 0x28510, // oncanplaythrough - 0xaf: 0x3760a, // ondragover - 0xb0: 0x62608, // template - 0xb1: 0x1d80d, // foreignObject - 0xb3: 0x9204, // rows - 0xb6: 0x44e07, // listing - 0xb7: 0x49c06, // output - 0xb9: 0x3310b, // contextmenu - 0xbb: 0x11f03, // low - 0xbc: 0x1c602, // rp - 0xbd: 0x5bb09, // onsuspend - 0xbe: 0x13606, // button - 0xbf: 0x4db04, // desc - 0xc1: 0x4e207, // section - 0xc2: 0x52a0a, // onprogress - 0xc3: 0x59e09, // onstorage - 0xc4: 0x2d204, // math - 0xc5: 0x4503, // alt - 0xc7: 0x8a02, // ul - 0xc8: 0x5107, // pattern - 0xc9: 0x4b60c, // onmousewheel - 0xca: 0x35709, // ondragend - 0xcb: 0xaf04, // ruby - 0xcc: 0xc01, // p - 0xcd: 0x31707, // onclose - 0xce: 0x24205, // meter - 0xcf: 0x11807, // bgsound - 0xd2: 0x25106, // height - 0xd4: 0x101, // b - 0xd5: 0x2c308, // itemtype - 0xd8: 0x1bb07, // caption - 0xd9: 0x10c08, // disabled - 0xdb: 0x33808, // menuitem - 0xdc: 0x62003, // svg - 0xdd: 0x18f05, // small - 0xde: 0x44a04, // data - 0xe0: 0x4cb08, // ononline - 0xe1: 0x2a206, // mglyph - 0xe3: 0x6505, // embed - 0xe4: 0x10502, // tr - 0xe5: 0x46b0b, // onloadstart - 0xe7: 0x3c306, // srcdoc - 0xeb: 0x5c408, // ontoggle - 0xed: 0xe703, // bdo - 0xee: 0x4702, // td - 0xef: 0x8305, // aside - 0xf0: 0x29402, // h2 - 0xf1: 0x52c08, // progress - 0xf2: 0x12c0a, // blockquote - 0xf4: 0xf005, // label - 0xf5: 0x601, // i - 0xf7: 0x9207, // rowspan - 0xfb: 0x51709, // onplaying - 0xfd: 0x2a103, // img - 0xfe: 0xf608, // optgroup - 0xff: 0x42307, // content - 0x101: 0x53e0c, // onratechange - 0x103: 0x3da0c, // onhashchange - 0x104: 0x4807, // details - 0x106: 0x40008, // download - 0x109: 0x14009, // translate - 0x10b: 0x4230f, // contenteditable - 0x10d: 0x36b0b, // ondragleave - 0x10e: 0x2106, // accept - 0x10f: 0x57a08, // selected - 0x112: 0x1f20a, // formaction - 0x113: 0x5b506, // center - 0x115: 0x45510, // onloadedmetadata - 0x116: 0x12804, // link - 0x117: 0xdd04, // time - 0x118: 0x19f0b, // crossorigin - 0x119: 0x3bd07, // onfocus - 0x11a: 0x58704, // wrap - 0x11b: 0x42204, // icon - 0x11d: 0x28105, // video - 0x11e: 0x4de05, // class - 0x121: 0x5d40e, // onvolumechange - 0x122: 0xaa06, // onblur - 0x123: 0x2b909, // itemscope - 0x124: 0x61105, // style - 0x127: 0x41e06, // public - 0x129: 0x2320e, // formnovalidate - 0x12a: 0x58206, // onshow - 0x12c: 0x51706, // onplay - 0x12d: 0x3c804, // cite - 0x12e: 0x2bc02, // ms - 0x12f: 0xdb0c, // ontimeupdate - 0x130: 0x10904, // kind - 0x131: 0x2470a, // formtarget - 0x135: 0x3af07, // onended - 0x136: 0x26506, // hidden - 0x137: 0x2c01, // s - 0x139: 0x2280a, // formmethod - 0x13a: 0x3e805, // input - 0x13c: 0x50b02, // h6 - 0x13d: 0xc902, // ol - 0x13e: 0x3420b, // oncuechange - 0x13f: 0x1e50d, // foreignobject - 0x143: 0x4e70e, // onbeforeunload - 0x144: 0x2bd05, // scope - 0x145: 0x39609, // onemptied - 0x146: 0x14b05, // defer - 0x147: 0xc103, // xmp - 0x148: 0x39f10, // ondurationchange - 0x149: 0x1903, // kbd - 0x14c: 0x47609, // onmessage - 0x14d: 0x60006, // option - 0x14e: 0x2eb09, // minlength - 0x14f: 0x32807, // checked - 0x150: 0xce08, // autoplay - 0x152: 0x202, // br - 0x153: 0x2360a, // novalidate - 0x156: 0x6307, // noembed - 0x159: 0x31007, // onclick - 0x15a: 0x47f0b, // onmousedown - 0x15b: 0x3a708, // onchange - 0x15e: 0x3f209, // oninvalid - 0x15f: 0x2bd06, // scoped - 0x160: 0x18808, // controls - 0x161: 0x30b05, // muted - 0x162: 0x58d08, // sortable - 0x163: 0x51106, // usemap - 0x164: 0x1b80a, // figcaption - 0x165: 0x35706, // ondrag - 0x166: 0x26b04, // high - 0x168: 0x3c303, // src - 0x169: 0x15706, // poster - 0x16b: 0x1670e, // annotation-xml - 0x16c: 0x5f704, // step - 0x16d: 0x4, // abbr - 0x16e: 0x1b06, // dialog - 0x170: 0x1202, // li - 0x172: 0x3ed02, // mo - 0x175: 0x1d803, // for - 0x176: 0x1a803, // ins - 0x178: 0x55504, // size - 0x179: 0x43210, // onlanguagechange - 0x17a: 0x8607, // default - 0x17b: 0x1a03, // bdi - 0x17c: 0x4d30a, // onpagehide - 0x17d: 0x6907, // dirname - 0x17e: 0x21404, // type - 0x17f: 0x1f204, // form - 0x181: 0x28509, // oncanplay - 0x182: 0x6103, // dfn - 0x183: 0x46308, // tabindex - 0x186: 0x6502, // em - 0x187: 0x27404, // lang - 0x189: 0x39108, // dropzone - 0x18a: 0x4080a, // onkeypress - 0x18b: 0x23c08, // datetime - 0x18c: 0x16204, // cols - 0x18d: 0x1, // a - 0x18e: 0x4420c, // onloadeddata - 0x190: 0xa605, // audio - 0x192: 0x2e05, // tbody - 0x193: 0x22c06, // method - 0x195: 0xf404, // loop - 0x196: 0x29606, // iframe - 0x198: 0x2d504, // head - 0x19e: 0x5f108, // manifest - 0x19f: 0xb309, // autofocus - 0x1a0: 0x14904, // code - 0x1a1: 0x55906, // strong - 0x1a2: 0x30308, // multiple - 0x1a3: 0xc05, // param - 0x1a6: 0x21107, // enctype - 0x1a7: 0x5b304, // face - 0x1a8: 0xfd09, // plaintext - 0x1a9: 0x26e02, // h1 - 0x1aa: 0x59509, // onstalled - 0x1ad: 0x3d406, // script - 0x1ae: 0x2db06, // spacer - 0x1af: 0x55108, // onresize - 0x1b0: 0x4a20b, // onmouseover - 0x1b1: 0x5cc08, // onunload - 0x1b2: 0x56708, // onseeked - 0x1b4: 0x2140d, // typemustmatch - 0x1b5: 0x1cc06, // figure - 0x1b6: 0x4950a, // onmouseout - 0x1b7: 0x25e03, // pre - 0x1b8: 0x50705, // width - 0x1b9: 0x19906, // sorted - 0x1bb: 0x5704, // nobr - 0x1be: 0x5302, // tt - 0x1bf: 0x1105, // align - 0x1c0: 0x3e607, // oninput - 0x1c3: 0x41807, // onkeyup - 0x1c6: 0x1c00c, // onafterprint - 0x1c7: 0x210e, // accept-charset - 0x1c8: 0x33c06, // itemid - 0x1c9: 0x3e809, // inputmode - 0x1cb: 0x53306, // strike - 0x1cc: 0x5a903, // sub - 0x1cd: 0x10505, // track - 0x1ce: 0x38605, // start - 0x1d0: 0xd608, // basefont - 0x1d6: 0x1aa06, // source - 0x1d7: 0x18206, // legend - 0x1d8: 0x2d405, // thead - 0x1da: 0x8c05, // tfoot - 0x1dd: 0x1ec06, // object - 0x1de: 0x6e05, // media - 0x1df: 0x1670a, // annotation - 0x1e0: 0x20d0b, // formenctype - 0x1e2: 0x3d208, // noscript - 0x1e4: 0x55505, // sizes - 0x1e5: 0x1fc0c, // autocomplete - 0x1e6: 0x9504, // span - 0x1e7: 0x9808, // noframes - 0x1e8: 0x24b06, // target - 0x1e9: 0x38f06, // ondrop - 0x1ea: 0x2b306, // applet - 0x1ec: 0x5a08, // reversed - 0x1f0: 0x2a907, // isindex - 0x1f3: 0x27008, // hreflang - 0x1f5: 0x2f302, // h5 - 0x1f6: 0x4f307, // address - 0x1fa: 0x2e103, // max - 0x1fb: 0xc30b, // placeholder - 0x1fc: 0x2f608, // textarea - 0x1fe: 0x4ad09, // onmouseup - 0x1ff: 0x3800b, // ondragstart -} - -const atomText = "abbradiogrouparamalignmarkbdialogaccept-charsetbodyaccesskey" + - "genavaluealtdetailsampatternobreversedfnoembedirnamediagroup" + - "ingasyncanvasidefaultfooterowspanoframesetitleaudionblurubya" + - "utofocusandboxmplaceholderautoplaybasefontimeupdatebdoncance" + - "labelooptgrouplaintextrackindisabledivarbgsoundlowbrbigblink" + - "blockquotebuttonabortranslatecodefercolgroupostercolorcolspa" + - "nnotation-xmlcommandraggablegendcontrolsmallcoordsortedcross" + - "originsourcefieldsetfigcaptionafterprintfigurequiredforeignO" + - "bjectforeignobjectformactionautocompleteerrorformenctypemust" + - "matchallengeformmethodformnovalidatetimeterformtargetheightm" + - "lhgroupreloadhiddenhigh1hreflanghttp-equivideoncanplaythroug" + - "h2iframeimageimglyph3isindexismappletitemscopeditemtypemarqu" + - "eematheaderspacermaxlength4minlength5mtextareadonlymultiplem" + - "utedonclickoncloseamlesspellcheckedoncontextmenuitemidoncuec" + - "hangeondblclickondragendondragenterondragleaveondragoverondr" + - "agstarticleondropzonemptiedondurationchangeonendedonerroronf" + - "ocusrcdocitempropenoscriptonhashchangeoninputmodeloninvalido" + - "nkeydownloadonkeypressrclangonkeyupublicontenteditableonlang" + - "uagechangeonloadeddatalistingonloadedmetadatabindexonloadsta" + - "rtonmessageonmousedownonmousemoveonmouseoutputonmouseoveronm" + - "ouseuponmousewheelonofflineononlineonpagehidesclassectionbef" + - "oreunloaddresshapeonpageshowidth6onpausemaponplayingonpopsta" + - "teonprogresstrikeytypeonratechangeonresetonresizestrongonscr" + - "ollonseekedonseekingonselectedonshowraponsortableonstalledon" + - "storageonsubmitemrefacenteronsuspendontoggleonunloadonvolume" + - "changeonwaitingoptimumanifestepromptoptionbeforeprintstylesu" + - "mmarysupsvgsystemplate" diff --git a/_third_party/golang.org/x/net/html/atom/table_test.go b/_third_party/golang.org/x/net/html/atom/table_test.go deleted file mode 100644 index 0f2ecce4..00000000 --- a/_third_party/golang.org/x/net/html/atom/table_test.go +++ /dev/null @@ -1,351 +0,0 @@ -// generated by go run gen.go -test; DO NOT EDIT - -package atom - -var testAtomList = []string{ - "a", - "abbr", - "abbr", - "accept", - "accept-charset", - "accesskey", - "action", - "address", - "align", - "alt", - "annotation", - "annotation-xml", - "applet", - "area", - "article", - "aside", - "async", - "audio", - "autocomplete", - "autofocus", - "autoplay", - "b", - "base", - "basefont", - "bdi", - "bdo", - "bgsound", - "big", - "blink", - "blockquote", - "body", - "br", - "button", - "canvas", - "caption", - "center", - "challenge", - "charset", - "checked", - "cite", - "cite", - "class", - "code", - "col", - "colgroup", - "color", - "cols", - "colspan", - "command", - "command", - "content", - "contenteditable", - "contextmenu", - "controls", - "coords", - "crossorigin", - "data", - "data", - "datalist", - "datetime", - "dd", - "default", - "defer", - "del", - "desc", - "details", - "dfn", - "dialog", - "dir", - "dirname", - "disabled", - "div", - "dl", - "download", - "draggable", - "dropzone", - "dt", - "em", - "embed", - "enctype", - "face", - "fieldset", - "figcaption", - "figure", - "font", - "footer", - "for", - "foreignObject", - "foreignobject", - "form", - "form", - "formaction", - "formenctype", - "formmethod", - "formnovalidate", - "formtarget", - "frame", - "frameset", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "headers", - "height", - "hgroup", - "hidden", - "high", - "hr", - "href", - "hreflang", - "html", - "http-equiv", - "i", - "icon", - "id", - "iframe", - "image", - "img", - "input", - "inputmode", - "ins", - "isindex", - "ismap", - "itemid", - "itemprop", - "itemref", - "itemscope", - "itemtype", - "kbd", - "keygen", - "keytype", - "kind", - "label", - "label", - "lang", - "legend", - "li", - "link", - "list", - "listing", - "loop", - "low", - "malignmark", - "manifest", - "map", - "mark", - "marquee", - "math", - "max", - "maxlength", - "media", - "mediagroup", - "menu", - "menuitem", - "meta", - "meter", - "method", - "mglyph", - "mi", - "min", - "minlength", - "mn", - "mo", - "ms", - "mtext", - "multiple", - "muted", - "name", - "nav", - "nobr", - "noembed", - "noframes", - "noscript", - "novalidate", - "object", - "ol", - "onabort", - "onafterprint", - "onautocomplete", - "onautocompleteerror", - "onbeforeprint", - "onbeforeunload", - "onblur", - "oncancel", - "oncanplay", - "oncanplaythrough", - "onchange", - "onclick", - "onclose", - "oncontextmenu", - "oncuechange", - "ondblclick", - "ondrag", - "ondragend", - "ondragenter", - "ondragleave", - "ondragover", - "ondragstart", - "ondrop", - "ondurationchange", - "onemptied", - "onended", - "onerror", - "onfocus", - "onhashchange", - "oninput", - "oninvalid", - "onkeydown", - "onkeypress", - "onkeyup", - "onlanguagechange", - "onload", - "onloadeddata", - "onloadedmetadata", - "onloadstart", - "onmessage", - "onmousedown", - "onmousemove", - "onmouseout", - "onmouseover", - "onmouseup", - "onmousewheel", - "onoffline", - "ononline", - "onpagehide", - "onpageshow", - "onpause", - "onplay", - "onplaying", - "onpopstate", - "onprogress", - "onratechange", - "onreset", - "onresize", - "onscroll", - "onseeked", - "onseeking", - "onselect", - "onshow", - "onsort", - "onstalled", - "onstorage", - "onsubmit", - "onsuspend", - "ontimeupdate", - "ontoggle", - "onunload", - "onvolumechange", - "onwaiting", - "open", - "optgroup", - "optimum", - "option", - "output", - "p", - "param", - "pattern", - "ping", - "placeholder", - "plaintext", - "poster", - "pre", - "preload", - "progress", - "prompt", - "public", - "q", - "radiogroup", - "readonly", - "rel", - "required", - "reversed", - "rows", - "rowspan", - "rp", - "rt", - "ruby", - "s", - "samp", - "sandbox", - "scope", - "scoped", - "script", - "seamless", - "section", - "select", - "selected", - "shape", - "size", - "sizes", - "small", - "sortable", - "sorted", - "source", - "spacer", - "span", - "span", - "spellcheck", - "src", - "srcdoc", - "srclang", - "start", - "step", - "strike", - "strong", - "style", - "style", - "sub", - "summary", - "sup", - "svg", - "system", - "tabindex", - "table", - "target", - "tbody", - "td", - "template", - "textarea", - "tfoot", - "th", - "thead", - "time", - "title", - "title", - "tr", - "track", - "translate", - "tt", - "type", - "typemustmatch", - "u", - "ul", - "usemap", - "value", - "var", - "video", - "wbr", - "width", - "wrap", - "xmp", -} diff --git a/_third_party/golang.org/x/net/html/charset/charset.go b/_third_party/golang.org/x/net/html/charset/charset.go deleted file mode 100644 index 4825a4b3..00000000 --- a/_third_party/golang.org/x/net/html/charset/charset.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package charset provides common text encodings for HTML documents. -// -// The mapping from encoding labels to encodings is defined at -// https://encoding.spec.whatwg.org/. -package charset // import "github.com/mjibson/goread/_third_party/golang.org/x/net/html/charset" - -import ( - "bytes" - "fmt" - "io" - "mime" - "strings" - "unicode/utf8" - - "github.com/mjibson/goread/_third_party/golang.org/x/net/html" - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding" - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding/charmap" - "github.com/mjibson/goread/_third_party/golang.org/x/text/transform" -) - -// Lookup returns the encoding with the specified label, and its canonical -// name. It returns nil and the empty string if label is not one of the -// standard encodings for HTML. Matching is case-insensitive and ignores -// leading and trailing whitespace. -func Lookup(label string) (e encoding.Encoding, name string) { - label = strings.ToLower(strings.Trim(label, "\t\n\r\f ")) - enc := encodings[label] - return enc.e, enc.name -} - -// DetermineEncoding determines the encoding of an HTML document by examining -// up to the first 1024 bytes of content and the declared Content-Type. -// -// See http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#determining-the-character-encoding -func DetermineEncoding(content []byte, contentType string) (e encoding.Encoding, name string, certain bool) { - if len(content) > 1024 { - content = content[:1024] - } - - for _, b := range boms { - if bytes.HasPrefix(content, b.bom) { - e, name = Lookup(b.enc) - return e, name, true - } - } - - if _, params, err := mime.ParseMediaType(contentType); err == nil { - if cs, ok := params["charset"]; ok { - if e, name = Lookup(cs); e != nil { - return e, name, true - } - } - } - - if len(content) > 0 { - e, name = prescan(content) - if e != nil { - return e, name, false - } - } - - // Try to detect UTF-8. - // First eliminate any partial rune at the end. - for i := len(content) - 1; i >= 0 && i > len(content)-4; i-- { - b := content[i] - if b < 0x80 { - break - } - if utf8.RuneStart(b) { - content = content[:i] - break - } - } - hasHighBit := false - for _, c := range content { - if c >= 0x80 { - hasHighBit = true - break - } - } - if hasHighBit && utf8.Valid(content) { - return encoding.Nop, "utf-8", false - } - - // TODO: change default depending on user's locale? - return charmap.Windows1252, "windows-1252", false -} - -// NewReader returns an io.Reader that converts the content of r to UTF-8. -// It calls DetermineEncoding to find out what r's encoding is. -func NewReader(r io.Reader, contentType string) (io.Reader, error) { - preview := make([]byte, 1024) - n, err := io.ReadFull(r, preview) - switch { - case err == io.ErrUnexpectedEOF: - preview = preview[:n] - r = bytes.NewReader(preview) - case err != nil: - return nil, err - default: - r = io.MultiReader(bytes.NewReader(preview), r) - } - - if e, _, _ := DetermineEncoding(preview, contentType); e != encoding.Nop { - r = transform.NewReader(r, e.NewDecoder()) - } - return r, nil -} - -// NewReaderLabel returns a reader that converts from the specified charset to -// UTF-8. It uses Lookup to find the encoding that corresponds to label, and -// returns an error if Lookup returns nil. It is suitable for use as -// encoding/xml.Decoder's CharsetReader function. -func NewReaderLabel(label string, input io.Reader) (io.Reader, error) { - e, _ := Lookup(label) - if e == nil { - return nil, fmt.Errorf("unsupported charset: %q", label) - } - return transform.NewReader(input, e.NewDecoder()), nil -} - -func prescan(content []byte) (e encoding.Encoding, name string) { - z := html.NewTokenizer(bytes.NewReader(content)) - for { - switch z.Next() { - case html.ErrorToken: - return nil, "" - - case html.StartTagToken, html.SelfClosingTagToken: - tagName, hasAttr := z.TagName() - if !bytes.Equal(tagName, []byte("meta")) { - continue - } - attrList := make(map[string]bool) - gotPragma := false - - const ( - dontKnow = iota - doNeedPragma - doNotNeedPragma - ) - needPragma := dontKnow - - name = "" - e = nil - for hasAttr { - var key, val []byte - key, val, hasAttr = z.TagAttr() - ks := string(key) - if attrList[ks] { - continue - } - attrList[ks] = true - for i, c := range val { - if 'A' <= c && c <= 'Z' { - val[i] = c + 0x20 - } - } - - switch ks { - case "http-equiv": - if bytes.Equal(val, []byte("content-type")) { - gotPragma = true - } - - case "content": - if e == nil { - name = fromMetaElement(string(val)) - if name != "" { - e, name = Lookup(name) - if e != nil { - needPragma = doNeedPragma - } - } - } - - case "charset": - e, name = Lookup(string(val)) - needPragma = doNotNeedPragma - } - } - - if needPragma == dontKnow || needPragma == doNeedPragma && !gotPragma { - continue - } - - if strings.HasPrefix(name, "utf-16") { - name = "utf-8" - e = encoding.Nop - } - - if e != nil { - return e, name - } - } - } -} - -func fromMetaElement(s string) string { - for s != "" { - csLoc := strings.Index(s, "charset") - if csLoc == -1 { - return "" - } - s = s[csLoc+len("charset"):] - s = strings.TrimLeft(s, " \t\n\f\r") - if !strings.HasPrefix(s, "=") { - continue - } - s = s[1:] - s = strings.TrimLeft(s, " \t\n\f\r") - if s == "" { - return "" - } - if q := s[0]; q == '"' || q == '\'' { - s = s[1:] - closeQuote := strings.IndexRune(s, rune(q)) - if closeQuote == -1 { - return "" - } - return s[:closeQuote] - } - - end := strings.IndexAny(s, "; \t\n\f\r") - if end == -1 { - end = len(s) - } - return s[:end] - } - return "" -} - -var boms = []struct { - bom []byte - enc string -}{ - {[]byte{0xfe, 0xff}, "utf-16be"}, - {[]byte{0xff, 0xfe}, "utf-16le"}, - {[]byte{0xef, 0xbb, 0xbf}, "utf-8"}, -} diff --git a/_third_party/golang.org/x/net/html/charset/charset_test.go b/_third_party/golang.org/x/net/html/charset/charset_test.go deleted file mode 100644 index 9714256e..00000000 --- a/_third_party/golang.org/x/net/html/charset/charset_test.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package charset - -import ( - "bytes" - "encoding/xml" - "io/ioutil" - "runtime" - "strings" - "testing" - - "github.com/mjibson/goread/_third_party/golang.org/x/text/transform" -) - -func transformString(t transform.Transformer, s string) (string, error) { - r := transform.NewReader(strings.NewReader(s), t) - b, err := ioutil.ReadAll(r) - return string(b), err -} - -var testCases = []struct { - utf8, other, otherEncoding string -}{ - {"Résumé", "Résumé", "utf8"}, - {"Résumé", "R\xe9sum\xe9", "latin1"}, - {"これは漢字です。", "S0\x8c0o0\"oW[g0Y0\x020", "UTF-16LE"}, - {"これは漢字です。", "0S0\x8c0oo\"[W0g0Y0\x02", "UTF-16BE"}, - {"Hello, world", "Hello, world", "ASCII"}, - {"Gdańsk", "Gda\xf1sk", "ISO-8859-2"}, - {"Ââ Čč Đđ Ŋŋ Õõ Šš Žž Åå Ää", "\xc2\xe2 \xc8\xe8 \xa9\xb9 \xaf\xbf \xd5\xf5 \xaa\xba \xac\xbc \xc5\xe5 \xc4\xe4", "ISO-8859-10"}, - {"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "ISO-8859-11"}, - {"latviešu", "latvie\xf0u", "ISO-8859-13"}, - {"Seònaid", "Se\xf2naid", "ISO-8859-14"}, - {"€1 is cheap", "\xa41 is cheap", "ISO-8859-15"}, - {"românește", "rom\xe2ne\xbate", "ISO-8859-16"}, - {"nutraĵo", "nutra\xbco", "ISO-8859-3"}, - {"Kalâdlit", "Kal\xe2dlit", "ISO-8859-4"}, - {"русский", "\xe0\xe3\xe1\xe1\xda\xd8\xd9", "ISO-8859-5"}, - {"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "ISO-8859-7"}, - {"Kağan", "Ka\xf0an", "ISO-8859-9"}, - {"Résumé", "R\x8esum\x8e", "macintosh"}, - {"Gdańsk", "Gda\xf1sk", "windows-1250"}, - {"русский", "\xf0\xf3\xf1\xf1\xea\xe8\xe9", "windows-1251"}, - {"Résumé", "R\xe9sum\xe9", "windows-1252"}, - {"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "windows-1253"}, - {"Kağan", "Ka\xf0an", "windows-1254"}, - {"עִבְרִית", "\xf2\xc4\xe1\xc0\xf8\xc4\xe9\xfa", "windows-1255"}, - {"العربية", "\xc7\xe1\xda\xd1\xc8\xed\xc9", "windows-1256"}, - {"latviešu", "latvie\xf0u", "windows-1257"}, - {"Việt", "Vi\xea\xf2t", "windows-1258"}, - {"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "windows-874"}, - {"русский", "\xd2\xd5\xd3\xd3\xcb\xc9\xca", "KOI8-R"}, - {"українська", "\xd5\xcb\xd2\xc1\xa7\xce\xd3\xd8\xcb\xc1", "KOI8-U"}, - {"Hello 常用國字標準字體表", "Hello \xb1`\xa5\u03b0\xea\xa6r\xbc\u0437\u01e6r\xc5\xe9\xaa\xed", "big5"}, - {"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gbk"}, - {"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gb18030"}, - {"עִבְרִית", "\x81\x30\xfb\x30\x81\x30\xf6\x34\x81\x30\xf9\x33\x81\x30\xf6\x30\x81\x30\xfb\x36\x81\x30\xf6\x34\x81\x30\xfa\x31\x81\x30\xfb\x38", "gb18030"}, - {"㧯", "\x82\x31\x89\x38", "gb18030"}, - {"これは漢字です。", "\x82\xb1\x82\xea\x82\xcd\x8a\xbf\x8e\x9a\x82\xc5\x82\xb7\x81B", "SJIS"}, - {"Hello, 世界!", "Hello, \x90\xa2\x8aE!", "SJIS"}, - {"イウエオカ", "\xb2\xb3\xb4\xb5\xb6", "SJIS"}, - {"これは漢字です。", "\xa4\xb3\xa4\xec\xa4\u03f4\xc1\xbb\xfa\xa4\u01e4\xb9\xa1\xa3", "EUC-JP"}, - {"Hello, 世界!", "Hello, \x1b$B@$3&\x1b(B!", "ISO-2022-JP"}, - {"네이트 | 즐거움의 시작, 슈파스(Spaβ) NATE", "\xb3\xd7\xc0\xcc\xc6\xae | \xc1\xf1\xb0\xc5\xbf\xf2\xc0\xc7 \xbd\xc3\xc0\xdb, \xbd\xb4\xc6\xc4\xbd\xba(Spa\xa5\xe2) NATE", "EUC-KR"}, -} - -func TestDecode(t *testing.T) { - for _, tc := range testCases { - e, _ := Lookup(tc.otherEncoding) - if e == nil { - t.Errorf("%s: not found", tc.otherEncoding) - continue - } - s, err := transformString(e.NewDecoder(), tc.other) - if err != nil { - t.Errorf("%s: decode %q: %v", tc.otherEncoding, tc.other, err) - continue - } - if s != tc.utf8 { - t.Errorf("%s: got %q, want %q", tc.otherEncoding, s, tc.utf8) - } - } -} - -func TestEncode(t *testing.T) { - for _, tc := range testCases { - e, _ := Lookup(tc.otherEncoding) - if e == nil { - t.Errorf("%s: not found", tc.otherEncoding) - continue - } - s, err := transformString(e.NewEncoder(), tc.utf8) - if err != nil { - t.Errorf("%s: encode %q: %s", tc.otherEncoding, tc.utf8, err) - continue - } - if s != tc.other { - t.Errorf("%s: got %q, want %q", tc.otherEncoding, s, tc.other) - } - } -} - -// TestNames verifies that you can pass an encoding's name to Lookup and get -// the same encoding back (except for "replacement"). -func TestNames(t *testing.T) { - for _, e := range encodings { - if e.name == "replacement" { - continue - } - _, got := Lookup(e.name) - if got != e.name { - t.Errorf("got %q, want %q", got, e.name) - continue - } - } -} - -var sniffTestCases = []struct { - filename, declared, want string -}{ - {"HTTP-charset.html", "text/html; charset=iso-8859-15", "iso-8859-15"}, - {"UTF-16LE-BOM.html", "", "utf-16le"}, - {"UTF-16BE-BOM.html", "", "utf-16be"}, - {"meta-content-attribute.html", "text/html", "iso-8859-15"}, - {"meta-charset-attribute.html", "text/html", "iso-8859-15"}, - {"No-encoding-declaration.html", "text/html", "utf-8"}, - {"HTTP-vs-UTF-8-BOM.html", "text/html; charset=iso-8859-15", "utf-8"}, - {"HTTP-vs-meta-content.html", "text/html; charset=iso-8859-15", "iso-8859-15"}, - {"HTTP-vs-meta-charset.html", "text/html; charset=iso-8859-15", "iso-8859-15"}, - {"UTF-8-BOM-vs-meta-content.html", "text/html", "utf-8"}, - {"UTF-8-BOM-vs-meta-charset.html", "text/html", "utf-8"}, -} - -func TestSniff(t *testing.T) { - switch runtime.GOOS { - case "nacl": // platforms that don't permit direct file system access - t.Skipf("not supported on %q", runtime.GOOS) - } - - for _, tc := range sniffTestCases { - content, err := ioutil.ReadFile("testdata/" + tc.filename) - if err != nil { - t.Errorf("%s: error reading file: %v", tc.filename, err) - continue - } - - _, name, _ := DetermineEncoding(content, tc.declared) - if name != tc.want { - t.Errorf("%s: got %q, want %q", tc.filename, name, tc.want) - continue - } - } -} - -func TestReader(t *testing.T) { - switch runtime.GOOS { - case "nacl": // platforms that don't permit direct file system access - t.Skipf("not supported on %q", runtime.GOOS) - } - - for _, tc := range sniffTestCases { - content, err := ioutil.ReadFile("testdata/" + tc.filename) - if err != nil { - t.Errorf("%s: error reading file: %v", tc.filename, err) - continue - } - - r, err := NewReader(bytes.NewReader(content), tc.declared) - if err != nil { - t.Errorf("%s: error creating reader: %v", tc.filename, err) - continue - } - - got, err := ioutil.ReadAll(r) - if err != nil { - t.Errorf("%s: error reading from charset.NewReader: %v", tc.filename, err) - continue - } - - e, _ := Lookup(tc.want) - want, err := ioutil.ReadAll(transform.NewReader(bytes.NewReader(content), e.NewDecoder())) - if err != nil { - t.Errorf("%s: error decoding with hard-coded charset name: %v", tc.filename, err) - continue - } - - if !bytes.Equal(got, want) { - t.Errorf("%s: got %q, want %q", tc.filename, got, want) - continue - } - } -} - -var metaTestCases = []struct { - meta, want string -}{ - {"", ""}, - {"text/html", ""}, - {"text/html; charset utf-8", ""}, - {"text/html; charset=latin-2", "latin-2"}, - {"text/html; charset; charset = utf-8", "utf-8"}, - {`charset="big5"`, "big5"}, - {"charset='shift_jis'", "shift_jis"}, -} - -func TestFromMeta(t *testing.T) { - for _, tc := range metaTestCases { - got := fromMetaElement(tc.meta) - if got != tc.want { - t.Errorf("%q: got %q, want %q", tc.meta, got, tc.want) - } - } -} - -func TestXML(t *testing.T) { - const s = "r\xe9sum\xe9" - - d := xml.NewDecoder(strings.NewReader(s)) - d.CharsetReader = NewReaderLabel - - var a struct { - Word string - } - err := d.Decode(&a) - if err != nil { - t.Fatalf("Decode: %v", err) - } - - want := "résumé" - if a.Word != want { - t.Errorf("got %q, want %q", a.Word, want) - } -} diff --git a/_third_party/golang.org/x/net/html/charset/gen.go b/_third_party/golang.org/x/net/html/charset/gen.go deleted file mode 100644 index 828347f4..00000000 --- a/_third_party/golang.org/x/net/html/charset/gen.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package main - -// Download https://encoding.spec.whatwg.org/encodings.json and use it to -// generate table.go. - -import ( - "encoding/json" - "fmt" - "log" - "net/http" - "strings" -) - -type enc struct { - Name string - Labels []string -} - -type group struct { - Encodings []enc - Heading string -} - -const specURL = "https://encoding.spec.whatwg.org/encodings.json" - -func main() { - resp, err := http.Get(specURL) - if err != nil { - log.Fatalf("error fetching %s: %s", specURL, err) - } - if resp.StatusCode != 200 { - log.Fatalf("error fetching %s: HTTP status %s", specURL, resp.Status) - } - defer resp.Body.Close() - - var groups []group - d := json.NewDecoder(resp.Body) - err = d.Decode(&groups) - if err != nil { - log.Fatalf("error reading encodings.json: %s", err) - } - - fmt.Println("// generated by go run gen.go; DO NOT EDIT") - fmt.Println() - fmt.Println("package charset") - fmt.Println() - - fmt.Println("import (") - fmt.Println(`"golang.org/x/text/encoding"`) - for _, pkg := range []string{"charmap", "japanese", "korean", "simplifiedchinese", "traditionalchinese", "unicode"} { - fmt.Printf("\"golang.org/x/text/encoding/%s\"\n", pkg) - } - fmt.Println(")") - fmt.Println() - - fmt.Println("var encodings = map[string]struct{e encoding.Encoding; name string} {") - for _, g := range groups { - for _, e := range g.Encodings { - goName, ok := miscNames[e.Name] - if !ok { - for k, v := range prefixes { - if strings.HasPrefix(e.Name, k) { - goName = v + e.Name[len(k):] - break - } - } - if goName == "" { - log.Fatalf("unrecognized encoding name: %s", e.Name) - } - } - - for _, label := range e.Labels { - fmt.Printf("%q: {%s, %q},\n", label, goName, e.Name) - } - } - } - fmt.Println("}") -} - -var prefixes = map[string]string{ - "iso-8859-": "charmap.ISO8859_", - "windows-": "charmap.Windows", -} - -var miscNames = map[string]string{ - "utf-8": "encoding.Nop", - "ibm866": "charmap.CodePage866", - "iso-8859-8-i": "charmap.ISO8859_8", - "koi8-r": "charmap.KOI8R", - "koi8-u": "charmap.KOI8U", - "macintosh": "charmap.Macintosh", - "x-mac-cyrillic": "charmap.MacintoshCyrillic", - "gbk": "simplifiedchinese.GBK", - "gb18030": "simplifiedchinese.GB18030", - "hz-gb-2312": "simplifiedchinese.HZGB2312", - "big5": "traditionalchinese.Big5", - "euc-jp": "japanese.EUCJP", - "iso-2022-jp": "japanese.ISO2022JP", - "shift_jis": "japanese.ShiftJIS", - "euc-kr": "korean.EUCKR", - "replacement": "encoding.Replacement", - "utf-16be": "unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM)", - "utf-16le": "unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)", - "x-user-defined": "charmap.XUserDefined", -} diff --git a/_third_party/golang.org/x/net/html/charset/table.go b/_third_party/golang.org/x/net/html/charset/table.go deleted file mode 100644 index eee69634..00000000 --- a/_third_party/golang.org/x/net/html/charset/table.go +++ /dev/null @@ -1,235 +0,0 @@ -// generated by go run gen.go; DO NOT EDIT - -package charset - -import ( - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding" - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding/charmap" - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding/japanese" - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding/korean" - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding/simplifiedchinese" - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding/traditionalchinese" - "github.com/mjibson/goread/_third_party/golang.org/x/text/encoding/unicode" -) - -var encodings = map[string]struct { - e encoding.Encoding - name string -}{ - "unicode-1-1-utf-8": {encoding.Nop, "utf-8"}, - "utf-8": {encoding.Nop, "utf-8"}, - "utf8": {encoding.Nop, "utf-8"}, - "866": {charmap.CodePage866, "ibm866"}, - "cp866": {charmap.CodePage866, "ibm866"}, - "csibm866": {charmap.CodePage866, "ibm866"}, - "ibm866": {charmap.CodePage866, "ibm866"}, - "csisolatin2": {charmap.ISO8859_2, "iso-8859-2"}, - "iso-8859-2": {charmap.ISO8859_2, "iso-8859-2"}, - "iso-ir-101": {charmap.ISO8859_2, "iso-8859-2"}, - "iso8859-2": {charmap.ISO8859_2, "iso-8859-2"}, - "iso88592": {charmap.ISO8859_2, "iso-8859-2"}, - "iso_8859-2": {charmap.ISO8859_2, "iso-8859-2"}, - "iso_8859-2:1987": {charmap.ISO8859_2, "iso-8859-2"}, - "l2": {charmap.ISO8859_2, "iso-8859-2"}, - "latin2": {charmap.ISO8859_2, "iso-8859-2"}, - "csisolatin3": {charmap.ISO8859_3, "iso-8859-3"}, - "iso-8859-3": {charmap.ISO8859_3, "iso-8859-3"}, - "iso-ir-109": {charmap.ISO8859_3, "iso-8859-3"}, - "iso8859-3": {charmap.ISO8859_3, "iso-8859-3"}, - "iso88593": {charmap.ISO8859_3, "iso-8859-3"}, - "iso_8859-3": {charmap.ISO8859_3, "iso-8859-3"}, - "iso_8859-3:1988": {charmap.ISO8859_3, "iso-8859-3"}, - "l3": {charmap.ISO8859_3, "iso-8859-3"}, - "latin3": {charmap.ISO8859_3, "iso-8859-3"}, - "csisolatin4": {charmap.ISO8859_4, "iso-8859-4"}, - "iso-8859-4": {charmap.ISO8859_4, "iso-8859-4"}, - "iso-ir-110": {charmap.ISO8859_4, "iso-8859-4"}, - "iso8859-4": {charmap.ISO8859_4, "iso-8859-4"}, - "iso88594": {charmap.ISO8859_4, "iso-8859-4"}, - "iso_8859-4": {charmap.ISO8859_4, "iso-8859-4"}, - "iso_8859-4:1988": {charmap.ISO8859_4, "iso-8859-4"}, - "l4": {charmap.ISO8859_4, "iso-8859-4"}, - "latin4": {charmap.ISO8859_4, "iso-8859-4"}, - "csisolatincyrillic": {charmap.ISO8859_5, "iso-8859-5"}, - "cyrillic": {charmap.ISO8859_5, "iso-8859-5"}, - "iso-8859-5": {charmap.ISO8859_5, "iso-8859-5"}, - "iso-ir-144": {charmap.ISO8859_5, "iso-8859-5"}, - "iso8859-5": {charmap.ISO8859_5, "iso-8859-5"}, - "iso88595": {charmap.ISO8859_5, "iso-8859-5"}, - "iso_8859-5": {charmap.ISO8859_5, "iso-8859-5"}, - "iso_8859-5:1988": {charmap.ISO8859_5, "iso-8859-5"}, - "arabic": {charmap.ISO8859_6, "iso-8859-6"}, - "asmo-708": {charmap.ISO8859_6, "iso-8859-6"}, - "csiso88596e": {charmap.ISO8859_6, "iso-8859-6"}, - "csiso88596i": {charmap.ISO8859_6, "iso-8859-6"}, - "csisolatinarabic": {charmap.ISO8859_6, "iso-8859-6"}, - "ecma-114": {charmap.ISO8859_6, "iso-8859-6"}, - "iso-8859-6": {charmap.ISO8859_6, "iso-8859-6"}, - "iso-8859-6-e": {charmap.ISO8859_6, "iso-8859-6"}, - "iso-8859-6-i": {charmap.ISO8859_6, "iso-8859-6"}, - "iso-ir-127": {charmap.ISO8859_6, "iso-8859-6"}, - "iso8859-6": {charmap.ISO8859_6, "iso-8859-6"}, - "iso88596": {charmap.ISO8859_6, "iso-8859-6"}, - "iso_8859-6": {charmap.ISO8859_6, "iso-8859-6"}, - "iso_8859-6:1987": {charmap.ISO8859_6, "iso-8859-6"}, - "csisolatingreek": {charmap.ISO8859_7, "iso-8859-7"}, - "ecma-118": {charmap.ISO8859_7, "iso-8859-7"}, - "elot_928": {charmap.ISO8859_7, "iso-8859-7"}, - "greek": {charmap.ISO8859_7, "iso-8859-7"}, - "greek8": {charmap.ISO8859_7, "iso-8859-7"}, - "iso-8859-7": {charmap.ISO8859_7, "iso-8859-7"}, - "iso-ir-126": {charmap.ISO8859_7, "iso-8859-7"}, - "iso8859-7": {charmap.ISO8859_7, "iso-8859-7"}, - "iso88597": {charmap.ISO8859_7, "iso-8859-7"}, - "iso_8859-7": {charmap.ISO8859_7, "iso-8859-7"}, - "iso_8859-7:1987": {charmap.ISO8859_7, "iso-8859-7"}, - "sun_eu_greek": {charmap.ISO8859_7, "iso-8859-7"}, - "csiso88598e": {charmap.ISO8859_8, "iso-8859-8"}, - "csisolatinhebrew": {charmap.ISO8859_8, "iso-8859-8"}, - "hebrew": {charmap.ISO8859_8, "iso-8859-8"}, - "iso-8859-8": {charmap.ISO8859_8, "iso-8859-8"}, - "iso-8859-8-e": {charmap.ISO8859_8, "iso-8859-8"}, - "iso-ir-138": {charmap.ISO8859_8, "iso-8859-8"}, - "iso8859-8": {charmap.ISO8859_8, "iso-8859-8"}, - "iso88598": {charmap.ISO8859_8, "iso-8859-8"}, - "iso_8859-8": {charmap.ISO8859_8, "iso-8859-8"}, - "iso_8859-8:1988": {charmap.ISO8859_8, "iso-8859-8"}, - "visual": {charmap.ISO8859_8, "iso-8859-8"}, - "csiso88598i": {charmap.ISO8859_8, "iso-8859-8-i"}, - "iso-8859-8-i": {charmap.ISO8859_8, "iso-8859-8-i"}, - "logical": {charmap.ISO8859_8, "iso-8859-8-i"}, - "csisolatin6": {charmap.ISO8859_10, "iso-8859-10"}, - "iso-8859-10": {charmap.ISO8859_10, "iso-8859-10"}, - "iso-ir-157": {charmap.ISO8859_10, "iso-8859-10"}, - "iso8859-10": {charmap.ISO8859_10, "iso-8859-10"}, - "iso885910": {charmap.ISO8859_10, "iso-8859-10"}, - "l6": {charmap.ISO8859_10, "iso-8859-10"}, - "latin6": {charmap.ISO8859_10, "iso-8859-10"}, - "iso-8859-13": {charmap.ISO8859_13, "iso-8859-13"}, - "iso8859-13": {charmap.ISO8859_13, "iso-8859-13"}, - "iso885913": {charmap.ISO8859_13, "iso-8859-13"}, - "iso-8859-14": {charmap.ISO8859_14, "iso-8859-14"}, - "iso8859-14": {charmap.ISO8859_14, "iso-8859-14"}, - "iso885914": {charmap.ISO8859_14, "iso-8859-14"}, - "csisolatin9": {charmap.ISO8859_15, "iso-8859-15"}, - "iso-8859-15": {charmap.ISO8859_15, "iso-8859-15"}, - "iso8859-15": {charmap.ISO8859_15, "iso-8859-15"}, - "iso885915": {charmap.ISO8859_15, "iso-8859-15"}, - "iso_8859-15": {charmap.ISO8859_15, "iso-8859-15"}, - "l9": {charmap.ISO8859_15, "iso-8859-15"}, - "iso-8859-16": {charmap.ISO8859_16, "iso-8859-16"}, - "cskoi8r": {charmap.KOI8R, "koi8-r"}, - "koi": {charmap.KOI8R, "koi8-r"}, - "koi8": {charmap.KOI8R, "koi8-r"}, - "koi8-r": {charmap.KOI8R, "koi8-r"}, - "koi8_r": {charmap.KOI8R, "koi8-r"}, - "koi8-u": {charmap.KOI8U, "koi8-u"}, - "csmacintosh": {charmap.Macintosh, "macintosh"}, - "mac": {charmap.Macintosh, "macintosh"}, - "macintosh": {charmap.Macintosh, "macintosh"}, - "x-mac-roman": {charmap.Macintosh, "macintosh"}, - "dos-874": {charmap.Windows874, "windows-874"}, - "iso-8859-11": {charmap.Windows874, "windows-874"}, - "iso8859-11": {charmap.Windows874, "windows-874"}, - "iso885911": {charmap.Windows874, "windows-874"}, - "tis-620": {charmap.Windows874, "windows-874"}, - "windows-874": {charmap.Windows874, "windows-874"}, - "cp1250": {charmap.Windows1250, "windows-1250"}, - "windows-1250": {charmap.Windows1250, "windows-1250"}, - "x-cp1250": {charmap.Windows1250, "windows-1250"}, - "cp1251": {charmap.Windows1251, "windows-1251"}, - "windows-1251": {charmap.Windows1251, "windows-1251"}, - "x-cp1251": {charmap.Windows1251, "windows-1251"}, - "ansi_x3.4-1968": {charmap.Windows1252, "windows-1252"}, - "ascii": {charmap.Windows1252, "windows-1252"}, - "cp1252": {charmap.Windows1252, "windows-1252"}, - "cp819": {charmap.Windows1252, "windows-1252"}, - "csisolatin1": {charmap.Windows1252, "windows-1252"}, - "ibm819": {charmap.Windows1252, "windows-1252"}, - "iso-8859-1": {charmap.Windows1252, "windows-1252"}, - "iso-ir-100": {charmap.Windows1252, "windows-1252"}, - "iso8859-1": {charmap.Windows1252, "windows-1252"}, - "iso88591": {charmap.Windows1252, "windows-1252"}, - "iso_8859-1": {charmap.Windows1252, "windows-1252"}, - "iso_8859-1:1987": {charmap.Windows1252, "windows-1252"}, - "l1": {charmap.Windows1252, "windows-1252"}, - "latin1": {charmap.Windows1252, "windows-1252"}, - "us-ascii": {charmap.Windows1252, "windows-1252"}, - "windows-1252": {charmap.Windows1252, "windows-1252"}, - "x-cp1252": {charmap.Windows1252, "windows-1252"}, - "cp1253": {charmap.Windows1253, "windows-1253"}, - "windows-1253": {charmap.Windows1253, "windows-1253"}, - "x-cp1253": {charmap.Windows1253, "windows-1253"}, - "cp1254": {charmap.Windows1254, "windows-1254"}, - "csisolatin5": {charmap.Windows1254, "windows-1254"}, - "iso-8859-9": {charmap.Windows1254, "windows-1254"}, - "iso-ir-148": {charmap.Windows1254, "windows-1254"}, - "iso8859-9": {charmap.Windows1254, "windows-1254"}, - "iso88599": {charmap.Windows1254, "windows-1254"}, - "iso_8859-9": {charmap.Windows1254, "windows-1254"}, - "iso_8859-9:1989": {charmap.Windows1254, "windows-1254"}, - "l5": {charmap.Windows1254, "windows-1254"}, - "latin5": {charmap.Windows1254, "windows-1254"}, - "windows-1254": {charmap.Windows1254, "windows-1254"}, - "x-cp1254": {charmap.Windows1254, "windows-1254"}, - "cp1255": {charmap.Windows1255, "windows-1255"}, - "windows-1255": {charmap.Windows1255, "windows-1255"}, - "x-cp1255": {charmap.Windows1255, "windows-1255"}, - "cp1256": {charmap.Windows1256, "windows-1256"}, - "windows-1256": {charmap.Windows1256, "windows-1256"}, - "x-cp1256": {charmap.Windows1256, "windows-1256"}, - "cp1257": {charmap.Windows1257, "windows-1257"}, - "windows-1257": {charmap.Windows1257, "windows-1257"}, - "x-cp1257": {charmap.Windows1257, "windows-1257"}, - "cp1258": {charmap.Windows1258, "windows-1258"}, - "windows-1258": {charmap.Windows1258, "windows-1258"}, - "x-cp1258": {charmap.Windows1258, "windows-1258"}, - "x-mac-cyrillic": {charmap.MacintoshCyrillic, "x-mac-cyrillic"}, - "x-mac-ukrainian": {charmap.MacintoshCyrillic, "x-mac-cyrillic"}, - "chinese": {simplifiedchinese.GBK, "gbk"}, - "csgb2312": {simplifiedchinese.GBK, "gbk"}, - "csiso58gb231280": {simplifiedchinese.GBK, "gbk"}, - "gb2312": {simplifiedchinese.GBK, "gbk"}, - "gb_2312": {simplifiedchinese.GBK, "gbk"}, - "gb_2312-80": {simplifiedchinese.GBK, "gbk"}, - "gbk": {simplifiedchinese.GBK, "gbk"}, - "iso-ir-58": {simplifiedchinese.GBK, "gbk"}, - "x-gbk": {simplifiedchinese.GBK, "gbk"}, - "gb18030": {simplifiedchinese.GB18030, "gb18030"}, - "hz-gb-2312": {simplifiedchinese.HZGB2312, "hz-gb-2312"}, - "big5": {traditionalchinese.Big5, "big5"}, - "big5-hkscs": {traditionalchinese.Big5, "big5"}, - "cn-big5": {traditionalchinese.Big5, "big5"}, - "csbig5": {traditionalchinese.Big5, "big5"}, - "x-x-big5": {traditionalchinese.Big5, "big5"}, - "cseucpkdfmtjapanese": {japanese.EUCJP, "euc-jp"}, - "euc-jp": {japanese.EUCJP, "euc-jp"}, - "x-euc-jp": {japanese.EUCJP, "euc-jp"}, - "csiso2022jp": {japanese.ISO2022JP, "iso-2022-jp"}, - "iso-2022-jp": {japanese.ISO2022JP, "iso-2022-jp"}, - "csshiftjis": {japanese.ShiftJIS, "shift_jis"}, - "ms_kanji": {japanese.ShiftJIS, "shift_jis"}, - "shift-jis": {japanese.ShiftJIS, "shift_jis"}, - "shift_jis": {japanese.ShiftJIS, "shift_jis"}, - "sjis": {japanese.ShiftJIS, "shift_jis"}, - "windows-31j": {japanese.ShiftJIS, "shift_jis"}, - "x-sjis": {japanese.ShiftJIS, "shift_jis"}, - "cseuckr": {korean.EUCKR, "euc-kr"}, - "csksc56011987": {korean.EUCKR, "euc-kr"}, - "euc-kr": {korean.EUCKR, "euc-kr"}, - "iso-ir-149": {korean.EUCKR, "euc-kr"}, - "korean": {korean.EUCKR, "euc-kr"}, - "ks_c_5601-1987": {korean.EUCKR, "euc-kr"}, - "ks_c_5601-1989": {korean.EUCKR, "euc-kr"}, - "ksc5601": {korean.EUCKR, "euc-kr"}, - "ksc_5601": {korean.EUCKR, "euc-kr"}, - "windows-949": {korean.EUCKR, "euc-kr"}, - "csiso2022kr": {encoding.Replacement, "replacement"}, - "iso-2022-kr": {encoding.Replacement, "replacement"}, - "iso-2022-cn": {encoding.Replacement, "replacement"}, - "iso-2022-cn-ext": {encoding.Replacement, "replacement"}, - "utf-16be": {unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM), "utf-16be"}, - "utf-16": {unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM), "utf-16le"}, - "utf-16le": {unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM), "utf-16le"}, - "x-user-defined": {charmap.XUserDefined, "x-user-defined"}, -} diff --git a/_third_party/golang.org/x/net/html/const.go b/_third_party/golang.org/x/net/html/const.go deleted file mode 100644 index 52f651ff..00000000 --- a/_third_party/golang.org/x/net/html/const.go +++ /dev/null @@ -1,102 +0,0 @@ -// 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. - -package html - -// Section 12.2.3.2 of the HTML5 specification says "The following elements -// have varying levels of special parsing rules". -// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements -var isSpecialElementMap = map[string]bool{ - "address": true, - "applet": true, - "area": true, - "article": true, - "aside": true, - "base": true, - "basefont": true, - "bgsound": true, - "blockquote": true, - "body": true, - "br": true, - "button": true, - "caption": true, - "center": true, - "col": true, - "colgroup": true, - "dd": true, - "details": true, - "dir": true, - "div": true, - "dl": true, - "dt": true, - "embed": true, - "fieldset": true, - "figcaption": true, - "figure": true, - "footer": true, - "form": true, - "frame": true, - "frameset": true, - "h1": true, - "h2": true, - "h3": true, - "h4": true, - "h5": true, - "h6": true, - "head": true, - "header": true, - "hgroup": true, - "hr": true, - "html": true, - "iframe": true, - "img": true, - "input": true, - "isindex": true, - "li": true, - "link": true, - "listing": true, - "marquee": true, - "menu": true, - "meta": true, - "nav": true, - "noembed": true, - "noframes": true, - "noscript": true, - "object": true, - "ol": true, - "p": true, - "param": true, - "plaintext": true, - "pre": true, - "script": true, - "section": true, - "select": true, - "source": true, - "style": true, - "summary": true, - "table": true, - "tbody": true, - "td": true, - "template": true, - "textarea": true, - "tfoot": true, - "th": true, - "thead": true, - "title": true, - "tr": true, - "track": true, - "ul": true, - "wbr": true, - "xmp": true, -} - -func isSpecialElement(element *Node) bool { - switch element.Namespace { - case "", "html": - return isSpecialElementMap[element.Data] - case "svg": - return element.Data == "foreignObject" - } - return false -} diff --git a/_third_party/golang.org/x/net/html/doc.go b/_third_party/golang.org/x/net/html/doc.go deleted file mode 100644 index 05abc977..00000000 --- a/_third_party/golang.org/x/net/html/doc.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package html implements an HTML5-compliant tokenizer and parser. - -Tokenization is done by creating a Tokenizer for an io.Reader r. It is the -caller's responsibility to ensure that r provides UTF-8 encoded HTML. - - z := html.NewTokenizer(r) - -Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(), -which parses the next token and returns its type, or an error: - - for { - tt := z.Next() - if tt == html.ErrorToken { - // ... - return ... - } - // Process the current token. - } - -There are two APIs for retrieving the current token. The high-level API is to -call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs -allow optionally calling Raw after Next but before Token, Text, TagName, or -TagAttr. In EBNF notation, the valid call sequence per token is: - - Next {Raw} [ Token | Text | TagName {TagAttr} ] - -Token returns an independent data structure that completely describes a token. -Entities (such as "<") are unescaped, tag names and attribute keys are -lower-cased, and attributes are collected into a []Attribute. For example: - - for { - if z.Next() == html.ErrorToken { - // Returning io.EOF indicates success. - return z.Err() - } - emitToken(z.Token()) - } - -The low-level API performs fewer allocations and copies, but the contents of -the []byte values returned by Text, TagName and TagAttr may change on the next -call to Next. For example, to extract an HTML page's anchor text: - - depth := 0 - for { - tt := z.Next() - switch tt { - case ErrorToken: - return z.Err() - case TextToken: - if depth > 0 { - // emitBytes should copy the []byte it receives, - // if it doesn't process it immediately. - emitBytes(z.Text()) - } - case StartTagToken, EndTagToken: - tn, _ := z.TagName() - if len(tn) == 1 && tn[0] == 'a' { - if tt == StartTagToken { - depth++ - } else { - depth-- - } - } - } - } - -Parsing is done by calling Parse with an io.Reader, which returns the root of -the parse tree (the document element) as a *Node. It is the caller's -responsibility to ensure that the Reader provides UTF-8 encoded HTML. For -example, to process each anchor node in depth-first order: - - doc, err := html.Parse(r) - if err != nil { - // ... - } - var f func(*html.Node) - f = func(n *html.Node) { - if n.Type == html.ElementNode && n.Data == "a" { - // Do something with n... - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - f(c) - } - } - f(doc) - -The relevant specifications include: -https://html.spec.whatwg.org/multipage/syntax.html and -https://html.spec.whatwg.org/multipage/syntax.html#tokenization -*/ -package html // import "github.com/mjibson/goread/_third_party/golang.org/x/net/html" - -// The tokenization algorithm implemented by this package is not a line-by-line -// transliteration of the relatively verbose state-machine in the WHATWG -// specification. A more direct approach is used instead, where the program -// counter implies the state, such as whether it is tokenizing a tag or a text -// node. Specification compliance is verified by checking expected and actual -// outputs over a test suite rather than aiming for algorithmic fidelity. - -// TODO(nigeltao): Does a DOM API belong in this package or a separate one? -// TODO(nigeltao): How does parsing interact with a JavaScript engine? diff --git a/_third_party/golang.org/x/net/html/doctype.go b/_third_party/golang.org/x/net/html/doctype.go deleted file mode 100644 index c484e5a9..00000000 --- a/_third_party/golang.org/x/net/html/doctype.go +++ /dev/null @@ -1,156 +0,0 @@ -// 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. - -package html - -import ( - "strings" -) - -// parseDoctype parses the data from a DoctypeToken into a name, -// public identifier, and system identifier. It returns a Node whose Type -// is DoctypeNode, whose Data is the name, and which has attributes -// named "system" and "public" for the two identifiers if they were present. -// quirks is whether the document should be parsed in "quirks mode". -func parseDoctype(s string) (n *Node, quirks bool) { - n = &Node{Type: DoctypeNode} - - // Find the name. - space := strings.IndexAny(s, whitespace) - if space == -1 { - space = len(s) - } - n.Data = s[:space] - // The comparison to "html" is case-sensitive. - if n.Data != "html" { - quirks = true - } - n.Data = strings.ToLower(n.Data) - s = strings.TrimLeft(s[space:], whitespace) - - if len(s) < 6 { - // It can't start with "PUBLIC" or "SYSTEM". - // Ignore the rest of the string. - return n, quirks || s != "" - } - - key := strings.ToLower(s[:6]) - s = s[6:] - for key == "public" || key == "system" { - s = strings.TrimLeft(s, whitespace) - if s == "" { - break - } - quote := s[0] - if quote != '"' && quote != '\'' { - break - } - s = s[1:] - q := strings.IndexRune(s, rune(quote)) - var id string - if q == -1 { - id = s - s = "" - } else { - id = s[:q] - s = s[q+1:] - } - n.Attr = append(n.Attr, Attribute{Key: key, Val: id}) - if key == "public" { - key = "system" - } else { - key = "" - } - } - - if key != "" || s != "" { - quirks = true - } else if len(n.Attr) > 0 { - if n.Attr[0].Key == "public" { - public := strings.ToLower(n.Attr[0].Val) - switch public { - case "-//w3o//dtd w3 html strict 3.0//en//", "-/w3d/dtd html 4.0 transitional/en", "html": - quirks = true - default: - for _, q := range quirkyIDs { - if strings.HasPrefix(public, q) { - quirks = true - break - } - } - } - // The following two public IDs only cause quirks mode if there is no system ID. - if len(n.Attr) == 1 && (strings.HasPrefix(public, "-//w3c//dtd html 4.01 frameset//") || - strings.HasPrefix(public, "-//w3c//dtd html 4.01 transitional//")) { - quirks = true - } - } - if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" && - strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" { - quirks = true - } - } - - return n, quirks -} - -// quirkyIDs is a list of public doctype identifiers that cause a document -// to be interpreted in quirks mode. The identifiers should be in lower case. -var quirkyIDs = []string{ - "+//silmaril//dtd html pro v0r11 19970101//", - "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", - "-//as//dtd html 3.0 aswedit + extensions//", - "-//ietf//dtd html 2.0 level 1//", - "-//ietf//dtd html 2.0 level 2//", - "-//ietf//dtd html 2.0 strict level 1//", - "-//ietf//dtd html 2.0 strict level 2//", - "-//ietf//dtd html 2.0 strict//", - "-//ietf//dtd html 2.0//", - "-//ietf//dtd html 2.1e//", - "-//ietf//dtd html 3.0//", - "-//ietf//dtd html 3.2 final//", - "-//ietf//dtd html 3.2//", - "-//ietf//dtd html 3//", - "-//ietf//dtd html level 0//", - "-//ietf//dtd html level 1//", - "-//ietf//dtd html level 2//", - "-//ietf//dtd html level 3//", - "-//ietf//dtd html strict level 0//", - "-//ietf//dtd html strict level 1//", - "-//ietf//dtd html strict level 2//", - "-//ietf//dtd html strict level 3//", - "-//ietf//dtd html strict//", - "-//ietf//dtd html//", - "-//metrius//dtd metrius presentational//", - "-//microsoft//dtd internet explorer 2.0 html strict//", - "-//microsoft//dtd internet explorer 2.0 html//", - "-//microsoft//dtd internet explorer 2.0 tables//", - "-//microsoft//dtd internet explorer 3.0 html strict//", - "-//microsoft//dtd internet explorer 3.0 html//", - "-//microsoft//dtd internet explorer 3.0 tables//", - "-//netscape comm. corp.//dtd html//", - "-//netscape comm. corp.//dtd strict html//", - "-//o'reilly and associates//dtd html 2.0//", - "-//o'reilly and associates//dtd html extended 1.0//", - "-//o'reilly and associates//dtd html extended relaxed 1.0//", - "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", - "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", - "-//spyglass//dtd html 2.0 extended//", - "-//sq//dtd html 2.0 hotmetal + extensions//", - "-//sun microsystems corp.//dtd hotjava html//", - "-//sun microsystems corp.//dtd hotjava strict html//", - "-//w3c//dtd html 3 1995-03-24//", - "-//w3c//dtd html 3.2 draft//", - "-//w3c//dtd html 3.2 final//", - "-//w3c//dtd html 3.2//", - "-//w3c//dtd html 3.2s draft//", - "-//w3c//dtd html 4.0 frameset//", - "-//w3c//dtd html 4.0 transitional//", - "-//w3c//dtd html experimental 19960712//", - "-//w3c//dtd html experimental 970421//", - "-//w3c//dtd w3 html//", - "-//w3o//dtd w3 html 3.0//", - "-//webtechs//dtd mozilla html 2.0//", - "-//webtechs//dtd mozilla html//", -} diff --git a/_third_party/golang.org/x/net/html/entity.go b/_third_party/golang.org/x/net/html/entity.go deleted file mode 100644 index a50c04c6..00000000 --- a/_third_party/golang.org/x/net/html/entity.go +++ /dev/null @@ -1,2253 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -// All entities that do not end with ';' are 6 or fewer bytes long. -const longestEntityWithoutSemicolon = 6 - -// entity is a map from HTML entity names to their values. The semicolon matters: -// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references -// lists both "amp" and "amp;" as two separate entries. -// -// Note that the HTML5 list is larger than the HTML4 list at -// http://www.w3.org/TR/html4/sgml/entities.html -var entity = map[string]rune{ - "AElig;": '\U000000C6', - "AMP;": '\U00000026', - "Aacute;": '\U000000C1', - "Abreve;": '\U00000102', - "Acirc;": '\U000000C2', - "Acy;": '\U00000410', - "Afr;": '\U0001D504', - "Agrave;": '\U000000C0', - "Alpha;": '\U00000391', - "Amacr;": '\U00000100', - "And;": '\U00002A53', - "Aogon;": '\U00000104', - "Aopf;": '\U0001D538', - "ApplyFunction;": '\U00002061', - "Aring;": '\U000000C5', - "Ascr;": '\U0001D49C', - "Assign;": '\U00002254', - "Atilde;": '\U000000C3', - "Auml;": '\U000000C4', - "Backslash;": '\U00002216', - "Barv;": '\U00002AE7', - "Barwed;": '\U00002306', - "Bcy;": '\U00000411', - "Because;": '\U00002235', - "Bernoullis;": '\U0000212C', - "Beta;": '\U00000392', - "Bfr;": '\U0001D505', - "Bopf;": '\U0001D539', - "Breve;": '\U000002D8', - "Bscr;": '\U0000212C', - "Bumpeq;": '\U0000224E', - "CHcy;": '\U00000427', - "COPY;": '\U000000A9', - "Cacute;": '\U00000106', - "Cap;": '\U000022D2', - "CapitalDifferentialD;": '\U00002145', - "Cayleys;": '\U0000212D', - "Ccaron;": '\U0000010C', - "Ccedil;": '\U000000C7', - "Ccirc;": '\U00000108', - "Cconint;": '\U00002230', - "Cdot;": '\U0000010A', - "Cedilla;": '\U000000B8', - "CenterDot;": '\U000000B7', - "Cfr;": '\U0000212D', - "Chi;": '\U000003A7', - "CircleDot;": '\U00002299', - "CircleMinus;": '\U00002296', - "CirclePlus;": '\U00002295', - "CircleTimes;": '\U00002297', - "ClockwiseContourIntegral;": '\U00002232', - "CloseCurlyDoubleQuote;": '\U0000201D', - "CloseCurlyQuote;": '\U00002019', - "Colon;": '\U00002237', - "Colone;": '\U00002A74', - "Congruent;": '\U00002261', - "Conint;": '\U0000222F', - "ContourIntegral;": '\U0000222E', - "Copf;": '\U00002102', - "Coproduct;": '\U00002210', - "CounterClockwiseContourIntegral;": '\U00002233', - "Cross;": '\U00002A2F', - "Cscr;": '\U0001D49E', - "Cup;": '\U000022D3', - "CupCap;": '\U0000224D', - "DD;": '\U00002145', - "DDotrahd;": '\U00002911', - "DJcy;": '\U00000402', - "DScy;": '\U00000405', - "DZcy;": '\U0000040F', - "Dagger;": '\U00002021', - "Darr;": '\U000021A1', - "Dashv;": '\U00002AE4', - "Dcaron;": '\U0000010E', - "Dcy;": '\U00000414', - "Del;": '\U00002207', - "Delta;": '\U00000394', - "Dfr;": '\U0001D507', - "DiacriticalAcute;": '\U000000B4', - "DiacriticalDot;": '\U000002D9', - "DiacriticalDoubleAcute;": '\U000002DD', - "DiacriticalGrave;": '\U00000060', - "DiacriticalTilde;": '\U000002DC', - "Diamond;": '\U000022C4', - "DifferentialD;": '\U00002146', - "Dopf;": '\U0001D53B', - "Dot;": '\U000000A8', - "DotDot;": '\U000020DC', - "DotEqual;": '\U00002250', - "DoubleContourIntegral;": '\U0000222F', - "DoubleDot;": '\U000000A8', - "DoubleDownArrow;": '\U000021D3', - "DoubleLeftArrow;": '\U000021D0', - "DoubleLeftRightArrow;": '\U000021D4', - "DoubleLeftTee;": '\U00002AE4', - "DoubleLongLeftArrow;": '\U000027F8', - "DoubleLongLeftRightArrow;": '\U000027FA', - "DoubleLongRightArrow;": '\U000027F9', - "DoubleRightArrow;": '\U000021D2', - "DoubleRightTee;": '\U000022A8', - "DoubleUpArrow;": '\U000021D1', - "DoubleUpDownArrow;": '\U000021D5', - "DoubleVerticalBar;": '\U00002225', - "DownArrow;": '\U00002193', - "DownArrowBar;": '\U00002913', - "DownArrowUpArrow;": '\U000021F5', - "DownBreve;": '\U00000311', - "DownLeftRightVector;": '\U00002950', - "DownLeftTeeVector;": '\U0000295E', - "DownLeftVector;": '\U000021BD', - "DownLeftVectorBar;": '\U00002956', - "DownRightTeeVector;": '\U0000295F', - "DownRightVector;": '\U000021C1', - "DownRightVectorBar;": '\U00002957', - "DownTee;": '\U000022A4', - "DownTeeArrow;": '\U000021A7', - "Downarrow;": '\U000021D3', - "Dscr;": '\U0001D49F', - "Dstrok;": '\U00000110', - "ENG;": '\U0000014A', - "ETH;": '\U000000D0', - "Eacute;": '\U000000C9', - "Ecaron;": '\U0000011A', - "Ecirc;": '\U000000CA', - "Ecy;": '\U0000042D', - "Edot;": '\U00000116', - "Efr;": '\U0001D508', - "Egrave;": '\U000000C8', - "Element;": '\U00002208', - "Emacr;": '\U00000112', - "EmptySmallSquare;": '\U000025FB', - "EmptyVerySmallSquare;": '\U000025AB', - "Eogon;": '\U00000118', - "Eopf;": '\U0001D53C', - "Epsilon;": '\U00000395', - "Equal;": '\U00002A75', - "EqualTilde;": '\U00002242', - "Equilibrium;": '\U000021CC', - "Escr;": '\U00002130', - "Esim;": '\U00002A73', - "Eta;": '\U00000397', - "Euml;": '\U000000CB', - "Exists;": '\U00002203', - "ExponentialE;": '\U00002147', - "Fcy;": '\U00000424', - "Ffr;": '\U0001D509', - "FilledSmallSquare;": '\U000025FC', - "FilledVerySmallSquare;": '\U000025AA', - "Fopf;": '\U0001D53D', - "ForAll;": '\U00002200', - "Fouriertrf;": '\U00002131', - "Fscr;": '\U00002131', - "GJcy;": '\U00000403', - "GT;": '\U0000003E', - "Gamma;": '\U00000393', - "Gammad;": '\U000003DC', - "Gbreve;": '\U0000011E', - "Gcedil;": '\U00000122', - "Gcirc;": '\U0000011C', - "Gcy;": '\U00000413', - "Gdot;": '\U00000120', - "Gfr;": '\U0001D50A', - "Gg;": '\U000022D9', - "Gopf;": '\U0001D53E', - "GreaterEqual;": '\U00002265', - "GreaterEqualLess;": '\U000022DB', - "GreaterFullEqual;": '\U00002267', - "GreaterGreater;": '\U00002AA2', - "GreaterLess;": '\U00002277', - "GreaterSlantEqual;": '\U00002A7E', - "GreaterTilde;": '\U00002273', - "Gscr;": '\U0001D4A2', - "Gt;": '\U0000226B', - "HARDcy;": '\U0000042A', - "Hacek;": '\U000002C7', - "Hat;": '\U0000005E', - "Hcirc;": '\U00000124', - "Hfr;": '\U0000210C', - "HilbertSpace;": '\U0000210B', - "Hopf;": '\U0000210D', - "HorizontalLine;": '\U00002500', - "Hscr;": '\U0000210B', - "Hstrok;": '\U00000126', - "HumpDownHump;": '\U0000224E', - "HumpEqual;": '\U0000224F', - "IEcy;": '\U00000415', - "IJlig;": '\U00000132', - "IOcy;": '\U00000401', - "Iacute;": '\U000000CD', - "Icirc;": '\U000000CE', - "Icy;": '\U00000418', - "Idot;": '\U00000130', - "Ifr;": '\U00002111', - "Igrave;": '\U000000CC', - "Im;": '\U00002111', - "Imacr;": '\U0000012A', - "ImaginaryI;": '\U00002148', - "Implies;": '\U000021D2', - "Int;": '\U0000222C', - "Integral;": '\U0000222B', - "Intersection;": '\U000022C2', - "InvisibleComma;": '\U00002063', - "InvisibleTimes;": '\U00002062', - "Iogon;": '\U0000012E', - "Iopf;": '\U0001D540', - "Iota;": '\U00000399', - "Iscr;": '\U00002110', - "Itilde;": '\U00000128', - "Iukcy;": '\U00000406', - "Iuml;": '\U000000CF', - "Jcirc;": '\U00000134', - "Jcy;": '\U00000419', - "Jfr;": '\U0001D50D', - "Jopf;": '\U0001D541', - "Jscr;": '\U0001D4A5', - "Jsercy;": '\U00000408', - "Jukcy;": '\U00000404', - "KHcy;": '\U00000425', - "KJcy;": '\U0000040C', - "Kappa;": '\U0000039A', - "Kcedil;": '\U00000136', - "Kcy;": '\U0000041A', - "Kfr;": '\U0001D50E', - "Kopf;": '\U0001D542', - "Kscr;": '\U0001D4A6', - "LJcy;": '\U00000409', - "LT;": '\U0000003C', - "Lacute;": '\U00000139', - "Lambda;": '\U0000039B', - "Lang;": '\U000027EA', - "Laplacetrf;": '\U00002112', - "Larr;": '\U0000219E', - "Lcaron;": '\U0000013D', - "Lcedil;": '\U0000013B', - "Lcy;": '\U0000041B', - "LeftAngleBracket;": '\U000027E8', - "LeftArrow;": '\U00002190', - "LeftArrowBar;": '\U000021E4', - "LeftArrowRightArrow;": '\U000021C6', - "LeftCeiling;": '\U00002308', - "LeftDoubleBracket;": '\U000027E6', - "LeftDownTeeVector;": '\U00002961', - "LeftDownVector;": '\U000021C3', - "LeftDownVectorBar;": '\U00002959', - "LeftFloor;": '\U0000230A', - "LeftRightArrow;": '\U00002194', - "LeftRightVector;": '\U0000294E', - "LeftTee;": '\U000022A3', - "LeftTeeArrow;": '\U000021A4', - "LeftTeeVector;": '\U0000295A', - "LeftTriangle;": '\U000022B2', - "LeftTriangleBar;": '\U000029CF', - "LeftTriangleEqual;": '\U000022B4', - "LeftUpDownVector;": '\U00002951', - "LeftUpTeeVector;": '\U00002960', - "LeftUpVector;": '\U000021BF', - "LeftUpVectorBar;": '\U00002958', - "LeftVector;": '\U000021BC', - "LeftVectorBar;": '\U00002952', - "Leftarrow;": '\U000021D0', - "Leftrightarrow;": '\U000021D4', - "LessEqualGreater;": '\U000022DA', - "LessFullEqual;": '\U00002266', - "LessGreater;": '\U00002276', - "LessLess;": '\U00002AA1', - "LessSlantEqual;": '\U00002A7D', - "LessTilde;": '\U00002272', - "Lfr;": '\U0001D50F', - "Ll;": '\U000022D8', - "Lleftarrow;": '\U000021DA', - "Lmidot;": '\U0000013F', - "LongLeftArrow;": '\U000027F5', - "LongLeftRightArrow;": '\U000027F7', - "LongRightArrow;": '\U000027F6', - "Longleftarrow;": '\U000027F8', - "Longleftrightarrow;": '\U000027FA', - "Longrightarrow;": '\U000027F9', - "Lopf;": '\U0001D543', - "LowerLeftArrow;": '\U00002199', - "LowerRightArrow;": '\U00002198', - "Lscr;": '\U00002112', - "Lsh;": '\U000021B0', - "Lstrok;": '\U00000141', - "Lt;": '\U0000226A', - "Map;": '\U00002905', - "Mcy;": '\U0000041C', - "MediumSpace;": '\U0000205F', - "Mellintrf;": '\U00002133', - "Mfr;": '\U0001D510', - "MinusPlus;": '\U00002213', - "Mopf;": '\U0001D544', - "Mscr;": '\U00002133', - "Mu;": '\U0000039C', - "NJcy;": '\U0000040A', - "Nacute;": '\U00000143', - "Ncaron;": '\U00000147', - "Ncedil;": '\U00000145', - "Ncy;": '\U0000041D', - "NegativeMediumSpace;": '\U0000200B', - "NegativeThickSpace;": '\U0000200B', - "NegativeThinSpace;": '\U0000200B', - "NegativeVeryThinSpace;": '\U0000200B', - "NestedGreaterGreater;": '\U0000226B', - "NestedLessLess;": '\U0000226A', - "NewLine;": '\U0000000A', - "Nfr;": '\U0001D511', - "NoBreak;": '\U00002060', - "NonBreakingSpace;": '\U000000A0', - "Nopf;": '\U00002115', - "Not;": '\U00002AEC', - "NotCongruent;": '\U00002262', - "NotCupCap;": '\U0000226D', - "NotDoubleVerticalBar;": '\U00002226', - "NotElement;": '\U00002209', - "NotEqual;": '\U00002260', - "NotExists;": '\U00002204', - "NotGreater;": '\U0000226F', - "NotGreaterEqual;": '\U00002271', - "NotGreaterLess;": '\U00002279', - "NotGreaterTilde;": '\U00002275', - "NotLeftTriangle;": '\U000022EA', - "NotLeftTriangleEqual;": '\U000022EC', - "NotLess;": '\U0000226E', - "NotLessEqual;": '\U00002270', - "NotLessGreater;": '\U00002278', - "NotLessTilde;": '\U00002274', - "NotPrecedes;": '\U00002280', - "NotPrecedesSlantEqual;": '\U000022E0', - "NotReverseElement;": '\U0000220C', - "NotRightTriangle;": '\U000022EB', - "NotRightTriangleEqual;": '\U000022ED', - "NotSquareSubsetEqual;": '\U000022E2', - "NotSquareSupersetEqual;": '\U000022E3', - "NotSubsetEqual;": '\U00002288', - "NotSucceeds;": '\U00002281', - "NotSucceedsSlantEqual;": '\U000022E1', - "NotSupersetEqual;": '\U00002289', - "NotTilde;": '\U00002241', - "NotTildeEqual;": '\U00002244', - "NotTildeFullEqual;": '\U00002247', - "NotTildeTilde;": '\U00002249', - "NotVerticalBar;": '\U00002224', - "Nscr;": '\U0001D4A9', - "Ntilde;": '\U000000D1', - "Nu;": '\U0000039D', - "OElig;": '\U00000152', - "Oacute;": '\U000000D3', - "Ocirc;": '\U000000D4', - "Ocy;": '\U0000041E', - "Odblac;": '\U00000150', - "Ofr;": '\U0001D512', - "Ograve;": '\U000000D2', - "Omacr;": '\U0000014C', - "Omega;": '\U000003A9', - "Omicron;": '\U0000039F', - "Oopf;": '\U0001D546', - "OpenCurlyDoubleQuote;": '\U0000201C', - "OpenCurlyQuote;": '\U00002018', - "Or;": '\U00002A54', - "Oscr;": '\U0001D4AA', - "Oslash;": '\U000000D8', - "Otilde;": '\U000000D5', - "Otimes;": '\U00002A37', - "Ouml;": '\U000000D6', - "OverBar;": '\U0000203E', - "OverBrace;": '\U000023DE', - "OverBracket;": '\U000023B4', - "OverParenthesis;": '\U000023DC', - "PartialD;": '\U00002202', - "Pcy;": '\U0000041F', - "Pfr;": '\U0001D513', - "Phi;": '\U000003A6', - "Pi;": '\U000003A0', - "PlusMinus;": '\U000000B1', - "Poincareplane;": '\U0000210C', - "Popf;": '\U00002119', - "Pr;": '\U00002ABB', - "Precedes;": '\U0000227A', - "PrecedesEqual;": '\U00002AAF', - "PrecedesSlantEqual;": '\U0000227C', - "PrecedesTilde;": '\U0000227E', - "Prime;": '\U00002033', - "Product;": '\U0000220F', - "Proportion;": '\U00002237', - "Proportional;": '\U0000221D', - "Pscr;": '\U0001D4AB', - "Psi;": '\U000003A8', - "QUOT;": '\U00000022', - "Qfr;": '\U0001D514', - "Qopf;": '\U0000211A', - "Qscr;": '\U0001D4AC', - "RBarr;": '\U00002910', - "REG;": '\U000000AE', - "Racute;": '\U00000154', - "Rang;": '\U000027EB', - "Rarr;": '\U000021A0', - "Rarrtl;": '\U00002916', - "Rcaron;": '\U00000158', - "Rcedil;": '\U00000156', - "Rcy;": '\U00000420', - "Re;": '\U0000211C', - "ReverseElement;": '\U0000220B', - "ReverseEquilibrium;": '\U000021CB', - "ReverseUpEquilibrium;": '\U0000296F', - "Rfr;": '\U0000211C', - "Rho;": '\U000003A1', - "RightAngleBracket;": '\U000027E9', - "RightArrow;": '\U00002192', - "RightArrowBar;": '\U000021E5', - "RightArrowLeftArrow;": '\U000021C4', - "RightCeiling;": '\U00002309', - "RightDoubleBracket;": '\U000027E7', - "RightDownTeeVector;": '\U0000295D', - "RightDownVector;": '\U000021C2', - "RightDownVectorBar;": '\U00002955', - "RightFloor;": '\U0000230B', - "RightTee;": '\U000022A2', - "RightTeeArrow;": '\U000021A6', - "RightTeeVector;": '\U0000295B', - "RightTriangle;": '\U000022B3', - "RightTriangleBar;": '\U000029D0', - "RightTriangleEqual;": '\U000022B5', - "RightUpDownVector;": '\U0000294F', - "RightUpTeeVector;": '\U0000295C', - "RightUpVector;": '\U000021BE', - "RightUpVectorBar;": '\U00002954', - "RightVector;": '\U000021C0', - "RightVectorBar;": '\U00002953', - "Rightarrow;": '\U000021D2', - "Ropf;": '\U0000211D', - "RoundImplies;": '\U00002970', - "Rrightarrow;": '\U000021DB', - "Rscr;": '\U0000211B', - "Rsh;": '\U000021B1', - "RuleDelayed;": '\U000029F4', - "SHCHcy;": '\U00000429', - "SHcy;": '\U00000428', - "SOFTcy;": '\U0000042C', - "Sacute;": '\U0000015A', - "Sc;": '\U00002ABC', - "Scaron;": '\U00000160', - "Scedil;": '\U0000015E', - "Scirc;": '\U0000015C', - "Scy;": '\U00000421', - "Sfr;": '\U0001D516', - "ShortDownArrow;": '\U00002193', - "ShortLeftArrow;": '\U00002190', - "ShortRightArrow;": '\U00002192', - "ShortUpArrow;": '\U00002191', - "Sigma;": '\U000003A3', - "SmallCircle;": '\U00002218', - "Sopf;": '\U0001D54A', - "Sqrt;": '\U0000221A', - "Square;": '\U000025A1', - "SquareIntersection;": '\U00002293', - "SquareSubset;": '\U0000228F', - "SquareSubsetEqual;": '\U00002291', - "SquareSuperset;": '\U00002290', - "SquareSupersetEqual;": '\U00002292', - "SquareUnion;": '\U00002294', - "Sscr;": '\U0001D4AE', - "Star;": '\U000022C6', - "Sub;": '\U000022D0', - "Subset;": '\U000022D0', - "SubsetEqual;": '\U00002286', - "Succeeds;": '\U0000227B', - "SucceedsEqual;": '\U00002AB0', - "SucceedsSlantEqual;": '\U0000227D', - "SucceedsTilde;": '\U0000227F', - "SuchThat;": '\U0000220B', - "Sum;": '\U00002211', - "Sup;": '\U000022D1', - "Superset;": '\U00002283', - "SupersetEqual;": '\U00002287', - "Supset;": '\U000022D1', - "THORN;": '\U000000DE', - "TRADE;": '\U00002122', - "TSHcy;": '\U0000040B', - "TScy;": '\U00000426', - "Tab;": '\U00000009', - "Tau;": '\U000003A4', - "Tcaron;": '\U00000164', - "Tcedil;": '\U00000162', - "Tcy;": '\U00000422', - "Tfr;": '\U0001D517', - "Therefore;": '\U00002234', - "Theta;": '\U00000398', - "ThinSpace;": '\U00002009', - "Tilde;": '\U0000223C', - "TildeEqual;": '\U00002243', - "TildeFullEqual;": '\U00002245', - "TildeTilde;": '\U00002248', - "Topf;": '\U0001D54B', - "TripleDot;": '\U000020DB', - "Tscr;": '\U0001D4AF', - "Tstrok;": '\U00000166', - "Uacute;": '\U000000DA', - "Uarr;": '\U0000219F', - "Uarrocir;": '\U00002949', - "Ubrcy;": '\U0000040E', - "Ubreve;": '\U0000016C', - "Ucirc;": '\U000000DB', - "Ucy;": '\U00000423', - "Udblac;": '\U00000170', - "Ufr;": '\U0001D518', - "Ugrave;": '\U000000D9', - "Umacr;": '\U0000016A', - "UnderBar;": '\U0000005F', - "UnderBrace;": '\U000023DF', - "UnderBracket;": '\U000023B5', - "UnderParenthesis;": '\U000023DD', - "Union;": '\U000022C3', - "UnionPlus;": '\U0000228E', - "Uogon;": '\U00000172', - "Uopf;": '\U0001D54C', - "UpArrow;": '\U00002191', - "UpArrowBar;": '\U00002912', - "UpArrowDownArrow;": '\U000021C5', - "UpDownArrow;": '\U00002195', - "UpEquilibrium;": '\U0000296E', - "UpTee;": '\U000022A5', - "UpTeeArrow;": '\U000021A5', - "Uparrow;": '\U000021D1', - "Updownarrow;": '\U000021D5', - "UpperLeftArrow;": '\U00002196', - "UpperRightArrow;": '\U00002197', - "Upsi;": '\U000003D2', - "Upsilon;": '\U000003A5', - "Uring;": '\U0000016E', - "Uscr;": '\U0001D4B0', - "Utilde;": '\U00000168', - "Uuml;": '\U000000DC', - "VDash;": '\U000022AB', - "Vbar;": '\U00002AEB', - "Vcy;": '\U00000412', - "Vdash;": '\U000022A9', - "Vdashl;": '\U00002AE6', - "Vee;": '\U000022C1', - "Verbar;": '\U00002016', - "Vert;": '\U00002016', - "VerticalBar;": '\U00002223', - "VerticalLine;": '\U0000007C', - "VerticalSeparator;": '\U00002758', - "VerticalTilde;": '\U00002240', - "VeryThinSpace;": '\U0000200A', - "Vfr;": '\U0001D519', - "Vopf;": '\U0001D54D', - "Vscr;": '\U0001D4B1', - "Vvdash;": '\U000022AA', - "Wcirc;": '\U00000174', - "Wedge;": '\U000022C0', - "Wfr;": '\U0001D51A', - "Wopf;": '\U0001D54E', - "Wscr;": '\U0001D4B2', - "Xfr;": '\U0001D51B', - "Xi;": '\U0000039E', - "Xopf;": '\U0001D54F', - "Xscr;": '\U0001D4B3', - "YAcy;": '\U0000042F', - "YIcy;": '\U00000407', - "YUcy;": '\U0000042E', - "Yacute;": '\U000000DD', - "Ycirc;": '\U00000176', - "Ycy;": '\U0000042B', - "Yfr;": '\U0001D51C', - "Yopf;": '\U0001D550', - "Yscr;": '\U0001D4B4', - "Yuml;": '\U00000178', - "ZHcy;": '\U00000416', - "Zacute;": '\U00000179', - "Zcaron;": '\U0000017D', - "Zcy;": '\U00000417', - "Zdot;": '\U0000017B', - "ZeroWidthSpace;": '\U0000200B', - "Zeta;": '\U00000396', - "Zfr;": '\U00002128', - "Zopf;": '\U00002124', - "Zscr;": '\U0001D4B5', - "aacute;": '\U000000E1', - "abreve;": '\U00000103', - "ac;": '\U0000223E', - "acd;": '\U0000223F', - "acirc;": '\U000000E2', - "acute;": '\U000000B4', - "acy;": '\U00000430', - "aelig;": '\U000000E6', - "af;": '\U00002061', - "afr;": '\U0001D51E', - "agrave;": '\U000000E0', - "alefsym;": '\U00002135', - "aleph;": '\U00002135', - "alpha;": '\U000003B1', - "amacr;": '\U00000101', - "amalg;": '\U00002A3F', - "amp;": '\U00000026', - "and;": '\U00002227', - "andand;": '\U00002A55', - "andd;": '\U00002A5C', - "andslope;": '\U00002A58', - "andv;": '\U00002A5A', - "ang;": '\U00002220', - "ange;": '\U000029A4', - "angle;": '\U00002220', - "angmsd;": '\U00002221', - "angmsdaa;": '\U000029A8', - "angmsdab;": '\U000029A9', - "angmsdac;": '\U000029AA', - "angmsdad;": '\U000029AB', - "angmsdae;": '\U000029AC', - "angmsdaf;": '\U000029AD', - "angmsdag;": '\U000029AE', - "angmsdah;": '\U000029AF', - "angrt;": '\U0000221F', - "angrtvb;": '\U000022BE', - "angrtvbd;": '\U0000299D', - "angsph;": '\U00002222', - "angst;": '\U000000C5', - "angzarr;": '\U0000237C', - "aogon;": '\U00000105', - "aopf;": '\U0001D552', - "ap;": '\U00002248', - "apE;": '\U00002A70', - "apacir;": '\U00002A6F', - "ape;": '\U0000224A', - "apid;": '\U0000224B', - "apos;": '\U00000027', - "approx;": '\U00002248', - "approxeq;": '\U0000224A', - "aring;": '\U000000E5', - "ascr;": '\U0001D4B6', - "ast;": '\U0000002A', - "asymp;": '\U00002248', - "asympeq;": '\U0000224D', - "atilde;": '\U000000E3', - "auml;": '\U000000E4', - "awconint;": '\U00002233', - "awint;": '\U00002A11', - "bNot;": '\U00002AED', - "backcong;": '\U0000224C', - "backepsilon;": '\U000003F6', - "backprime;": '\U00002035', - "backsim;": '\U0000223D', - "backsimeq;": '\U000022CD', - "barvee;": '\U000022BD', - "barwed;": '\U00002305', - "barwedge;": '\U00002305', - "bbrk;": '\U000023B5', - "bbrktbrk;": '\U000023B6', - "bcong;": '\U0000224C', - "bcy;": '\U00000431', - "bdquo;": '\U0000201E', - "becaus;": '\U00002235', - "because;": '\U00002235', - "bemptyv;": '\U000029B0', - "bepsi;": '\U000003F6', - "bernou;": '\U0000212C', - "beta;": '\U000003B2', - "beth;": '\U00002136', - "between;": '\U0000226C', - "bfr;": '\U0001D51F', - "bigcap;": '\U000022C2', - "bigcirc;": '\U000025EF', - "bigcup;": '\U000022C3', - "bigodot;": '\U00002A00', - "bigoplus;": '\U00002A01', - "bigotimes;": '\U00002A02', - "bigsqcup;": '\U00002A06', - "bigstar;": '\U00002605', - "bigtriangledown;": '\U000025BD', - "bigtriangleup;": '\U000025B3', - "biguplus;": '\U00002A04', - "bigvee;": '\U000022C1', - "bigwedge;": '\U000022C0', - "bkarow;": '\U0000290D', - "blacklozenge;": '\U000029EB', - "blacksquare;": '\U000025AA', - "blacktriangle;": '\U000025B4', - "blacktriangledown;": '\U000025BE', - "blacktriangleleft;": '\U000025C2', - "blacktriangleright;": '\U000025B8', - "blank;": '\U00002423', - "blk12;": '\U00002592', - "blk14;": '\U00002591', - "blk34;": '\U00002593', - "block;": '\U00002588', - "bnot;": '\U00002310', - "bopf;": '\U0001D553', - "bot;": '\U000022A5', - "bottom;": '\U000022A5', - "bowtie;": '\U000022C8', - "boxDL;": '\U00002557', - "boxDR;": '\U00002554', - "boxDl;": '\U00002556', - "boxDr;": '\U00002553', - "boxH;": '\U00002550', - "boxHD;": '\U00002566', - "boxHU;": '\U00002569', - "boxHd;": '\U00002564', - "boxHu;": '\U00002567', - "boxUL;": '\U0000255D', - "boxUR;": '\U0000255A', - "boxUl;": '\U0000255C', - "boxUr;": '\U00002559', - "boxV;": '\U00002551', - "boxVH;": '\U0000256C', - "boxVL;": '\U00002563', - "boxVR;": '\U00002560', - "boxVh;": '\U0000256B', - "boxVl;": '\U00002562', - "boxVr;": '\U0000255F', - "boxbox;": '\U000029C9', - "boxdL;": '\U00002555', - "boxdR;": '\U00002552', - "boxdl;": '\U00002510', - "boxdr;": '\U0000250C', - "boxh;": '\U00002500', - "boxhD;": '\U00002565', - "boxhU;": '\U00002568', - "boxhd;": '\U0000252C', - "boxhu;": '\U00002534', - "boxminus;": '\U0000229F', - "boxplus;": '\U0000229E', - "boxtimes;": '\U000022A0', - "boxuL;": '\U0000255B', - "boxuR;": '\U00002558', - "boxul;": '\U00002518', - "boxur;": '\U00002514', - "boxv;": '\U00002502', - "boxvH;": '\U0000256A', - "boxvL;": '\U00002561', - "boxvR;": '\U0000255E', - "boxvh;": '\U0000253C', - "boxvl;": '\U00002524', - "boxvr;": '\U0000251C', - "bprime;": '\U00002035', - "breve;": '\U000002D8', - "brvbar;": '\U000000A6', - "bscr;": '\U0001D4B7', - "bsemi;": '\U0000204F', - "bsim;": '\U0000223D', - "bsime;": '\U000022CD', - "bsol;": '\U0000005C', - "bsolb;": '\U000029C5', - "bsolhsub;": '\U000027C8', - "bull;": '\U00002022', - "bullet;": '\U00002022', - "bump;": '\U0000224E', - "bumpE;": '\U00002AAE', - "bumpe;": '\U0000224F', - "bumpeq;": '\U0000224F', - "cacute;": '\U00000107', - "cap;": '\U00002229', - "capand;": '\U00002A44', - "capbrcup;": '\U00002A49', - "capcap;": '\U00002A4B', - "capcup;": '\U00002A47', - "capdot;": '\U00002A40', - "caret;": '\U00002041', - "caron;": '\U000002C7', - "ccaps;": '\U00002A4D', - "ccaron;": '\U0000010D', - "ccedil;": '\U000000E7', - "ccirc;": '\U00000109', - "ccups;": '\U00002A4C', - "ccupssm;": '\U00002A50', - "cdot;": '\U0000010B', - "cedil;": '\U000000B8', - "cemptyv;": '\U000029B2', - "cent;": '\U000000A2', - "centerdot;": '\U000000B7', - "cfr;": '\U0001D520', - "chcy;": '\U00000447', - "check;": '\U00002713', - "checkmark;": '\U00002713', - "chi;": '\U000003C7', - "cir;": '\U000025CB', - "cirE;": '\U000029C3', - "circ;": '\U000002C6', - "circeq;": '\U00002257', - "circlearrowleft;": '\U000021BA', - "circlearrowright;": '\U000021BB', - "circledR;": '\U000000AE', - "circledS;": '\U000024C8', - "circledast;": '\U0000229B', - "circledcirc;": '\U0000229A', - "circleddash;": '\U0000229D', - "cire;": '\U00002257', - "cirfnint;": '\U00002A10', - "cirmid;": '\U00002AEF', - "cirscir;": '\U000029C2', - "clubs;": '\U00002663', - "clubsuit;": '\U00002663', - "colon;": '\U0000003A', - "colone;": '\U00002254', - "coloneq;": '\U00002254', - "comma;": '\U0000002C', - "commat;": '\U00000040', - "comp;": '\U00002201', - "compfn;": '\U00002218', - "complement;": '\U00002201', - "complexes;": '\U00002102', - "cong;": '\U00002245', - "congdot;": '\U00002A6D', - "conint;": '\U0000222E', - "copf;": '\U0001D554', - "coprod;": '\U00002210', - "copy;": '\U000000A9', - "copysr;": '\U00002117', - "crarr;": '\U000021B5', - "cross;": '\U00002717', - "cscr;": '\U0001D4B8', - "csub;": '\U00002ACF', - "csube;": '\U00002AD1', - "csup;": '\U00002AD0', - "csupe;": '\U00002AD2', - "ctdot;": '\U000022EF', - "cudarrl;": '\U00002938', - "cudarrr;": '\U00002935', - "cuepr;": '\U000022DE', - "cuesc;": '\U000022DF', - "cularr;": '\U000021B6', - "cularrp;": '\U0000293D', - "cup;": '\U0000222A', - "cupbrcap;": '\U00002A48', - "cupcap;": '\U00002A46', - "cupcup;": '\U00002A4A', - "cupdot;": '\U0000228D', - "cupor;": '\U00002A45', - "curarr;": '\U000021B7', - "curarrm;": '\U0000293C', - "curlyeqprec;": '\U000022DE', - "curlyeqsucc;": '\U000022DF', - "curlyvee;": '\U000022CE', - "curlywedge;": '\U000022CF', - "curren;": '\U000000A4', - "curvearrowleft;": '\U000021B6', - "curvearrowright;": '\U000021B7', - "cuvee;": '\U000022CE', - "cuwed;": '\U000022CF', - "cwconint;": '\U00002232', - "cwint;": '\U00002231', - "cylcty;": '\U0000232D', - "dArr;": '\U000021D3', - "dHar;": '\U00002965', - "dagger;": '\U00002020', - "daleth;": '\U00002138', - "darr;": '\U00002193', - "dash;": '\U00002010', - "dashv;": '\U000022A3', - "dbkarow;": '\U0000290F', - "dblac;": '\U000002DD', - "dcaron;": '\U0000010F', - "dcy;": '\U00000434', - "dd;": '\U00002146', - "ddagger;": '\U00002021', - "ddarr;": '\U000021CA', - "ddotseq;": '\U00002A77', - "deg;": '\U000000B0', - "delta;": '\U000003B4', - "demptyv;": '\U000029B1', - "dfisht;": '\U0000297F', - "dfr;": '\U0001D521', - "dharl;": '\U000021C3', - "dharr;": '\U000021C2', - "diam;": '\U000022C4', - "diamond;": '\U000022C4', - "diamondsuit;": '\U00002666', - "diams;": '\U00002666', - "die;": '\U000000A8', - "digamma;": '\U000003DD', - "disin;": '\U000022F2', - "div;": '\U000000F7', - "divide;": '\U000000F7', - "divideontimes;": '\U000022C7', - "divonx;": '\U000022C7', - "djcy;": '\U00000452', - "dlcorn;": '\U0000231E', - "dlcrop;": '\U0000230D', - "dollar;": '\U00000024', - "dopf;": '\U0001D555', - "dot;": '\U000002D9', - "doteq;": '\U00002250', - "doteqdot;": '\U00002251', - "dotminus;": '\U00002238', - "dotplus;": '\U00002214', - "dotsquare;": '\U000022A1', - "doublebarwedge;": '\U00002306', - "downarrow;": '\U00002193', - "downdownarrows;": '\U000021CA', - "downharpoonleft;": '\U000021C3', - "downharpoonright;": '\U000021C2', - "drbkarow;": '\U00002910', - "drcorn;": '\U0000231F', - "drcrop;": '\U0000230C', - "dscr;": '\U0001D4B9', - "dscy;": '\U00000455', - "dsol;": '\U000029F6', - "dstrok;": '\U00000111', - "dtdot;": '\U000022F1', - "dtri;": '\U000025BF', - "dtrif;": '\U000025BE', - "duarr;": '\U000021F5', - "duhar;": '\U0000296F', - "dwangle;": '\U000029A6', - "dzcy;": '\U0000045F', - "dzigrarr;": '\U000027FF', - "eDDot;": '\U00002A77', - "eDot;": '\U00002251', - "eacute;": '\U000000E9', - "easter;": '\U00002A6E', - "ecaron;": '\U0000011B', - "ecir;": '\U00002256', - "ecirc;": '\U000000EA', - "ecolon;": '\U00002255', - "ecy;": '\U0000044D', - "edot;": '\U00000117', - "ee;": '\U00002147', - "efDot;": '\U00002252', - "efr;": '\U0001D522', - "eg;": '\U00002A9A', - "egrave;": '\U000000E8', - "egs;": '\U00002A96', - "egsdot;": '\U00002A98', - "el;": '\U00002A99', - "elinters;": '\U000023E7', - "ell;": '\U00002113', - "els;": '\U00002A95', - "elsdot;": '\U00002A97', - "emacr;": '\U00000113', - "empty;": '\U00002205', - "emptyset;": '\U00002205', - "emptyv;": '\U00002205', - "emsp;": '\U00002003', - "emsp13;": '\U00002004', - "emsp14;": '\U00002005', - "eng;": '\U0000014B', - "ensp;": '\U00002002', - "eogon;": '\U00000119', - "eopf;": '\U0001D556', - "epar;": '\U000022D5', - "eparsl;": '\U000029E3', - "eplus;": '\U00002A71', - "epsi;": '\U000003B5', - "epsilon;": '\U000003B5', - "epsiv;": '\U000003F5', - "eqcirc;": '\U00002256', - "eqcolon;": '\U00002255', - "eqsim;": '\U00002242', - "eqslantgtr;": '\U00002A96', - "eqslantless;": '\U00002A95', - "equals;": '\U0000003D', - "equest;": '\U0000225F', - "equiv;": '\U00002261', - "equivDD;": '\U00002A78', - "eqvparsl;": '\U000029E5', - "erDot;": '\U00002253', - "erarr;": '\U00002971', - "escr;": '\U0000212F', - "esdot;": '\U00002250', - "esim;": '\U00002242', - "eta;": '\U000003B7', - "eth;": '\U000000F0', - "euml;": '\U000000EB', - "euro;": '\U000020AC', - "excl;": '\U00000021', - "exist;": '\U00002203', - "expectation;": '\U00002130', - "exponentiale;": '\U00002147', - "fallingdotseq;": '\U00002252', - "fcy;": '\U00000444', - "female;": '\U00002640', - "ffilig;": '\U0000FB03', - "fflig;": '\U0000FB00', - "ffllig;": '\U0000FB04', - "ffr;": '\U0001D523', - "filig;": '\U0000FB01', - "flat;": '\U0000266D', - "fllig;": '\U0000FB02', - "fltns;": '\U000025B1', - "fnof;": '\U00000192', - "fopf;": '\U0001D557', - "forall;": '\U00002200', - "fork;": '\U000022D4', - "forkv;": '\U00002AD9', - "fpartint;": '\U00002A0D', - "frac12;": '\U000000BD', - "frac13;": '\U00002153', - "frac14;": '\U000000BC', - "frac15;": '\U00002155', - "frac16;": '\U00002159', - "frac18;": '\U0000215B', - "frac23;": '\U00002154', - "frac25;": '\U00002156', - "frac34;": '\U000000BE', - "frac35;": '\U00002157', - "frac38;": '\U0000215C', - "frac45;": '\U00002158', - "frac56;": '\U0000215A', - "frac58;": '\U0000215D', - "frac78;": '\U0000215E', - "frasl;": '\U00002044', - "frown;": '\U00002322', - "fscr;": '\U0001D4BB', - "gE;": '\U00002267', - "gEl;": '\U00002A8C', - "gacute;": '\U000001F5', - "gamma;": '\U000003B3', - "gammad;": '\U000003DD', - "gap;": '\U00002A86', - "gbreve;": '\U0000011F', - "gcirc;": '\U0000011D', - "gcy;": '\U00000433', - "gdot;": '\U00000121', - "ge;": '\U00002265', - "gel;": '\U000022DB', - "geq;": '\U00002265', - "geqq;": '\U00002267', - "geqslant;": '\U00002A7E', - "ges;": '\U00002A7E', - "gescc;": '\U00002AA9', - "gesdot;": '\U00002A80', - "gesdoto;": '\U00002A82', - "gesdotol;": '\U00002A84', - "gesles;": '\U00002A94', - "gfr;": '\U0001D524', - "gg;": '\U0000226B', - "ggg;": '\U000022D9', - "gimel;": '\U00002137', - "gjcy;": '\U00000453', - "gl;": '\U00002277', - "glE;": '\U00002A92', - "gla;": '\U00002AA5', - "glj;": '\U00002AA4', - "gnE;": '\U00002269', - "gnap;": '\U00002A8A', - "gnapprox;": '\U00002A8A', - "gne;": '\U00002A88', - "gneq;": '\U00002A88', - "gneqq;": '\U00002269', - "gnsim;": '\U000022E7', - "gopf;": '\U0001D558', - "grave;": '\U00000060', - "gscr;": '\U0000210A', - "gsim;": '\U00002273', - "gsime;": '\U00002A8E', - "gsiml;": '\U00002A90', - "gt;": '\U0000003E', - "gtcc;": '\U00002AA7', - "gtcir;": '\U00002A7A', - "gtdot;": '\U000022D7', - "gtlPar;": '\U00002995', - "gtquest;": '\U00002A7C', - "gtrapprox;": '\U00002A86', - "gtrarr;": '\U00002978', - "gtrdot;": '\U000022D7', - "gtreqless;": '\U000022DB', - "gtreqqless;": '\U00002A8C', - "gtrless;": '\U00002277', - "gtrsim;": '\U00002273', - "hArr;": '\U000021D4', - "hairsp;": '\U0000200A', - "half;": '\U000000BD', - "hamilt;": '\U0000210B', - "hardcy;": '\U0000044A', - "harr;": '\U00002194', - "harrcir;": '\U00002948', - "harrw;": '\U000021AD', - "hbar;": '\U0000210F', - "hcirc;": '\U00000125', - "hearts;": '\U00002665', - "heartsuit;": '\U00002665', - "hellip;": '\U00002026', - "hercon;": '\U000022B9', - "hfr;": '\U0001D525', - "hksearow;": '\U00002925', - "hkswarow;": '\U00002926', - "hoarr;": '\U000021FF', - "homtht;": '\U0000223B', - "hookleftarrow;": '\U000021A9', - "hookrightarrow;": '\U000021AA', - "hopf;": '\U0001D559', - "horbar;": '\U00002015', - "hscr;": '\U0001D4BD', - "hslash;": '\U0000210F', - "hstrok;": '\U00000127', - "hybull;": '\U00002043', - "hyphen;": '\U00002010', - "iacute;": '\U000000ED', - "ic;": '\U00002063', - "icirc;": '\U000000EE', - "icy;": '\U00000438', - "iecy;": '\U00000435', - "iexcl;": '\U000000A1', - "iff;": '\U000021D4', - "ifr;": '\U0001D526', - "igrave;": '\U000000EC', - "ii;": '\U00002148', - "iiiint;": '\U00002A0C', - "iiint;": '\U0000222D', - "iinfin;": '\U000029DC', - "iiota;": '\U00002129', - "ijlig;": '\U00000133', - "imacr;": '\U0000012B', - "image;": '\U00002111', - "imagline;": '\U00002110', - "imagpart;": '\U00002111', - "imath;": '\U00000131', - "imof;": '\U000022B7', - "imped;": '\U000001B5', - "in;": '\U00002208', - "incare;": '\U00002105', - "infin;": '\U0000221E', - "infintie;": '\U000029DD', - "inodot;": '\U00000131', - "int;": '\U0000222B', - "intcal;": '\U000022BA', - "integers;": '\U00002124', - "intercal;": '\U000022BA', - "intlarhk;": '\U00002A17', - "intprod;": '\U00002A3C', - "iocy;": '\U00000451', - "iogon;": '\U0000012F', - "iopf;": '\U0001D55A', - "iota;": '\U000003B9', - "iprod;": '\U00002A3C', - "iquest;": '\U000000BF', - "iscr;": '\U0001D4BE', - "isin;": '\U00002208', - "isinE;": '\U000022F9', - "isindot;": '\U000022F5', - "isins;": '\U000022F4', - "isinsv;": '\U000022F3', - "isinv;": '\U00002208', - "it;": '\U00002062', - "itilde;": '\U00000129', - "iukcy;": '\U00000456', - "iuml;": '\U000000EF', - "jcirc;": '\U00000135', - "jcy;": '\U00000439', - "jfr;": '\U0001D527', - "jmath;": '\U00000237', - "jopf;": '\U0001D55B', - "jscr;": '\U0001D4BF', - "jsercy;": '\U00000458', - "jukcy;": '\U00000454', - "kappa;": '\U000003BA', - "kappav;": '\U000003F0', - "kcedil;": '\U00000137', - "kcy;": '\U0000043A', - "kfr;": '\U0001D528', - "kgreen;": '\U00000138', - "khcy;": '\U00000445', - "kjcy;": '\U0000045C', - "kopf;": '\U0001D55C', - "kscr;": '\U0001D4C0', - "lAarr;": '\U000021DA', - "lArr;": '\U000021D0', - "lAtail;": '\U0000291B', - "lBarr;": '\U0000290E', - "lE;": '\U00002266', - "lEg;": '\U00002A8B', - "lHar;": '\U00002962', - "lacute;": '\U0000013A', - "laemptyv;": '\U000029B4', - "lagran;": '\U00002112', - "lambda;": '\U000003BB', - "lang;": '\U000027E8', - "langd;": '\U00002991', - "langle;": '\U000027E8', - "lap;": '\U00002A85', - "laquo;": '\U000000AB', - "larr;": '\U00002190', - "larrb;": '\U000021E4', - "larrbfs;": '\U0000291F', - "larrfs;": '\U0000291D', - "larrhk;": '\U000021A9', - "larrlp;": '\U000021AB', - "larrpl;": '\U00002939', - "larrsim;": '\U00002973', - "larrtl;": '\U000021A2', - "lat;": '\U00002AAB', - "latail;": '\U00002919', - "late;": '\U00002AAD', - "lbarr;": '\U0000290C', - "lbbrk;": '\U00002772', - "lbrace;": '\U0000007B', - "lbrack;": '\U0000005B', - "lbrke;": '\U0000298B', - "lbrksld;": '\U0000298F', - "lbrkslu;": '\U0000298D', - "lcaron;": '\U0000013E', - "lcedil;": '\U0000013C', - "lceil;": '\U00002308', - "lcub;": '\U0000007B', - "lcy;": '\U0000043B', - "ldca;": '\U00002936', - "ldquo;": '\U0000201C', - "ldquor;": '\U0000201E', - "ldrdhar;": '\U00002967', - "ldrushar;": '\U0000294B', - "ldsh;": '\U000021B2', - "le;": '\U00002264', - "leftarrow;": '\U00002190', - "leftarrowtail;": '\U000021A2', - "leftharpoondown;": '\U000021BD', - "leftharpoonup;": '\U000021BC', - "leftleftarrows;": '\U000021C7', - "leftrightarrow;": '\U00002194', - "leftrightarrows;": '\U000021C6', - "leftrightharpoons;": '\U000021CB', - "leftrightsquigarrow;": '\U000021AD', - "leftthreetimes;": '\U000022CB', - "leg;": '\U000022DA', - "leq;": '\U00002264', - "leqq;": '\U00002266', - "leqslant;": '\U00002A7D', - "les;": '\U00002A7D', - "lescc;": '\U00002AA8', - "lesdot;": '\U00002A7F', - "lesdoto;": '\U00002A81', - "lesdotor;": '\U00002A83', - "lesges;": '\U00002A93', - "lessapprox;": '\U00002A85', - "lessdot;": '\U000022D6', - "lesseqgtr;": '\U000022DA', - "lesseqqgtr;": '\U00002A8B', - "lessgtr;": '\U00002276', - "lesssim;": '\U00002272', - "lfisht;": '\U0000297C', - "lfloor;": '\U0000230A', - "lfr;": '\U0001D529', - "lg;": '\U00002276', - "lgE;": '\U00002A91', - "lhard;": '\U000021BD', - "lharu;": '\U000021BC', - "lharul;": '\U0000296A', - "lhblk;": '\U00002584', - "ljcy;": '\U00000459', - "ll;": '\U0000226A', - "llarr;": '\U000021C7', - "llcorner;": '\U0000231E', - "llhard;": '\U0000296B', - "lltri;": '\U000025FA', - "lmidot;": '\U00000140', - "lmoust;": '\U000023B0', - "lmoustache;": '\U000023B0', - "lnE;": '\U00002268', - "lnap;": '\U00002A89', - "lnapprox;": '\U00002A89', - "lne;": '\U00002A87', - "lneq;": '\U00002A87', - "lneqq;": '\U00002268', - "lnsim;": '\U000022E6', - "loang;": '\U000027EC', - "loarr;": '\U000021FD', - "lobrk;": '\U000027E6', - "longleftarrow;": '\U000027F5', - "longleftrightarrow;": '\U000027F7', - "longmapsto;": '\U000027FC', - "longrightarrow;": '\U000027F6', - "looparrowleft;": '\U000021AB', - "looparrowright;": '\U000021AC', - "lopar;": '\U00002985', - "lopf;": '\U0001D55D', - "loplus;": '\U00002A2D', - "lotimes;": '\U00002A34', - "lowast;": '\U00002217', - "lowbar;": '\U0000005F', - "loz;": '\U000025CA', - "lozenge;": '\U000025CA', - "lozf;": '\U000029EB', - "lpar;": '\U00000028', - "lparlt;": '\U00002993', - "lrarr;": '\U000021C6', - "lrcorner;": '\U0000231F', - "lrhar;": '\U000021CB', - "lrhard;": '\U0000296D', - "lrm;": '\U0000200E', - "lrtri;": '\U000022BF', - "lsaquo;": '\U00002039', - "lscr;": '\U0001D4C1', - "lsh;": '\U000021B0', - "lsim;": '\U00002272', - "lsime;": '\U00002A8D', - "lsimg;": '\U00002A8F', - "lsqb;": '\U0000005B', - "lsquo;": '\U00002018', - "lsquor;": '\U0000201A', - "lstrok;": '\U00000142', - "lt;": '\U0000003C', - "ltcc;": '\U00002AA6', - "ltcir;": '\U00002A79', - "ltdot;": '\U000022D6', - "lthree;": '\U000022CB', - "ltimes;": '\U000022C9', - "ltlarr;": '\U00002976', - "ltquest;": '\U00002A7B', - "ltrPar;": '\U00002996', - "ltri;": '\U000025C3', - "ltrie;": '\U000022B4', - "ltrif;": '\U000025C2', - "lurdshar;": '\U0000294A', - "luruhar;": '\U00002966', - "mDDot;": '\U0000223A', - "macr;": '\U000000AF', - "male;": '\U00002642', - "malt;": '\U00002720', - "maltese;": '\U00002720', - "map;": '\U000021A6', - "mapsto;": '\U000021A6', - "mapstodown;": '\U000021A7', - "mapstoleft;": '\U000021A4', - "mapstoup;": '\U000021A5', - "marker;": '\U000025AE', - "mcomma;": '\U00002A29', - "mcy;": '\U0000043C', - "mdash;": '\U00002014', - "measuredangle;": '\U00002221', - "mfr;": '\U0001D52A', - "mho;": '\U00002127', - "micro;": '\U000000B5', - "mid;": '\U00002223', - "midast;": '\U0000002A', - "midcir;": '\U00002AF0', - "middot;": '\U000000B7', - "minus;": '\U00002212', - "minusb;": '\U0000229F', - "minusd;": '\U00002238', - "minusdu;": '\U00002A2A', - "mlcp;": '\U00002ADB', - "mldr;": '\U00002026', - "mnplus;": '\U00002213', - "models;": '\U000022A7', - "mopf;": '\U0001D55E', - "mp;": '\U00002213', - "mscr;": '\U0001D4C2', - "mstpos;": '\U0000223E', - "mu;": '\U000003BC', - "multimap;": '\U000022B8', - "mumap;": '\U000022B8', - "nLeftarrow;": '\U000021CD', - "nLeftrightarrow;": '\U000021CE', - "nRightarrow;": '\U000021CF', - "nVDash;": '\U000022AF', - "nVdash;": '\U000022AE', - "nabla;": '\U00002207', - "nacute;": '\U00000144', - "nap;": '\U00002249', - "napos;": '\U00000149', - "napprox;": '\U00002249', - "natur;": '\U0000266E', - "natural;": '\U0000266E', - "naturals;": '\U00002115', - "nbsp;": '\U000000A0', - "ncap;": '\U00002A43', - "ncaron;": '\U00000148', - "ncedil;": '\U00000146', - "ncong;": '\U00002247', - "ncup;": '\U00002A42', - "ncy;": '\U0000043D', - "ndash;": '\U00002013', - "ne;": '\U00002260', - "neArr;": '\U000021D7', - "nearhk;": '\U00002924', - "nearr;": '\U00002197', - "nearrow;": '\U00002197', - "nequiv;": '\U00002262', - "nesear;": '\U00002928', - "nexist;": '\U00002204', - "nexists;": '\U00002204', - "nfr;": '\U0001D52B', - "nge;": '\U00002271', - "ngeq;": '\U00002271', - "ngsim;": '\U00002275', - "ngt;": '\U0000226F', - "ngtr;": '\U0000226F', - "nhArr;": '\U000021CE', - "nharr;": '\U000021AE', - "nhpar;": '\U00002AF2', - "ni;": '\U0000220B', - "nis;": '\U000022FC', - "nisd;": '\U000022FA', - "niv;": '\U0000220B', - "njcy;": '\U0000045A', - "nlArr;": '\U000021CD', - "nlarr;": '\U0000219A', - "nldr;": '\U00002025', - "nle;": '\U00002270', - "nleftarrow;": '\U0000219A', - "nleftrightarrow;": '\U000021AE', - "nleq;": '\U00002270', - "nless;": '\U0000226E', - "nlsim;": '\U00002274', - "nlt;": '\U0000226E', - "nltri;": '\U000022EA', - "nltrie;": '\U000022EC', - "nmid;": '\U00002224', - "nopf;": '\U0001D55F', - "not;": '\U000000AC', - "notin;": '\U00002209', - "notinva;": '\U00002209', - "notinvb;": '\U000022F7', - "notinvc;": '\U000022F6', - "notni;": '\U0000220C', - "notniva;": '\U0000220C', - "notnivb;": '\U000022FE', - "notnivc;": '\U000022FD', - "npar;": '\U00002226', - "nparallel;": '\U00002226', - "npolint;": '\U00002A14', - "npr;": '\U00002280', - "nprcue;": '\U000022E0', - "nprec;": '\U00002280', - "nrArr;": '\U000021CF', - "nrarr;": '\U0000219B', - "nrightarrow;": '\U0000219B', - "nrtri;": '\U000022EB', - "nrtrie;": '\U000022ED', - "nsc;": '\U00002281', - "nsccue;": '\U000022E1', - "nscr;": '\U0001D4C3', - "nshortmid;": '\U00002224', - "nshortparallel;": '\U00002226', - "nsim;": '\U00002241', - "nsime;": '\U00002244', - "nsimeq;": '\U00002244', - "nsmid;": '\U00002224', - "nspar;": '\U00002226', - "nsqsube;": '\U000022E2', - "nsqsupe;": '\U000022E3', - "nsub;": '\U00002284', - "nsube;": '\U00002288', - "nsubseteq;": '\U00002288', - "nsucc;": '\U00002281', - "nsup;": '\U00002285', - "nsupe;": '\U00002289', - "nsupseteq;": '\U00002289', - "ntgl;": '\U00002279', - "ntilde;": '\U000000F1', - "ntlg;": '\U00002278', - "ntriangleleft;": '\U000022EA', - "ntrianglelefteq;": '\U000022EC', - "ntriangleright;": '\U000022EB', - "ntrianglerighteq;": '\U000022ED', - "nu;": '\U000003BD', - "num;": '\U00000023', - "numero;": '\U00002116', - "numsp;": '\U00002007', - "nvDash;": '\U000022AD', - "nvHarr;": '\U00002904', - "nvdash;": '\U000022AC', - "nvinfin;": '\U000029DE', - "nvlArr;": '\U00002902', - "nvrArr;": '\U00002903', - "nwArr;": '\U000021D6', - "nwarhk;": '\U00002923', - "nwarr;": '\U00002196', - "nwarrow;": '\U00002196', - "nwnear;": '\U00002927', - "oS;": '\U000024C8', - "oacute;": '\U000000F3', - "oast;": '\U0000229B', - "ocir;": '\U0000229A', - "ocirc;": '\U000000F4', - "ocy;": '\U0000043E', - "odash;": '\U0000229D', - "odblac;": '\U00000151', - "odiv;": '\U00002A38', - "odot;": '\U00002299', - "odsold;": '\U000029BC', - "oelig;": '\U00000153', - "ofcir;": '\U000029BF', - "ofr;": '\U0001D52C', - "ogon;": '\U000002DB', - "ograve;": '\U000000F2', - "ogt;": '\U000029C1', - "ohbar;": '\U000029B5', - "ohm;": '\U000003A9', - "oint;": '\U0000222E', - "olarr;": '\U000021BA', - "olcir;": '\U000029BE', - "olcross;": '\U000029BB', - "oline;": '\U0000203E', - "olt;": '\U000029C0', - "omacr;": '\U0000014D', - "omega;": '\U000003C9', - "omicron;": '\U000003BF', - "omid;": '\U000029B6', - "ominus;": '\U00002296', - "oopf;": '\U0001D560', - "opar;": '\U000029B7', - "operp;": '\U000029B9', - "oplus;": '\U00002295', - "or;": '\U00002228', - "orarr;": '\U000021BB', - "ord;": '\U00002A5D', - "order;": '\U00002134', - "orderof;": '\U00002134', - "ordf;": '\U000000AA', - "ordm;": '\U000000BA', - "origof;": '\U000022B6', - "oror;": '\U00002A56', - "orslope;": '\U00002A57', - "orv;": '\U00002A5B', - "oscr;": '\U00002134', - "oslash;": '\U000000F8', - "osol;": '\U00002298', - "otilde;": '\U000000F5', - "otimes;": '\U00002297', - "otimesas;": '\U00002A36', - "ouml;": '\U000000F6', - "ovbar;": '\U0000233D', - "par;": '\U00002225', - "para;": '\U000000B6', - "parallel;": '\U00002225', - "parsim;": '\U00002AF3', - "parsl;": '\U00002AFD', - "part;": '\U00002202', - "pcy;": '\U0000043F', - "percnt;": '\U00000025', - "period;": '\U0000002E', - "permil;": '\U00002030', - "perp;": '\U000022A5', - "pertenk;": '\U00002031', - "pfr;": '\U0001D52D', - "phi;": '\U000003C6', - "phiv;": '\U000003D5', - "phmmat;": '\U00002133', - "phone;": '\U0000260E', - "pi;": '\U000003C0', - "pitchfork;": '\U000022D4', - "piv;": '\U000003D6', - "planck;": '\U0000210F', - "planckh;": '\U0000210E', - "plankv;": '\U0000210F', - "plus;": '\U0000002B', - "plusacir;": '\U00002A23', - "plusb;": '\U0000229E', - "pluscir;": '\U00002A22', - "plusdo;": '\U00002214', - "plusdu;": '\U00002A25', - "pluse;": '\U00002A72', - "plusmn;": '\U000000B1', - "plussim;": '\U00002A26', - "plustwo;": '\U00002A27', - "pm;": '\U000000B1', - "pointint;": '\U00002A15', - "popf;": '\U0001D561', - "pound;": '\U000000A3', - "pr;": '\U0000227A', - "prE;": '\U00002AB3', - "prap;": '\U00002AB7', - "prcue;": '\U0000227C', - "pre;": '\U00002AAF', - "prec;": '\U0000227A', - "precapprox;": '\U00002AB7', - "preccurlyeq;": '\U0000227C', - "preceq;": '\U00002AAF', - "precnapprox;": '\U00002AB9', - "precneqq;": '\U00002AB5', - "precnsim;": '\U000022E8', - "precsim;": '\U0000227E', - "prime;": '\U00002032', - "primes;": '\U00002119', - "prnE;": '\U00002AB5', - "prnap;": '\U00002AB9', - "prnsim;": '\U000022E8', - "prod;": '\U0000220F', - "profalar;": '\U0000232E', - "profline;": '\U00002312', - "profsurf;": '\U00002313', - "prop;": '\U0000221D', - "propto;": '\U0000221D', - "prsim;": '\U0000227E', - "prurel;": '\U000022B0', - "pscr;": '\U0001D4C5', - "psi;": '\U000003C8', - "puncsp;": '\U00002008', - "qfr;": '\U0001D52E', - "qint;": '\U00002A0C', - "qopf;": '\U0001D562', - "qprime;": '\U00002057', - "qscr;": '\U0001D4C6', - "quaternions;": '\U0000210D', - "quatint;": '\U00002A16', - "quest;": '\U0000003F', - "questeq;": '\U0000225F', - "quot;": '\U00000022', - "rAarr;": '\U000021DB', - "rArr;": '\U000021D2', - "rAtail;": '\U0000291C', - "rBarr;": '\U0000290F', - "rHar;": '\U00002964', - "racute;": '\U00000155', - "radic;": '\U0000221A', - "raemptyv;": '\U000029B3', - "rang;": '\U000027E9', - "rangd;": '\U00002992', - "range;": '\U000029A5', - "rangle;": '\U000027E9', - "raquo;": '\U000000BB', - "rarr;": '\U00002192', - "rarrap;": '\U00002975', - "rarrb;": '\U000021E5', - "rarrbfs;": '\U00002920', - "rarrc;": '\U00002933', - "rarrfs;": '\U0000291E', - "rarrhk;": '\U000021AA', - "rarrlp;": '\U000021AC', - "rarrpl;": '\U00002945', - "rarrsim;": '\U00002974', - "rarrtl;": '\U000021A3', - "rarrw;": '\U0000219D', - "ratail;": '\U0000291A', - "ratio;": '\U00002236', - "rationals;": '\U0000211A', - "rbarr;": '\U0000290D', - "rbbrk;": '\U00002773', - "rbrace;": '\U0000007D', - "rbrack;": '\U0000005D', - "rbrke;": '\U0000298C', - "rbrksld;": '\U0000298E', - "rbrkslu;": '\U00002990', - "rcaron;": '\U00000159', - "rcedil;": '\U00000157', - "rceil;": '\U00002309', - "rcub;": '\U0000007D', - "rcy;": '\U00000440', - "rdca;": '\U00002937', - "rdldhar;": '\U00002969', - "rdquo;": '\U0000201D', - "rdquor;": '\U0000201D', - "rdsh;": '\U000021B3', - "real;": '\U0000211C', - "realine;": '\U0000211B', - "realpart;": '\U0000211C', - "reals;": '\U0000211D', - "rect;": '\U000025AD', - "reg;": '\U000000AE', - "rfisht;": '\U0000297D', - "rfloor;": '\U0000230B', - "rfr;": '\U0001D52F', - "rhard;": '\U000021C1', - "rharu;": '\U000021C0', - "rharul;": '\U0000296C', - "rho;": '\U000003C1', - "rhov;": '\U000003F1', - "rightarrow;": '\U00002192', - "rightarrowtail;": '\U000021A3', - "rightharpoondown;": '\U000021C1', - "rightharpoonup;": '\U000021C0', - "rightleftarrows;": '\U000021C4', - "rightleftharpoons;": '\U000021CC', - "rightrightarrows;": '\U000021C9', - "rightsquigarrow;": '\U0000219D', - "rightthreetimes;": '\U000022CC', - "ring;": '\U000002DA', - "risingdotseq;": '\U00002253', - "rlarr;": '\U000021C4', - "rlhar;": '\U000021CC', - "rlm;": '\U0000200F', - "rmoust;": '\U000023B1', - "rmoustache;": '\U000023B1', - "rnmid;": '\U00002AEE', - "roang;": '\U000027ED', - "roarr;": '\U000021FE', - "robrk;": '\U000027E7', - "ropar;": '\U00002986', - "ropf;": '\U0001D563', - "roplus;": '\U00002A2E', - "rotimes;": '\U00002A35', - "rpar;": '\U00000029', - "rpargt;": '\U00002994', - "rppolint;": '\U00002A12', - "rrarr;": '\U000021C9', - "rsaquo;": '\U0000203A', - "rscr;": '\U0001D4C7', - "rsh;": '\U000021B1', - "rsqb;": '\U0000005D', - "rsquo;": '\U00002019', - "rsquor;": '\U00002019', - "rthree;": '\U000022CC', - "rtimes;": '\U000022CA', - "rtri;": '\U000025B9', - "rtrie;": '\U000022B5', - "rtrif;": '\U000025B8', - "rtriltri;": '\U000029CE', - "ruluhar;": '\U00002968', - "rx;": '\U0000211E', - "sacute;": '\U0000015B', - "sbquo;": '\U0000201A', - "sc;": '\U0000227B', - "scE;": '\U00002AB4', - "scap;": '\U00002AB8', - "scaron;": '\U00000161', - "sccue;": '\U0000227D', - "sce;": '\U00002AB0', - "scedil;": '\U0000015F', - "scirc;": '\U0000015D', - "scnE;": '\U00002AB6', - "scnap;": '\U00002ABA', - "scnsim;": '\U000022E9', - "scpolint;": '\U00002A13', - "scsim;": '\U0000227F', - "scy;": '\U00000441', - "sdot;": '\U000022C5', - "sdotb;": '\U000022A1', - "sdote;": '\U00002A66', - "seArr;": '\U000021D8', - "searhk;": '\U00002925', - "searr;": '\U00002198', - "searrow;": '\U00002198', - "sect;": '\U000000A7', - "semi;": '\U0000003B', - "seswar;": '\U00002929', - "setminus;": '\U00002216', - "setmn;": '\U00002216', - "sext;": '\U00002736', - "sfr;": '\U0001D530', - "sfrown;": '\U00002322', - "sharp;": '\U0000266F', - "shchcy;": '\U00000449', - "shcy;": '\U00000448', - "shortmid;": '\U00002223', - "shortparallel;": '\U00002225', - "shy;": '\U000000AD', - "sigma;": '\U000003C3', - "sigmaf;": '\U000003C2', - "sigmav;": '\U000003C2', - "sim;": '\U0000223C', - "simdot;": '\U00002A6A', - "sime;": '\U00002243', - "simeq;": '\U00002243', - "simg;": '\U00002A9E', - "simgE;": '\U00002AA0', - "siml;": '\U00002A9D', - "simlE;": '\U00002A9F', - "simne;": '\U00002246', - "simplus;": '\U00002A24', - "simrarr;": '\U00002972', - "slarr;": '\U00002190', - "smallsetminus;": '\U00002216', - "smashp;": '\U00002A33', - "smeparsl;": '\U000029E4', - "smid;": '\U00002223', - "smile;": '\U00002323', - "smt;": '\U00002AAA', - "smte;": '\U00002AAC', - "softcy;": '\U0000044C', - "sol;": '\U0000002F', - "solb;": '\U000029C4', - "solbar;": '\U0000233F', - "sopf;": '\U0001D564', - "spades;": '\U00002660', - "spadesuit;": '\U00002660', - "spar;": '\U00002225', - "sqcap;": '\U00002293', - "sqcup;": '\U00002294', - "sqsub;": '\U0000228F', - "sqsube;": '\U00002291', - "sqsubset;": '\U0000228F', - "sqsubseteq;": '\U00002291', - "sqsup;": '\U00002290', - "sqsupe;": '\U00002292', - "sqsupset;": '\U00002290', - "sqsupseteq;": '\U00002292', - "squ;": '\U000025A1', - "square;": '\U000025A1', - "squarf;": '\U000025AA', - "squf;": '\U000025AA', - "srarr;": '\U00002192', - "sscr;": '\U0001D4C8', - "ssetmn;": '\U00002216', - "ssmile;": '\U00002323', - "sstarf;": '\U000022C6', - "star;": '\U00002606', - "starf;": '\U00002605', - "straightepsilon;": '\U000003F5', - "straightphi;": '\U000003D5', - "strns;": '\U000000AF', - "sub;": '\U00002282', - "subE;": '\U00002AC5', - "subdot;": '\U00002ABD', - "sube;": '\U00002286', - "subedot;": '\U00002AC3', - "submult;": '\U00002AC1', - "subnE;": '\U00002ACB', - "subne;": '\U0000228A', - "subplus;": '\U00002ABF', - "subrarr;": '\U00002979', - "subset;": '\U00002282', - "subseteq;": '\U00002286', - "subseteqq;": '\U00002AC5', - "subsetneq;": '\U0000228A', - "subsetneqq;": '\U00002ACB', - "subsim;": '\U00002AC7', - "subsub;": '\U00002AD5', - "subsup;": '\U00002AD3', - "succ;": '\U0000227B', - "succapprox;": '\U00002AB8', - "succcurlyeq;": '\U0000227D', - "succeq;": '\U00002AB0', - "succnapprox;": '\U00002ABA', - "succneqq;": '\U00002AB6', - "succnsim;": '\U000022E9', - "succsim;": '\U0000227F', - "sum;": '\U00002211', - "sung;": '\U0000266A', - "sup;": '\U00002283', - "sup1;": '\U000000B9', - "sup2;": '\U000000B2', - "sup3;": '\U000000B3', - "supE;": '\U00002AC6', - "supdot;": '\U00002ABE', - "supdsub;": '\U00002AD8', - "supe;": '\U00002287', - "supedot;": '\U00002AC4', - "suphsol;": '\U000027C9', - "suphsub;": '\U00002AD7', - "suplarr;": '\U0000297B', - "supmult;": '\U00002AC2', - "supnE;": '\U00002ACC', - "supne;": '\U0000228B', - "supplus;": '\U00002AC0', - "supset;": '\U00002283', - "supseteq;": '\U00002287', - "supseteqq;": '\U00002AC6', - "supsetneq;": '\U0000228B', - "supsetneqq;": '\U00002ACC', - "supsim;": '\U00002AC8', - "supsub;": '\U00002AD4', - "supsup;": '\U00002AD6', - "swArr;": '\U000021D9', - "swarhk;": '\U00002926', - "swarr;": '\U00002199', - "swarrow;": '\U00002199', - "swnwar;": '\U0000292A', - "szlig;": '\U000000DF', - "target;": '\U00002316', - "tau;": '\U000003C4', - "tbrk;": '\U000023B4', - "tcaron;": '\U00000165', - "tcedil;": '\U00000163', - "tcy;": '\U00000442', - "tdot;": '\U000020DB', - "telrec;": '\U00002315', - "tfr;": '\U0001D531', - "there4;": '\U00002234', - "therefore;": '\U00002234', - "theta;": '\U000003B8', - "thetasym;": '\U000003D1', - "thetav;": '\U000003D1', - "thickapprox;": '\U00002248', - "thicksim;": '\U0000223C', - "thinsp;": '\U00002009', - "thkap;": '\U00002248', - "thksim;": '\U0000223C', - "thorn;": '\U000000FE', - "tilde;": '\U000002DC', - "times;": '\U000000D7', - "timesb;": '\U000022A0', - "timesbar;": '\U00002A31', - "timesd;": '\U00002A30', - "tint;": '\U0000222D', - "toea;": '\U00002928', - "top;": '\U000022A4', - "topbot;": '\U00002336', - "topcir;": '\U00002AF1', - "topf;": '\U0001D565', - "topfork;": '\U00002ADA', - "tosa;": '\U00002929', - "tprime;": '\U00002034', - "trade;": '\U00002122', - "triangle;": '\U000025B5', - "triangledown;": '\U000025BF', - "triangleleft;": '\U000025C3', - "trianglelefteq;": '\U000022B4', - "triangleq;": '\U0000225C', - "triangleright;": '\U000025B9', - "trianglerighteq;": '\U000022B5', - "tridot;": '\U000025EC', - "trie;": '\U0000225C', - "triminus;": '\U00002A3A', - "triplus;": '\U00002A39', - "trisb;": '\U000029CD', - "tritime;": '\U00002A3B', - "trpezium;": '\U000023E2', - "tscr;": '\U0001D4C9', - "tscy;": '\U00000446', - "tshcy;": '\U0000045B', - "tstrok;": '\U00000167', - "twixt;": '\U0000226C', - "twoheadleftarrow;": '\U0000219E', - "twoheadrightarrow;": '\U000021A0', - "uArr;": '\U000021D1', - "uHar;": '\U00002963', - "uacute;": '\U000000FA', - "uarr;": '\U00002191', - "ubrcy;": '\U0000045E', - "ubreve;": '\U0000016D', - "ucirc;": '\U000000FB', - "ucy;": '\U00000443', - "udarr;": '\U000021C5', - "udblac;": '\U00000171', - "udhar;": '\U0000296E', - "ufisht;": '\U0000297E', - "ufr;": '\U0001D532', - "ugrave;": '\U000000F9', - "uharl;": '\U000021BF', - "uharr;": '\U000021BE', - "uhblk;": '\U00002580', - "ulcorn;": '\U0000231C', - "ulcorner;": '\U0000231C', - "ulcrop;": '\U0000230F', - "ultri;": '\U000025F8', - "umacr;": '\U0000016B', - "uml;": '\U000000A8', - "uogon;": '\U00000173', - "uopf;": '\U0001D566', - "uparrow;": '\U00002191', - "updownarrow;": '\U00002195', - "upharpoonleft;": '\U000021BF', - "upharpoonright;": '\U000021BE', - "uplus;": '\U0000228E', - "upsi;": '\U000003C5', - "upsih;": '\U000003D2', - "upsilon;": '\U000003C5', - "upuparrows;": '\U000021C8', - "urcorn;": '\U0000231D', - "urcorner;": '\U0000231D', - "urcrop;": '\U0000230E', - "uring;": '\U0000016F', - "urtri;": '\U000025F9', - "uscr;": '\U0001D4CA', - "utdot;": '\U000022F0', - "utilde;": '\U00000169', - "utri;": '\U000025B5', - "utrif;": '\U000025B4', - "uuarr;": '\U000021C8', - "uuml;": '\U000000FC', - "uwangle;": '\U000029A7', - "vArr;": '\U000021D5', - "vBar;": '\U00002AE8', - "vBarv;": '\U00002AE9', - "vDash;": '\U000022A8', - "vangrt;": '\U0000299C', - "varepsilon;": '\U000003F5', - "varkappa;": '\U000003F0', - "varnothing;": '\U00002205', - "varphi;": '\U000003D5', - "varpi;": '\U000003D6', - "varpropto;": '\U0000221D', - "varr;": '\U00002195', - "varrho;": '\U000003F1', - "varsigma;": '\U000003C2', - "vartheta;": '\U000003D1', - "vartriangleleft;": '\U000022B2', - "vartriangleright;": '\U000022B3', - "vcy;": '\U00000432', - "vdash;": '\U000022A2', - "vee;": '\U00002228', - "veebar;": '\U000022BB', - "veeeq;": '\U0000225A', - "vellip;": '\U000022EE', - "verbar;": '\U0000007C', - "vert;": '\U0000007C', - "vfr;": '\U0001D533', - "vltri;": '\U000022B2', - "vopf;": '\U0001D567', - "vprop;": '\U0000221D', - "vrtri;": '\U000022B3', - "vscr;": '\U0001D4CB', - "vzigzag;": '\U0000299A', - "wcirc;": '\U00000175', - "wedbar;": '\U00002A5F', - "wedge;": '\U00002227', - "wedgeq;": '\U00002259', - "weierp;": '\U00002118', - "wfr;": '\U0001D534', - "wopf;": '\U0001D568', - "wp;": '\U00002118', - "wr;": '\U00002240', - "wreath;": '\U00002240', - "wscr;": '\U0001D4CC', - "xcap;": '\U000022C2', - "xcirc;": '\U000025EF', - "xcup;": '\U000022C3', - "xdtri;": '\U000025BD', - "xfr;": '\U0001D535', - "xhArr;": '\U000027FA', - "xharr;": '\U000027F7', - "xi;": '\U000003BE', - "xlArr;": '\U000027F8', - "xlarr;": '\U000027F5', - "xmap;": '\U000027FC', - "xnis;": '\U000022FB', - "xodot;": '\U00002A00', - "xopf;": '\U0001D569', - "xoplus;": '\U00002A01', - "xotime;": '\U00002A02', - "xrArr;": '\U000027F9', - "xrarr;": '\U000027F6', - "xscr;": '\U0001D4CD', - "xsqcup;": '\U00002A06', - "xuplus;": '\U00002A04', - "xutri;": '\U000025B3', - "xvee;": '\U000022C1', - "xwedge;": '\U000022C0', - "yacute;": '\U000000FD', - "yacy;": '\U0000044F', - "ycirc;": '\U00000177', - "ycy;": '\U0000044B', - "yen;": '\U000000A5', - "yfr;": '\U0001D536', - "yicy;": '\U00000457', - "yopf;": '\U0001D56A', - "yscr;": '\U0001D4CE', - "yucy;": '\U0000044E', - "yuml;": '\U000000FF', - "zacute;": '\U0000017A', - "zcaron;": '\U0000017E', - "zcy;": '\U00000437', - "zdot;": '\U0000017C', - "zeetrf;": '\U00002128', - "zeta;": '\U000003B6', - "zfr;": '\U0001D537', - "zhcy;": '\U00000436', - "zigrarr;": '\U000021DD', - "zopf;": '\U0001D56B', - "zscr;": '\U0001D4CF', - "zwj;": '\U0000200D', - "zwnj;": '\U0000200C', - "AElig": '\U000000C6', - "AMP": '\U00000026', - "Aacute": '\U000000C1', - "Acirc": '\U000000C2', - "Agrave": '\U000000C0', - "Aring": '\U000000C5', - "Atilde": '\U000000C3', - "Auml": '\U000000C4', - "COPY": '\U000000A9', - "Ccedil": '\U000000C7', - "ETH": '\U000000D0', - "Eacute": '\U000000C9', - "Ecirc": '\U000000CA', - "Egrave": '\U000000C8', - "Euml": '\U000000CB', - "GT": '\U0000003E', - "Iacute": '\U000000CD', - "Icirc": '\U000000CE', - "Igrave": '\U000000CC', - "Iuml": '\U000000CF', - "LT": '\U0000003C', - "Ntilde": '\U000000D1', - "Oacute": '\U000000D3', - "Ocirc": '\U000000D4', - "Ograve": '\U000000D2', - "Oslash": '\U000000D8', - "Otilde": '\U000000D5', - "Ouml": '\U000000D6', - "QUOT": '\U00000022', - "REG": '\U000000AE', - "THORN": '\U000000DE', - "Uacute": '\U000000DA', - "Ucirc": '\U000000DB', - "Ugrave": '\U000000D9', - "Uuml": '\U000000DC', - "Yacute": '\U000000DD', - "aacute": '\U000000E1', - "acirc": '\U000000E2', - "acute": '\U000000B4', - "aelig": '\U000000E6', - "agrave": '\U000000E0', - "amp": '\U00000026', - "aring": '\U000000E5', - "atilde": '\U000000E3', - "auml": '\U000000E4', - "brvbar": '\U000000A6', - "ccedil": '\U000000E7', - "cedil": '\U000000B8', - "cent": '\U000000A2', - "copy": '\U000000A9', - "curren": '\U000000A4', - "deg": '\U000000B0', - "divide": '\U000000F7', - "eacute": '\U000000E9', - "ecirc": '\U000000EA', - "egrave": '\U000000E8', - "eth": '\U000000F0', - "euml": '\U000000EB', - "frac12": '\U000000BD', - "frac14": '\U000000BC', - "frac34": '\U000000BE', - "gt": '\U0000003E', - "iacute": '\U000000ED', - "icirc": '\U000000EE', - "iexcl": '\U000000A1', - "igrave": '\U000000EC', - "iquest": '\U000000BF', - "iuml": '\U000000EF', - "laquo": '\U000000AB', - "lt": '\U0000003C', - "macr": '\U000000AF', - "micro": '\U000000B5', - "middot": '\U000000B7', - "nbsp": '\U000000A0', - "not": '\U000000AC', - "ntilde": '\U000000F1', - "oacute": '\U000000F3', - "ocirc": '\U000000F4', - "ograve": '\U000000F2', - "ordf": '\U000000AA', - "ordm": '\U000000BA', - "oslash": '\U000000F8', - "otilde": '\U000000F5', - "ouml": '\U000000F6', - "para": '\U000000B6', - "plusmn": '\U000000B1', - "pound": '\U000000A3', - "quot": '\U00000022', - "raquo": '\U000000BB', - "reg": '\U000000AE', - "sect": '\U000000A7', - "shy": '\U000000AD', - "sup1": '\U000000B9', - "sup2": '\U000000B2', - "sup3": '\U000000B3', - "szlig": '\U000000DF', - "thorn": '\U000000FE', - "times": '\U000000D7', - "uacute": '\U000000FA', - "ucirc": '\U000000FB', - "ugrave": '\U000000F9', - "uml": '\U000000A8', - "uuml": '\U000000FC', - "yacute": '\U000000FD', - "yen": '\U000000A5', - "yuml": '\U000000FF', -} - -// HTML entities that are two unicode codepoints. -var entity2 = map[string][2]rune{ - // TODO(nigeltao): Handle replacements that are wider than their names. - // "nLt;": {'\u226A', '\u20D2'}, - // "nGt;": {'\u226B', '\u20D2'}, - "NotEqualTilde;": {'\u2242', '\u0338'}, - "NotGreaterFullEqual;": {'\u2267', '\u0338'}, - "NotGreaterGreater;": {'\u226B', '\u0338'}, - "NotGreaterSlantEqual;": {'\u2A7E', '\u0338'}, - "NotHumpDownHump;": {'\u224E', '\u0338'}, - "NotHumpEqual;": {'\u224F', '\u0338'}, - "NotLeftTriangleBar;": {'\u29CF', '\u0338'}, - "NotLessLess;": {'\u226A', '\u0338'}, - "NotLessSlantEqual;": {'\u2A7D', '\u0338'}, - "NotNestedGreaterGreater;": {'\u2AA2', '\u0338'}, - "NotNestedLessLess;": {'\u2AA1', '\u0338'}, - "NotPrecedesEqual;": {'\u2AAF', '\u0338'}, - "NotRightTriangleBar;": {'\u29D0', '\u0338'}, - "NotSquareSubset;": {'\u228F', '\u0338'}, - "NotSquareSuperset;": {'\u2290', '\u0338'}, - "NotSubset;": {'\u2282', '\u20D2'}, - "NotSucceedsEqual;": {'\u2AB0', '\u0338'}, - "NotSucceedsTilde;": {'\u227F', '\u0338'}, - "NotSuperset;": {'\u2283', '\u20D2'}, - "ThickSpace;": {'\u205F', '\u200A'}, - "acE;": {'\u223E', '\u0333'}, - "bne;": {'\u003D', '\u20E5'}, - "bnequiv;": {'\u2261', '\u20E5'}, - "caps;": {'\u2229', '\uFE00'}, - "cups;": {'\u222A', '\uFE00'}, - "fjlig;": {'\u0066', '\u006A'}, - "gesl;": {'\u22DB', '\uFE00'}, - "gvertneqq;": {'\u2269', '\uFE00'}, - "gvnE;": {'\u2269', '\uFE00'}, - "lates;": {'\u2AAD', '\uFE00'}, - "lesg;": {'\u22DA', '\uFE00'}, - "lvertneqq;": {'\u2268', '\uFE00'}, - "lvnE;": {'\u2268', '\uFE00'}, - "nGg;": {'\u22D9', '\u0338'}, - "nGtv;": {'\u226B', '\u0338'}, - "nLl;": {'\u22D8', '\u0338'}, - "nLtv;": {'\u226A', '\u0338'}, - "nang;": {'\u2220', '\u20D2'}, - "napE;": {'\u2A70', '\u0338'}, - "napid;": {'\u224B', '\u0338'}, - "nbump;": {'\u224E', '\u0338'}, - "nbumpe;": {'\u224F', '\u0338'}, - "ncongdot;": {'\u2A6D', '\u0338'}, - "nedot;": {'\u2250', '\u0338'}, - "nesim;": {'\u2242', '\u0338'}, - "ngE;": {'\u2267', '\u0338'}, - "ngeqq;": {'\u2267', '\u0338'}, - "ngeqslant;": {'\u2A7E', '\u0338'}, - "nges;": {'\u2A7E', '\u0338'}, - "nlE;": {'\u2266', '\u0338'}, - "nleqq;": {'\u2266', '\u0338'}, - "nleqslant;": {'\u2A7D', '\u0338'}, - "nles;": {'\u2A7D', '\u0338'}, - "notinE;": {'\u22F9', '\u0338'}, - "notindot;": {'\u22F5', '\u0338'}, - "nparsl;": {'\u2AFD', '\u20E5'}, - "npart;": {'\u2202', '\u0338'}, - "npre;": {'\u2AAF', '\u0338'}, - "npreceq;": {'\u2AAF', '\u0338'}, - "nrarrc;": {'\u2933', '\u0338'}, - "nrarrw;": {'\u219D', '\u0338'}, - "nsce;": {'\u2AB0', '\u0338'}, - "nsubE;": {'\u2AC5', '\u0338'}, - "nsubset;": {'\u2282', '\u20D2'}, - "nsubseteqq;": {'\u2AC5', '\u0338'}, - "nsucceq;": {'\u2AB0', '\u0338'}, - "nsupE;": {'\u2AC6', '\u0338'}, - "nsupset;": {'\u2283', '\u20D2'}, - "nsupseteqq;": {'\u2AC6', '\u0338'}, - "nvap;": {'\u224D', '\u20D2'}, - "nvge;": {'\u2265', '\u20D2'}, - "nvgt;": {'\u003E', '\u20D2'}, - "nvle;": {'\u2264', '\u20D2'}, - "nvlt;": {'\u003C', '\u20D2'}, - "nvltrie;": {'\u22B4', '\u20D2'}, - "nvrtrie;": {'\u22B5', '\u20D2'}, - "nvsim;": {'\u223C', '\u20D2'}, - "race;": {'\u223D', '\u0331'}, - "smtes;": {'\u2AAC', '\uFE00'}, - "sqcaps;": {'\u2293', '\uFE00'}, - "sqcups;": {'\u2294', '\uFE00'}, - "varsubsetneq;": {'\u228A', '\uFE00'}, - "varsubsetneqq;": {'\u2ACB', '\uFE00'}, - "varsupsetneq;": {'\u228B', '\uFE00'}, - "varsupsetneqq;": {'\u2ACC', '\uFE00'}, - "vnsub;": {'\u2282', '\u20D2'}, - "vnsup;": {'\u2283', '\u20D2'}, - "vsubnE;": {'\u2ACB', '\uFE00'}, - "vsubne;": {'\u228A', '\uFE00'}, - "vsupnE;": {'\u2ACC', '\uFE00'}, - "vsupne;": {'\u228B', '\uFE00'}, -} diff --git a/_third_party/golang.org/x/net/html/entity_test.go b/_third_party/golang.org/x/net/html/entity_test.go deleted file mode 100644 index b53f866f..00000000 --- a/_third_party/golang.org/x/net/html/entity_test.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "testing" - "unicode/utf8" -) - -func TestEntityLength(t *testing.T) { - // We verify that the length of UTF-8 encoding of each value is <= 1 + len(key). - // The +1 comes from the leading "&". This property implies that the length of - // unescaped text is <= the length of escaped text. - for k, v := range entity { - if 1+len(k) < utf8.RuneLen(v) { - t.Error("escaped entity &" + k + " is shorter than its UTF-8 encoding " + string(v)) - } - if len(k) > longestEntityWithoutSemicolon && k[len(k)-1] != ';' { - t.Errorf("entity name %s is %d characters, but longestEntityWithoutSemicolon=%d", k, len(k), longestEntityWithoutSemicolon) - } - } - for k, v := range entity2 { - if 1+len(k) < utf8.RuneLen(v[0])+utf8.RuneLen(v[1]) { - t.Error("escaped entity &" + k + " is shorter than its UTF-8 encoding " + string(v[0]) + string(v[1])) - } - } -} diff --git a/_third_party/golang.org/x/net/html/escape.go b/_third_party/golang.org/x/net/html/escape.go deleted file mode 100644 index d8561396..00000000 --- a/_third_party/golang.org/x/net/html/escape.go +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "bytes" - "strings" - "unicode/utf8" -) - -// These replacements permit compatibility with old numeric entities that -// assumed Windows-1252 encoding. -// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference -var replacementTable = [...]rune{ - '\u20AC', // First entry is what 0x80 should be replaced with. - '\u0081', - '\u201A', - '\u0192', - '\u201E', - '\u2026', - '\u2020', - '\u2021', - '\u02C6', - '\u2030', - '\u0160', - '\u2039', - '\u0152', - '\u008D', - '\u017D', - '\u008F', - '\u0090', - '\u2018', - '\u2019', - '\u201C', - '\u201D', - '\u2022', - '\u2013', - '\u2014', - '\u02DC', - '\u2122', - '\u0161', - '\u203A', - '\u0153', - '\u009D', - '\u017E', - '\u0178', // Last entry is 0x9F. - // 0x00->'\uFFFD' is handled programmatically. - // 0x0D->'\u000D' is a no-op. -} - -// unescapeEntity reads an entity like "<" from b[src:] and writes the -// corresponding "<" to b[dst:], returning the incremented dst and src cursors. -// Precondition: b[src] == '&' && dst <= src. -// attribute should be true if parsing an attribute value. -func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) { - // https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference - - // i starts at 1 because we already know that s[0] == '&'. - i, s := 1, b[src:] - - if len(s) <= 1 { - b[dst] = b[src] - return dst + 1, src + 1 - } - - if s[i] == '#' { - if len(s) <= 3 { // We need to have at least "&#.". - b[dst] = b[src] - return dst + 1, src + 1 - } - i++ - c := s[i] - hex := false - if c == 'x' || c == 'X' { - hex = true - i++ - } - - x := '\x00' - for i < len(s) { - c = s[i] - i++ - if hex { - if '0' <= c && c <= '9' { - x = 16*x + rune(c) - '0' - continue - } else if 'a' <= c && c <= 'f' { - x = 16*x + rune(c) - 'a' + 10 - continue - } else if 'A' <= c && c <= 'F' { - x = 16*x + rune(c) - 'A' + 10 - continue - } - } else if '0' <= c && c <= '9' { - x = 10*x + rune(c) - '0' - continue - } - if c != ';' { - i-- - } - break - } - - if i <= 3 { // No characters matched. - b[dst] = b[src] - return dst + 1, src + 1 - } - - if 0x80 <= x && x <= 0x9F { - // Replace characters from Windows-1252 with UTF-8 equivalents. - x = replacementTable[x-0x80] - } else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF { - // Replace invalid characters with the replacement character. - x = '\uFFFD' - } - - return dst + utf8.EncodeRune(b[dst:], x), src + i - } - - // Consume the maximum number of characters possible, with the - // consumed characters matching one of the named references. - - for i < len(s) { - c := s[i] - i++ - // Lower-cased characters are more common in entities, so we check for them first. - if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { - continue - } - if c != ';' { - i-- - } - break - } - - entityName := string(s[1:i]) - if entityName == "" { - // No-op. - } else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' { - // No-op. - } else if x := entity[entityName]; x != 0 { - return dst + utf8.EncodeRune(b[dst:], x), src + i - } else if x := entity2[entityName]; x[0] != 0 { - dst1 := dst + utf8.EncodeRune(b[dst:], x[0]) - return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i - } else if !attribute { - maxLen := len(entityName) - 1 - if maxLen > longestEntityWithoutSemicolon { - maxLen = longestEntityWithoutSemicolon - } - for j := maxLen; j > 1; j-- { - if x := entity[entityName[:j]]; x != 0 { - return dst + utf8.EncodeRune(b[dst:], x), src + j + 1 - } - } - } - - dst1, src1 = dst+i, src+i - copy(b[dst:dst1], b[src:src1]) - return dst1, src1 -} - -// unescape unescapes b's entities in-place, so that "a<b" becomes "a': - esc = ">" - case '"': - // """ is shorter than """. - esc = """ - case '\r': - esc = " " - default: - panic("unrecognized escape character") - } - s = s[i+1:] - if _, err := w.WriteString(esc); err != nil { - return err - } - i = strings.IndexAny(s, escapedChars) - } - _, err := w.WriteString(s) - return err -} - -// EscapeString escapes special characters like "<" to become "<". It -// escapes only five such characters: <, >, &, ' and ". -// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't -// always true. -func EscapeString(s string) string { - if strings.IndexAny(s, escapedChars) == -1 { - return s - } - var buf bytes.Buffer - escape(&buf, s) - return buf.String() -} - -// UnescapeString unescapes entities like "<" to become "<". It unescapes a -// larger range of entities than EscapeString escapes. For example, "á" -// unescapes to "á", as does "á" and "&xE1;". -// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't -// always true. -func UnescapeString(s string) string { - for _, c := range s { - if c == '&' { - return string(unescape([]byte(s), false)) - } - } - return s -} diff --git a/_third_party/golang.org/x/net/html/escape_test.go b/_third_party/golang.org/x/net/html/escape_test.go deleted file mode 100644 index b405d4b4..00000000 --- a/_third_party/golang.org/x/net/html/escape_test.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import "testing" - -type unescapeTest struct { - // A short description of the test case. - desc string - // The HTML text. - html string - // The unescaped text. - unescaped string -} - -var unescapeTests = []unescapeTest{ - // Handle no entities. - { - "copy", - "A\ttext\nstring", - "A\ttext\nstring", - }, - // Handle simple named entities. - { - "simple", - "& > <", - "& > <", - }, - // Handle hitting the end of the string. - { - "stringEnd", - "& &", - "& &", - }, - // Handle entities with two codepoints. - { - "multiCodepoint", - "text ⋛︀ blah", - "text \u22db\ufe00 blah", - }, - // Handle decimal numeric entities. - { - "decimalEntity", - "Delta = Δ ", - "Delta = Δ ", - }, - // Handle hexadecimal numeric entities. - { - "hexadecimalEntity", - "Lambda = λ = λ ", - "Lambda = λ = λ ", - }, - // Handle numeric early termination. - { - "numericEnds", - "&# &#x €43 © = ©f = ©", - "&# &#x €43 © = ©f = ©", - }, - // Handle numeric ISO-8859-1 entity replacements. - { - "numericReplacements", - "Footnote‡", - "Footnote‡", - }, -} - -func TestUnescape(t *testing.T) { - for _, tt := range unescapeTests { - unescaped := UnescapeString(tt.html) - if unescaped != tt.unescaped { - t.Errorf("TestUnescape %s: want %q, got %q", tt.desc, tt.unescaped, unescaped) - } - } -} - -func TestUnescapeEscape(t *testing.T) { - ss := []string{ - ``, - `abc def`, - `a & b`, - `a&b`, - `a & b`, - `"`, - `"`, - `"<&>"`, - `"<&>"`, - `3&5==1 && 0<1, "0<1", a+acute=á`, - `The special characters are: <, >, &, ' and "`, - } - for _, s := range ss { - if got := UnescapeString(EscapeString(s)); got != s { - t.Errorf("got %q want %q", got, s) - } - } -} diff --git a/_third_party/golang.org/x/net/html/example_test.go b/_third_party/golang.org/x/net/html/example_test.go deleted file mode 100644 index c9e0e738..00000000 --- a/_third_party/golang.org/x/net/html/example_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This example demonstrates parsing HTML data and walking the resulting tree. -package html_test - -import ( - "fmt" - "log" - "strings" - - "github.com/mjibson/goread/_third_party/golang.org/x/net/html" -) - -func ExampleParse() { - s := `

Links:

` - doc, err := html.Parse(strings.NewReader(s)) - if err != nil { - log.Fatal(err) - } - var f func(*html.Node) - f = func(n *html.Node) { - if n.Type == html.ElementNode && n.Data == "a" { - for _, a := range n.Attr { - if a.Key == "href" { - fmt.Println(a.Val) - break - } - } - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - f(c) - } - } - f(doc) - // Output: - // foo - // /bar/baz -} diff --git a/_third_party/golang.org/x/net/html/foreign.go b/_third_party/golang.org/x/net/html/foreign.go deleted file mode 100644 index d3b38440..00000000 --- a/_third_party/golang.org/x/net/html/foreign.go +++ /dev/null @@ -1,226 +0,0 @@ -// 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. - -package html - -import ( - "strings" -) - -func adjustAttributeNames(aa []Attribute, nameMap map[string]string) { - for i := range aa { - if newName, ok := nameMap[aa[i].Key]; ok { - aa[i].Key = newName - } - } -} - -func adjustForeignAttributes(aa []Attribute) { - for i, a := range aa { - if a.Key == "" || a.Key[0] != 'x' { - continue - } - switch a.Key { - case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show", - "xlink:title", "xlink:type", "xml:base", "xml:lang", "xml:space", "xmlns:xlink": - j := strings.Index(a.Key, ":") - aa[i].Namespace = a.Key[:j] - aa[i].Key = a.Key[j+1:] - } - } -} - -func htmlIntegrationPoint(n *Node) bool { - if n.Type != ElementNode { - return false - } - switch n.Namespace { - case "math": - if n.Data == "annotation-xml" { - for _, a := range n.Attr { - if a.Key == "encoding" { - val := strings.ToLower(a.Val) - if val == "text/html" || val == "application/xhtml+xml" { - return true - } - } - } - } - case "svg": - switch n.Data { - case "desc", "foreignObject", "title": - return true - } - } - return false -} - -func mathMLTextIntegrationPoint(n *Node) bool { - if n.Namespace != "math" { - return false - } - switch n.Data { - case "mi", "mo", "mn", "ms", "mtext": - return true - } - return false -} - -// Section 12.2.5.5. -var breakout = map[string]bool{ - "b": true, - "big": true, - "blockquote": true, - "body": true, - "br": true, - "center": true, - "code": true, - "dd": true, - "div": true, - "dl": true, - "dt": true, - "em": true, - "embed": true, - "h1": true, - "h2": true, - "h3": true, - "h4": true, - "h5": true, - "h6": true, - "head": true, - "hr": true, - "i": true, - "img": true, - "li": true, - "listing": true, - "menu": true, - "meta": true, - "nobr": true, - "ol": true, - "p": true, - "pre": true, - "ruby": true, - "s": true, - "small": true, - "span": true, - "strong": true, - "strike": true, - "sub": true, - "sup": true, - "table": true, - "tt": true, - "u": true, - "ul": true, - "var": true, -} - -// Section 12.2.5.5. -var svgTagNameAdjustments = map[string]string{ - "altglyph": "altGlyph", - "altglyphdef": "altGlyphDef", - "altglyphitem": "altGlyphItem", - "animatecolor": "animateColor", - "animatemotion": "animateMotion", - "animatetransform": "animateTransform", - "clippath": "clipPath", - "feblend": "feBlend", - "fecolormatrix": "feColorMatrix", - "fecomponenttransfer": "feComponentTransfer", - "fecomposite": "feComposite", - "feconvolvematrix": "feConvolveMatrix", - "fediffuselighting": "feDiffuseLighting", - "fedisplacementmap": "feDisplacementMap", - "fedistantlight": "feDistantLight", - "feflood": "feFlood", - "fefunca": "feFuncA", - "fefuncb": "feFuncB", - "fefuncg": "feFuncG", - "fefuncr": "feFuncR", - "fegaussianblur": "feGaussianBlur", - "feimage": "feImage", - "femerge": "feMerge", - "femergenode": "feMergeNode", - "femorphology": "feMorphology", - "feoffset": "feOffset", - "fepointlight": "fePointLight", - "fespecularlighting": "feSpecularLighting", - "fespotlight": "feSpotLight", - "fetile": "feTile", - "feturbulence": "feTurbulence", - "foreignobject": "foreignObject", - "glyphref": "glyphRef", - "lineargradient": "linearGradient", - "radialgradient": "radialGradient", - "textpath": "textPath", -} - -// Section 12.2.5.1 -var mathMLAttributeAdjustments = map[string]string{ - "definitionurl": "definitionURL", -} - -var svgAttributeAdjustments = map[string]string{ - "attributename": "attributeName", - "attributetype": "attributeType", - "basefrequency": "baseFrequency", - "baseprofile": "baseProfile", - "calcmode": "calcMode", - "clippathunits": "clipPathUnits", - "contentscripttype": "contentScriptType", - "contentstyletype": "contentStyleType", - "diffuseconstant": "diffuseConstant", - "edgemode": "edgeMode", - "externalresourcesrequired": "externalResourcesRequired", - "filterres": "filterRes", - "filterunits": "filterUnits", - "glyphref": "glyphRef", - "gradienttransform": "gradientTransform", - "gradientunits": "gradientUnits", - "kernelmatrix": "kernelMatrix", - "kernelunitlength": "kernelUnitLength", - "keypoints": "keyPoints", - "keysplines": "keySplines", - "keytimes": "keyTimes", - "lengthadjust": "lengthAdjust", - "limitingconeangle": "limitingConeAngle", - "markerheight": "markerHeight", - "markerunits": "markerUnits", - "markerwidth": "markerWidth", - "maskcontentunits": "maskContentUnits", - "maskunits": "maskUnits", - "numoctaves": "numOctaves", - "pathlength": "pathLength", - "patterncontentunits": "patternContentUnits", - "patterntransform": "patternTransform", - "patternunits": "patternUnits", - "pointsatx": "pointsAtX", - "pointsaty": "pointsAtY", - "pointsatz": "pointsAtZ", - "preservealpha": "preserveAlpha", - "preserveaspectratio": "preserveAspectRatio", - "primitiveunits": "primitiveUnits", - "refx": "refX", - "refy": "refY", - "repeatcount": "repeatCount", - "repeatdur": "repeatDur", - "requiredextensions": "requiredExtensions", - "requiredfeatures": "requiredFeatures", - "specularconstant": "specularConstant", - "specularexponent": "specularExponent", - "spreadmethod": "spreadMethod", - "startoffset": "startOffset", - "stddeviation": "stdDeviation", - "stitchtiles": "stitchTiles", - "surfacescale": "surfaceScale", - "systemlanguage": "systemLanguage", - "tablevalues": "tableValues", - "targetx": "targetX", - "targety": "targetY", - "textlength": "textLength", - "viewbox": "viewBox", - "viewtarget": "viewTarget", - "xchannelselector": "xChannelSelector", - "ychannelselector": "yChannelSelector", - "zoomandpan": "zoomAndPan", -} diff --git a/_third_party/golang.org/x/net/html/node.go b/_third_party/golang.org/x/net/html/node.go deleted file mode 100644 index 1dde7327..00000000 --- a/_third_party/golang.org/x/net/html/node.go +++ /dev/null @@ -1,193 +0,0 @@ -// 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. - -package html - -import ( - "github.com/mjibson/goread/_third_party/golang.org/x/net/html/atom" -) - -// A NodeType is the type of a Node. -type NodeType uint32 - -const ( - ErrorNode NodeType = iota - TextNode - DocumentNode - ElementNode - CommentNode - DoctypeNode - scopeMarkerNode -) - -// Section 12.2.3.3 says "scope markers are inserted when entering applet -// elements, buttons, object elements, marquees, table cells, and table -// captions, and are used to prevent formatting from 'leaking'". -var scopeMarker = Node{Type: scopeMarkerNode} - -// A Node consists of a NodeType and some Data (tag name for element nodes, -// content for text) and are part of a tree of Nodes. Element nodes may also -// have a Namespace and contain a slice of Attributes. Data is unescaped, so -// that it looks like "a 0 { - return (*s)[i-1] - } - return nil -} - -// index returns the index of the top-most occurrence of n in the stack, or -1 -// if n is not present. -func (s *nodeStack) index(n *Node) int { - for i := len(*s) - 1; i >= 0; i-- { - if (*s)[i] == n { - return i - } - } - return -1 -} - -// insert inserts a node at the given index. -func (s *nodeStack) insert(i int, n *Node) { - (*s) = append(*s, nil) - copy((*s)[i+1:], (*s)[i:]) - (*s)[i] = n -} - -// remove removes a node from the stack. It is a no-op if n is not present. -func (s *nodeStack) remove(n *Node) { - i := s.index(n) - if i == -1 { - return - } - copy((*s)[i:], (*s)[i+1:]) - j := len(*s) - 1 - (*s)[j] = nil - *s = (*s)[:j] -} diff --git a/_third_party/golang.org/x/net/html/node_test.go b/_third_party/golang.org/x/net/html/node_test.go deleted file mode 100644 index 471102f3..00000000 --- a/_third_party/golang.org/x/net/html/node_test.go +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "fmt" -) - -// checkTreeConsistency checks that a node and its descendants are all -// consistent in their parent/child/sibling relationships. -func checkTreeConsistency(n *Node) error { - return checkTreeConsistency1(n, 0) -} - -func checkTreeConsistency1(n *Node, depth int) error { - if depth == 1e4 { - return fmt.Errorf("html: tree looks like it contains a cycle") - } - if err := checkNodeConsistency(n); err != nil { - return err - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - if err := checkTreeConsistency1(c, depth+1); err != nil { - return err - } - } - return nil -} - -// checkNodeConsistency checks that a node's parent/child/sibling relationships -// are consistent. -func checkNodeConsistency(n *Node) error { - if n == nil { - return nil - } - - nParent := 0 - for p := n.Parent; p != nil; p = p.Parent { - nParent++ - if nParent == 1e4 { - return fmt.Errorf("html: parent list looks like an infinite loop") - } - } - - nForward := 0 - for c := n.FirstChild; c != nil; c = c.NextSibling { - nForward++ - if nForward == 1e6 { - return fmt.Errorf("html: forward list of children looks like an infinite loop") - } - if c.Parent != n { - return fmt.Errorf("html: inconsistent child/parent relationship") - } - } - - nBackward := 0 - for c := n.LastChild; c != nil; c = c.PrevSibling { - nBackward++ - if nBackward == 1e6 { - return fmt.Errorf("html: backward list of children looks like an infinite loop") - } - if c.Parent != n { - return fmt.Errorf("html: inconsistent child/parent relationship") - } - } - - if n.Parent != nil { - if n.Parent == n { - return fmt.Errorf("html: inconsistent parent relationship") - } - if n.Parent == n.FirstChild { - return fmt.Errorf("html: inconsistent parent/first relationship") - } - if n.Parent == n.LastChild { - return fmt.Errorf("html: inconsistent parent/last relationship") - } - if n.Parent == n.PrevSibling { - return fmt.Errorf("html: inconsistent parent/prev relationship") - } - if n.Parent == n.NextSibling { - return fmt.Errorf("html: inconsistent parent/next relationship") - } - - parentHasNAsAChild := false - for c := n.Parent.FirstChild; c != nil; c = c.NextSibling { - if c == n { - parentHasNAsAChild = true - break - } - } - if !parentHasNAsAChild { - return fmt.Errorf("html: inconsistent parent/child relationship") - } - } - - if n.PrevSibling != nil && n.PrevSibling.NextSibling != n { - return fmt.Errorf("html: inconsistent prev/next relationship") - } - if n.NextSibling != nil && n.NextSibling.PrevSibling != n { - return fmt.Errorf("html: inconsistent next/prev relationship") - } - - if (n.FirstChild == nil) != (n.LastChild == nil) { - return fmt.Errorf("html: inconsistent first/last relationship") - } - if n.FirstChild != nil && n.FirstChild == n.LastChild { - // We have a sole child. - if n.FirstChild.PrevSibling != nil || n.FirstChild.NextSibling != nil { - return fmt.Errorf("html: inconsistent sole child's sibling relationship") - } - } - - seen := map[*Node]bool{} - - var last *Node - for c := n.FirstChild; c != nil; c = c.NextSibling { - if seen[c] { - return fmt.Errorf("html: inconsistent repeated child") - } - seen[c] = true - last = c - } - if last != n.LastChild { - return fmt.Errorf("html: inconsistent last relationship") - } - - var first *Node - for c := n.LastChild; c != nil; c = c.PrevSibling { - if !seen[c] { - return fmt.Errorf("html: inconsistent missing child") - } - delete(seen, c) - first = c - } - if first != n.FirstChild { - return fmt.Errorf("html: inconsistent first relationship") - } - - if len(seen) != 0 { - return fmt.Errorf("html: inconsistent forwards/backwards child list") - } - - return nil -} diff --git a/_third_party/golang.org/x/net/html/parse.go b/_third_party/golang.org/x/net/html/parse.go deleted file mode 100644 index 9a19e02f..00000000 --- a/_third_party/golang.org/x/net/html/parse.go +++ /dev/null @@ -1,2094 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package html - -import ( - "errors" - "fmt" - "io" - "strings" - - a "github.com/mjibson/goread/_third_party/golang.org/x/net/html/atom" -) - -// A parser implements the HTML5 parsing algorithm: -// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction -type parser struct { - // tokenizer provides the tokens for the parser. - tokenizer *Tokenizer - // tok is the most recently read token. - tok Token - // Self-closing tags like
are treated as start tags, except that - // hasSelfClosingToken is set while they are being processed. - hasSelfClosingToken bool - // doc is the document root element. - doc *Node - // The stack of open elements (section 12.2.3.2) and active formatting - // elements (section 12.2.3.3). - oe, afe nodeStack - // Element pointers (section 12.2.3.4). - head, form *Node - // Other parsing state flags (section 12.2.3.5). - scripting, framesetOK bool - // im is the current insertion mode. - im insertionMode - // originalIM is the insertion mode to go back to after completing a text - // or inTableText insertion mode. - originalIM insertionMode - // fosterParenting is whether new elements should be inserted according to - // the foster parenting rules (section 12.2.5.3). - fosterParenting bool - // quirks is whether the parser is operating in "quirks mode." - quirks bool - // fragment is whether the parser is parsing an HTML fragment. - fragment bool - // context is the context element when parsing an HTML fragment - // (section 12.4). - context *Node -} - -func (p *parser) top() *Node { - if n := p.oe.top(); n != nil { - return n - } - return p.doc -} - -// Stop tags for use in popUntil. These come from section 12.2.3.2. -var ( - defaultScopeStopTags = map[string][]a.Atom{ - "": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template}, - "math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext}, - "svg": {a.Desc, a.ForeignObject, a.Title}, - } -) - -type scope int - -const ( - defaultScope scope = iota - listItemScope - buttonScope - tableScope - tableRowScope - tableBodyScope - selectScope -) - -// popUntil pops the stack of open elements at the highest element whose tag -// is in matchTags, provided there is no higher element in the scope's stop -// tags (as defined in section 12.2.3.2). It returns whether or not there was -// such an element. If there was not, popUntil leaves the stack unchanged. -// -// For example, the set of stop tags for table scope is: "html", "table". If -// the stack was: -// ["html", "body", "font", "table", "b", "i", "u"] -// then popUntil(tableScope, "font") would return false, but -// popUntil(tableScope, "i") would return true and the stack would become: -// ["html", "body", "font", "table", "b"] -// -// If an element's tag is in both the stop tags and matchTags, then the stack -// will be popped and the function returns true (provided, of course, there was -// no higher element in the stack that was also in the stop tags). For example, -// popUntil(tableScope, "table") returns true and leaves: -// ["html", "body", "font"] -func (p *parser) popUntil(s scope, matchTags ...a.Atom) bool { - if i := p.indexOfElementInScope(s, matchTags...); i != -1 { - p.oe = p.oe[:i] - return true - } - return false -} - -// indexOfElementInScope returns the index in p.oe of the highest element whose -// tag is in matchTags that is in scope. If no matching element is in scope, it -// returns -1. -func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { - for i := len(p.oe) - 1; i >= 0; i-- { - tagAtom := p.oe[i].DataAtom - if p.oe[i].Namespace == "" { - for _, t := range matchTags { - if t == tagAtom { - return i - } - } - switch s { - case defaultScope: - // No-op. - case listItemScope: - if tagAtom == a.Ol || tagAtom == a.Ul { - return -1 - } - case buttonScope: - if tagAtom == a.Button { - return -1 - } - case tableScope: - if tagAtom == a.Html || tagAtom == a.Table { - return -1 - } - case selectScope: - if tagAtom != a.Optgroup && tagAtom != a.Option { - return -1 - } - default: - panic("unreachable") - } - } - switch s { - case defaultScope, listItemScope, buttonScope: - for _, t := range defaultScopeStopTags[p.oe[i].Namespace] { - if t == tagAtom { - return -1 - } - } - } - } - return -1 -} - -// elementInScope is like popUntil, except that it doesn't modify the stack of -// open elements. -func (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool { - return p.indexOfElementInScope(s, matchTags...) != -1 -} - -// clearStackToContext pops elements off the stack of open elements until a -// scope-defined element is found. -func (p *parser) clearStackToContext(s scope) { - for i := len(p.oe) - 1; i >= 0; i-- { - tagAtom := p.oe[i].DataAtom - switch s { - case tableScope: - if tagAtom == a.Html || tagAtom == a.Table { - p.oe = p.oe[:i+1] - return - } - case tableRowScope: - if tagAtom == a.Html || tagAtom == a.Tr { - p.oe = p.oe[:i+1] - return - } - case tableBodyScope: - if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead { - p.oe = p.oe[:i+1] - return - } - default: - panic("unreachable") - } - } -} - -// generateImpliedEndTags pops nodes off the stack of open elements as long as -// the top node has a tag name of dd, dt, li, option, optgroup, p, rp, or rt. -// If exceptions are specified, nodes with that name will not be popped off. -func (p *parser) generateImpliedEndTags(exceptions ...string) { - var i int -loop: - for i = len(p.oe) - 1; i >= 0; i-- { - n := p.oe[i] - if n.Type == ElementNode { - switch n.DataAtom { - case a.Dd, a.Dt, a.Li, a.Option, a.Optgroup, a.P, a.Rp, a.Rt: - for _, except := range exceptions { - if n.Data == except { - break loop - } - } - continue - } - } - break - } - - p.oe = p.oe[:i+1] -} - -// addChild adds a child node n to the top element, and pushes n onto the stack -// of open elements if it is an element node. -func (p *parser) addChild(n *Node) { - if p.shouldFosterParent() { - p.fosterParent(n) - } else { - p.top().AppendChild(n) - } - - if n.Type == ElementNode { - p.oe = append(p.oe, n) - } -} - -// shouldFosterParent returns whether the next node to be added should be -// foster parented. -func (p *parser) shouldFosterParent() bool { - if p.fosterParenting { - switch p.top().DataAtom { - case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: - return true - } - } - return false -} - -// fosterParent adds a child node according to the foster parenting rules. -// Section 12.2.5.3, "foster parenting". -func (p *parser) fosterParent(n *Node) { - var table, parent, prev *Node - var i int - for i = len(p.oe) - 1; i >= 0; i-- { - if p.oe[i].DataAtom == a.Table { - table = p.oe[i] - break - } - } - - if table == nil { - // The foster parent is the html element. - parent = p.oe[0] - } else { - parent = table.Parent - } - if parent == nil { - parent = p.oe[i-1] - } - - if table != nil { - prev = table.PrevSibling - } else { - prev = parent.LastChild - } - if prev != nil && prev.Type == TextNode && n.Type == TextNode { - prev.Data += n.Data - return - } - - parent.InsertBefore(n, table) -} - -// addText adds text to the preceding node if it is a text node, or else it -// calls addChild with a new text node. -func (p *parser) addText(text string) { - if text == "" { - return - } - - if p.shouldFosterParent() { - p.fosterParent(&Node{ - Type: TextNode, - Data: text, - }) - return - } - - t := p.top() - if n := t.LastChild; n != nil && n.Type == TextNode { - n.Data += text - return - } - p.addChild(&Node{ - Type: TextNode, - Data: text, - }) -} - -// addElement adds a child element based on the current token. -func (p *parser) addElement() { - p.addChild(&Node{ - Type: ElementNode, - DataAtom: p.tok.DataAtom, - Data: p.tok.Data, - Attr: p.tok.Attr, - }) -} - -// Section 12.2.3.3. -func (p *parser) addFormattingElement() { - tagAtom, attr := p.tok.DataAtom, p.tok.Attr - p.addElement() - - // Implement the Noah's Ark clause, but with three per family instead of two. - identicalElements := 0 -findIdenticalElements: - for i := len(p.afe) - 1; i >= 0; i-- { - n := p.afe[i] - if n.Type == scopeMarkerNode { - break - } - if n.Type != ElementNode { - continue - } - if n.Namespace != "" { - continue - } - if n.DataAtom != tagAtom { - continue - } - if len(n.Attr) != len(attr) { - continue - } - compareAttributes: - for _, t0 := range n.Attr { - for _, t1 := range attr { - if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val { - // Found a match for this attribute, continue with the next attribute. - continue compareAttributes - } - } - // If we get here, there is no attribute that matches a. - // Therefore the element is not identical to the new one. - continue findIdenticalElements - } - - identicalElements++ - if identicalElements >= 3 { - p.afe.remove(n) - } - } - - p.afe = append(p.afe, p.top()) -} - -// Section 12.2.3.3. -func (p *parser) clearActiveFormattingElements() { - for { - n := p.afe.pop() - if len(p.afe) == 0 || n.Type == scopeMarkerNode { - return - } - } -} - -// Section 12.2.3.3. -func (p *parser) reconstructActiveFormattingElements() { - n := p.afe.top() - if n == nil { - return - } - if n.Type == scopeMarkerNode || p.oe.index(n) != -1 { - return - } - i := len(p.afe) - 1 - for n.Type != scopeMarkerNode && p.oe.index(n) == -1 { - if i == 0 { - i = -1 - break - } - i-- - n = p.afe[i] - } - for { - i++ - clone := p.afe[i].clone() - p.addChild(clone) - p.afe[i] = clone - if i == len(p.afe)-1 { - break - } - } -} - -// Section 12.2.4. -func (p *parser) acknowledgeSelfClosingTag() { - p.hasSelfClosingToken = false -} - -// An insertion mode (section 12.2.3.1) is the state transition function from -// a particular state in the HTML5 parser's state machine. It updates the -// parser's fields depending on parser.tok (where ErrorToken means EOF). -// It returns whether the token was consumed. -type insertionMode func(*parser) bool - -// setOriginalIM sets the insertion mode to return to after completing a text or -// inTableText insertion mode. -// Section 12.2.3.1, "using the rules for". -func (p *parser) setOriginalIM() { - if p.originalIM != nil { - panic("html: bad parser state: originalIM was set twice") - } - p.originalIM = p.im -} - -// Section 12.2.3.1, "reset the insertion mode". -func (p *parser) resetInsertionMode() { - for i := len(p.oe) - 1; i >= 0; i-- { - n := p.oe[i] - if i == 0 && p.context != nil { - n = p.context - } - - switch n.DataAtom { - case a.Select: - p.im = inSelectIM - case a.Td, a.Th: - p.im = inCellIM - case a.Tr: - p.im = inRowIM - case a.Tbody, a.Thead, a.Tfoot: - p.im = inTableBodyIM - case a.Caption: - p.im = inCaptionIM - case a.Colgroup: - p.im = inColumnGroupIM - case a.Table: - p.im = inTableIM - case a.Head: - p.im = inBodyIM - case a.Body: - p.im = inBodyIM - case a.Frameset: - p.im = inFramesetIM - case a.Html: - p.im = beforeHeadIM - default: - continue - } - return - } - p.im = inBodyIM -} - -const whitespace = " \t\r\n\f" - -// Section 12.2.5.4.1. -func initialIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case CommentToken: - p.doc.AppendChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - n, quirks := parseDoctype(p.tok.Data) - p.doc.AppendChild(n) - p.quirks = quirks - p.im = beforeHTMLIM - return true - } - p.quirks = true - p.im = beforeHTMLIM - return false -} - -// Section 12.2.5.4.2. -func beforeHTMLIM(p *parser) bool { - switch p.tok.Type { - case DoctypeToken: - // Ignore the token. - return true - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case StartTagToken: - if p.tok.DataAtom == a.Html { - p.addElement() - p.im = beforeHeadIM - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head, a.Body, a.Html, a.Br: - p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.doc.AppendChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - } - p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) - return false -} - -// Section 12.2.5.4.3. -func beforeHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Head: - p.addElement() - p.head = p.top() - p.im = inHeadIM - return true - case a.Html: - return inBodyIM(p) - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head, a.Body, a.Html, a.Br: - p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) - return false -} - -// Section 12.2.5.4.4. -func inHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - s := strings.TrimLeft(p.tok.Data, whitespace) - if len(s) < len(p.tok.Data) { - // Add the initial whitespace to the current node. - p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) - if s == "" { - return true - } - p.tok.Data = s - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Html: - return inBodyIM(p) - case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta: - p.addElement() - p.oe.pop() - p.acknowledgeSelfClosingTag() - return true - case a.Script, a.Title, a.Noscript, a.Noframes, a.Style: - p.addElement() - p.setOriginalIM() - p.im = textIM - return true - case a.Head: - // Ignore the token. - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head: - n := p.oe.pop() - if n.DataAtom != a.Head { - panic("html: bad parser state: element not found, in the in-head insertion mode") - } - p.im = afterHeadIM - return true - case a.Body, a.Html, a.Br: - p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) - return false -} - -// Section 12.2.5.4.6. -func afterHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - s := strings.TrimLeft(p.tok.Data, whitespace) - if len(s) < len(p.tok.Data) { - // Add the initial whitespace to the current node. - p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) - if s == "" { - return true - } - p.tok.Data = s - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Html: - return inBodyIM(p) - case a.Body: - p.addElement() - p.framesetOK = false - p.im = inBodyIM - return true - case a.Frameset: - p.addElement() - p.im = inFramesetIM - return true - case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title: - p.oe = append(p.oe, p.head) - defer p.oe.remove(p.head) - return inHeadIM(p) - case a.Head: - // Ignore the token. - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Body, a.Html, a.Br: - // Drop down to creating an implied tag. - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(StartTagToken, a.Body, a.Body.String()) - p.framesetOK = true - return false -} - -// copyAttributes copies attributes of src not found on dst to dst. -func copyAttributes(dst *Node, src Token) { - if len(src.Attr) == 0 { - return - } - attr := map[string]string{} - for _, t := range dst.Attr { - attr[t.Key] = t.Val - } - for _, t := range src.Attr { - if _, ok := attr[t.Key]; !ok { - dst.Attr = append(dst.Attr, t) - attr[t.Key] = t.Val - } - } -} - -// Section 12.2.5.4.7. -func inBodyIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - d := p.tok.Data - switch n := p.oe.top(); n.DataAtom { - case a.Pre, a.Listing: - if n.FirstChild == nil { - // Ignore a newline at the start of a
 block.
-				if d != "" && d[0] == '\r' {
-					d = d[1:]
-				}
-				if d != "" && d[0] == '\n' {
-					d = d[1:]
-				}
-			}
-		}
-		d = strings.Replace(d, "\x00", "", -1)
-		if d == "" {
-			return true
-		}
-		p.reconstructActiveFormattingElements()
-		p.addText(d)
-		if p.framesetOK && strings.TrimLeft(d, whitespace) != "" {
-			// There were non-whitespace characters inserted.
-			p.framesetOK = false
-		}
-	case StartTagToken:
-		switch p.tok.DataAtom {
-		case a.Html:
-			copyAttributes(p.oe[0], p.tok)
-		case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
-			return inHeadIM(p)
-		case a.Body:
-			if len(p.oe) >= 2 {
-				body := p.oe[1]
-				if body.Type == ElementNode && body.DataAtom == a.Body {
-					p.framesetOK = false
-					copyAttributes(body, p.tok)
-				}
-			}
-		case a.Frameset:
-			if !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {
-				// Ignore the token.
-				return true
-			}
-			body := p.oe[1]
-			if body.Parent != nil {
-				body.Parent.RemoveChild(body)
-			}
-			p.oe = p.oe[:1]
-			p.addElement()
-			p.im = inFramesetIM
-			return true
-		case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-			p.popUntil(buttonScope, a.P)
-			switch n := p.top(); n.DataAtom {
-			case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-				p.oe.pop()
-			}
-			p.addElement()
-		case a.Pre, a.Listing:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-			// The newline, if any, will be dealt with by the TextToken case.
-			p.framesetOK = false
-		case a.Form:
-			if p.form == nil {
-				p.popUntil(buttonScope, a.P)
-				p.addElement()
-				p.form = p.top()
-			}
-		case a.Li:
-			p.framesetOK = false
-			for i := len(p.oe) - 1; i >= 0; i-- {
-				node := p.oe[i]
-				switch node.DataAtom {
-				case a.Li:
-					p.oe = p.oe[:i]
-				case a.Address, a.Div, a.P:
-					continue
-				default:
-					if !isSpecialElement(node) {
-						continue
-					}
-				}
-				break
-			}
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Dd, a.Dt:
-			p.framesetOK = false
-			for i := len(p.oe) - 1; i >= 0; i-- {
-				node := p.oe[i]
-				switch node.DataAtom {
-				case a.Dd, a.Dt:
-					p.oe = p.oe[:i]
-				case a.Address, a.Div, a.P:
-					continue
-				default:
-					if !isSpecialElement(node) {
-						continue
-					}
-				}
-				break
-			}
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Plaintext:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Button:
-			p.popUntil(defaultScope, a.Button)
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.framesetOK = false
-		case a.A:
-			for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
-				if n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {
-					p.inBodyEndTagFormatting(a.A)
-					p.oe.remove(n)
-					p.afe.remove(n)
-					break
-				}
-			}
-			p.reconstructActiveFormattingElements()
-			p.addFormattingElement()
-		case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
-			p.reconstructActiveFormattingElements()
-			p.addFormattingElement()
-		case a.Nobr:
-			p.reconstructActiveFormattingElements()
-			if p.elementInScope(defaultScope, a.Nobr) {
-				p.inBodyEndTagFormatting(a.Nobr)
-				p.reconstructActiveFormattingElements()
-			}
-			p.addFormattingElement()
-		case a.Applet, a.Marquee, a.Object:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.afe = append(p.afe, &scopeMarker)
-			p.framesetOK = false
-		case a.Table:
-			if !p.quirks {
-				p.popUntil(buttonScope, a.P)
-			}
-			p.addElement()
-			p.framesetOK = false
-			p.im = inTableIM
-			return true
-		case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-			if p.tok.DataAtom == a.Input {
-				for _, t := range p.tok.Attr {
-					if t.Key == "type" {
-						if strings.ToLower(t.Val) == "hidden" {
-							// Skip setting framesetOK = false
-							return true
-						}
-					}
-				}
-			}
-			p.framesetOK = false
-		case a.Param, a.Source, a.Track:
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-		case a.Hr:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-			p.framesetOK = false
-		case a.Image:
-			p.tok.DataAtom = a.Img
-			p.tok.Data = a.Img.String()
-			return false
-		case a.Isindex:
-			if p.form != nil {
-				// Ignore the token.
-				return true
-			}
-			action := ""
-			prompt := "This is a searchable index. Enter search keywords: "
-			attr := []Attribute{{Key: "name", Val: "isindex"}}
-			for _, t := range p.tok.Attr {
-				switch t.Key {
-				case "action":
-					action = t.Val
-				case "name":
-					// Ignore the attribute.
-				case "prompt":
-					prompt = t.Val
-				default:
-					attr = append(attr, t)
-				}
-			}
-			p.acknowledgeSelfClosingTag()
-			p.popUntil(buttonScope, a.P)
-			p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
-			if action != "" {
-				p.form.Attr = []Attribute{{Key: "action", Val: action}}
-			}
-			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
-			p.parseImpliedToken(StartTagToken, a.Label, a.Label.String())
-			p.addText(prompt)
-			p.addChild(&Node{
-				Type:     ElementNode,
-				DataAtom: a.Input,
-				Data:     a.Input.String(),
-				Attr:     attr,
-			})
-			p.oe.pop()
-			p.parseImpliedToken(EndTagToken, a.Label, a.Label.String())
-			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
-			p.parseImpliedToken(EndTagToken, a.Form, a.Form.String())
-		case a.Textarea:
-			p.addElement()
-			p.setOriginalIM()
-			p.framesetOK = false
-			p.im = textIM
-		case a.Xmp:
-			p.popUntil(buttonScope, a.P)
-			p.reconstructActiveFormattingElements()
-			p.framesetOK = false
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Iframe:
-			p.framesetOK = false
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Noembed, a.Noscript:
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Select:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.framesetOK = false
-			p.im = inSelectIM
-			return true
-		case a.Optgroup, a.Option:
-			if p.top().DataAtom == a.Option {
-				p.oe.pop()
-			}
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-		case a.Rp, a.Rt:
-			if p.elementInScope(defaultScope, a.Ruby) {
-				p.generateImpliedEndTags()
-			}
-			p.addElement()
-		case a.Math, a.Svg:
-			p.reconstructActiveFormattingElements()
-			if p.tok.DataAtom == a.Math {
-				adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
-			} else {
-				adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
-			}
-			adjustForeignAttributes(p.tok.Attr)
-			p.addElement()
-			p.top().Namespace = p.tok.Data
-			if p.hasSelfClosingToken {
-				p.oe.pop()
-				p.acknowledgeSelfClosingTag()
-			}
-			return true
-		case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
-			// Ignore the token.
-		default:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-		}
-	case EndTagToken:
-		switch p.tok.DataAtom {
-		case a.Body:
-			if p.elementInScope(defaultScope, a.Body) {
-				p.im = afterBodyIM
-			}
-		case a.Html:
-			if p.elementInScope(defaultScope, a.Body) {
-				p.parseImpliedToken(EndTagToken, a.Body, a.Body.String())
-				return false
-			}
-			return true
-		case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
-			p.popUntil(defaultScope, p.tok.DataAtom)
-		case a.Form:
-			node := p.form
-			p.form = nil
-			i := p.indexOfElementInScope(defaultScope, a.Form)
-			if node == nil || i == -1 || p.oe[i] != node {
-				// Ignore the token.
-				return true
-			}
-			p.generateImpliedEndTags()
-			p.oe.remove(node)
-		case a.P:
-			if !p.elementInScope(buttonScope, a.P) {
-				p.parseImpliedToken(StartTagToken, a.P, a.P.String())
-			}
-			p.popUntil(buttonScope, a.P)
-		case a.Li:
-			p.popUntil(listItemScope, a.Li)
-		case a.Dd, a.Dt:
-			p.popUntil(defaultScope, p.tok.DataAtom)
-		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-			p.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)
-		case a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
-			p.inBodyEndTagFormatting(p.tok.DataAtom)
-		case a.Applet, a.Marquee, a.Object:
-			if p.popUntil(defaultScope, p.tok.DataAtom) {
-				p.clearActiveFormattingElements()
-			}
-		case a.Br:
-			p.tok.Type = StartTagToken
-			return false
-		default:
-			p.inBodyEndTagOther(p.tok.DataAtom)
-		}
-	case CommentToken:
-		p.addChild(&Node{
-			Type: CommentNode,
-			Data: p.tok.Data,
-		})
-	}
-
-	return true
-}
-
-func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
-	// This is the "adoption agency" algorithm, described at
-	// https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency
-
-	// TODO: this is a fairly literal line-by-line translation of that algorithm.
-	// Once the code successfully parses the comprehensive test suite, we should
-	// refactor this code to be more idiomatic.
-
-	// Steps 1-4. The outer loop.
-	for i := 0; i < 8; i++ {
-		// Step 5. Find the formatting element.
-		var formattingElement *Node
-		for j := len(p.afe) - 1; j >= 0; j-- {
-			if p.afe[j].Type == scopeMarkerNode {
-				break
-			}
-			if p.afe[j].DataAtom == tagAtom {
-				formattingElement = p.afe[j]
-				break
-			}
-		}
-		if formattingElement == nil {
-			p.inBodyEndTagOther(tagAtom)
-			return
-		}
-		feIndex := p.oe.index(formattingElement)
-		if feIndex == -1 {
-			p.afe.remove(formattingElement)
-			return
-		}
-		if !p.elementInScope(defaultScope, tagAtom) {
-			// Ignore the tag.
-			return
-		}
-
-		// Steps 9-10. Find the furthest block.
-		var furthestBlock *Node
-		for _, e := range p.oe[feIndex:] {
-			if isSpecialElement(e) {
-				furthestBlock = e
-				break
-			}
-		}
-		if furthestBlock == nil {
-			e := p.oe.pop()
-			for e != formattingElement {
-				e = p.oe.pop()
-			}
-			p.afe.remove(e)
-			return
-		}
-
-		// Steps 11-12. Find the common ancestor and bookmark node.
-		commonAncestor := p.oe[feIndex-1]
-		bookmark := p.afe.index(formattingElement)
-
-		// Step 13. The inner loop. Find the lastNode to reparent.
-		lastNode := furthestBlock
-		node := furthestBlock
-		x := p.oe.index(node)
-		// Steps 13.1-13.2
-		for j := 0; j < 3; j++ {
-			// Step 13.3.
-			x--
-			node = p.oe[x]
-			// Step 13.4 - 13.5.
-			if p.afe.index(node) == -1 {
-				p.oe.remove(node)
-				continue
-			}
-			// Step 13.6.
-			if node == formattingElement {
-				break
-			}
-			// Step 13.7.
-			clone := node.clone()
-			p.afe[p.afe.index(node)] = clone
-			p.oe[p.oe.index(node)] = clone
-			node = clone
-			// Step 13.8.
-			if lastNode == furthestBlock {
-				bookmark = p.afe.index(node) + 1
-			}
-			// Step 13.9.
-			if lastNode.Parent != nil {
-				lastNode.Parent.RemoveChild(lastNode)
-			}
-			node.AppendChild(lastNode)
-			// Step 13.10.
-			lastNode = node
-		}
-
-		// Step 14. Reparent lastNode to the common ancestor,
-		// or for misnested table nodes, to the foster parent.
-		if lastNode.Parent != nil {
-			lastNode.Parent.RemoveChild(lastNode)
-		}
-		switch commonAncestor.DataAtom {
-		case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
-			p.fosterParent(lastNode)
-		default:
-			commonAncestor.AppendChild(lastNode)
-		}
-
-		// Steps 15-17. Reparent nodes from the furthest block's children
-		// to a clone of the formatting element.
-		clone := formattingElement.clone()
-		reparentChildren(clone, furthestBlock)
-		furthestBlock.AppendChild(clone)
-
-		// Step 18. Fix up the list of active formatting elements.
-		if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
-			// Move the bookmark with the rest of the list.
-			bookmark--
-		}
-		p.afe.remove(formattingElement)
-		p.afe.insert(bookmark, clone)
-
-		// Step 19. Fix up the stack of open elements.
-		p.oe.remove(formattingElement)
-		p.oe.insert(p.oe.index(furthestBlock)+1, clone)
-	}
-}
-
-// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
-// "Any other end tag" handling from 12.2.5.5 The rules for parsing tokens in foreign content
-// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign
-func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
-	for i := len(p.oe) - 1; i >= 0; i-- {
-		if p.oe[i].DataAtom == tagAtom {
-			p.oe = p.oe[:i]
-			break
-		}
-		if isSpecialElement(p.oe[i]) {
-			break
-		}
-	}
-}
-
-// Section 12.2.5.4.8.
-func textIM(p *parser) bool {
-	switch p.tok.Type {
-	case ErrorToken:
-		p.oe.pop()
-	case TextToken:
-		d := p.tok.Data
-		if n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil {
-			// Ignore a newline at the start of a ",
-		"",
-	},
-	{
-		"title with tag and entity",
-		"<b>K&R C</b>",
-		"$<b>K&R C</b>$",
-	},
-	// DOCTYPE tests.
-	{
-		"Proper DOCTYPE",
-		"",
-		"",
-	},
-	{
-		"DOCTYPE with no space",
-		"",
-		"",
-	},
-	{
-		"DOCTYPE with two spaces",
-		"",
-		"",
-	},
-	{
-		"looks like DOCTYPE but isn't",
-		"",
-		"",
-	},
-	{
-		"DOCTYPE at EOF",
-		"",
-	},
-	// XML processing instructions.
-	{
-		"XML processing instruction",
-		"",
-		"",
-	},
-	// Comments.
-	{
-		"comment0",
-		"abcdef",
-		"abc$$$$def",
-	},
-	{
-		"comment1",
-		"az",
-		"a$$z",
-	},
-	{
-		"comment2",
-		"az",
-		"a$$z",
-	},
-	{
-		"comment3",
-		"az",
-		"a$$z",
-	},
-	{
-		"comment4",
-		"az",
-		"a$$z",
-	},
-	{
-		"comment5",
-		"az",
-		"a$$z",
-	},
-	{
-		"comment6",
-		"az",
-		"a$$z",
-	},
-	{
-		"comment7",
-		"a",
-	},
-	{
-		"comment8",
-		"a",
-	},
-	{
-		"comment9",
-		"a",
-	},
-	{
-		"comment10",
-		"a",
-	},
-	{
-		"comment11",
-		"a",
-	},
-	{
-		"comment12",
-		"a",
-	},
-	{
-		"comment13",
-		"az",
-		"a$$z",
-	},
-	// An attribute with a backslash.
-	{
-		"backslash",
-		`

`, - `

`, - }, - // Entities, tag name and attribute key lower-casing, and whitespace - // normalization within a tag. - { - "tricky", - "

te<&;xt

", - `

$$te<&;xt$$

`, - }, - // A nonexistent entity. Tokenizing and converting back to a string should - // escape the "&" to become "&". - { - "noSuchEntity", - `<&alsoDoesntExist;&`, - `$<&alsoDoesntExist;&`, - }, - { - "entity without semicolon", - `¬it;∉`, - `¬it;∉$`, - }, - { - "entity with digits", - "½", - "½", - }, - // Attribute tests: - // http://dev.w3.org/html5/pf-summary/Overview.html#attributes - { - "Empty attribute", - ``, - ``, - }, - { - "Empty attribute, whitespace", - ``, - ``, - }, - { - "Unquoted attribute value", - ``, - ``, - }, - { - "Unquoted attribute value, spaces", - ``, - ``, - }, - { - "Unquoted attribute value, trailing space", - ``, - ``, - }, - { - "Single-quoted attribute value", - ``, - ``, - }, - { - "Single-quoted attribute value, trailing space", - ``, - ``, - }, - { - "Double-quoted attribute value", - ``, - ``, - }, - { - "Attribute name characters", - ``, - ``, - }, - { - "Mixed attributes", - `a

z`, - `a$

$z`, - }, - { - "Attributes with a solitary single quote", - `

`, - `

$

`, - }, -} - -func TestTokenizer(t *testing.T) { -loop: - for _, tt := range tokenTests { - z := NewTokenizer(strings.NewReader(tt.html)) - if tt.golden != "" { - for i, s := range strings.Split(tt.golden, "$") { - if z.Next() == ErrorToken { - t.Errorf("%s token %d: want %q got error %v", tt.desc, i, s, z.Err()) - continue loop - } - actual := z.Token().String() - if s != actual { - t.Errorf("%s token %d: want %q got %q", tt.desc, i, s, actual) - continue loop - } - } - } - z.Next() - if z.Err() != io.EOF { - t.Errorf("%s: want EOF got %q", tt.desc, z.Err()) - } - } -} - -func TestMaxBuffer(t *testing.T) { - // Exceeding the maximum buffer size generates ErrBufferExceeded. - z := NewTokenizer(strings.NewReader("<" + strings.Repeat("t", 10))) - z.SetMaxBuf(5) - tt := z.Next() - if got, want := tt, ErrorToken; got != want { - t.Fatalf("token type: got: %v want: %v", got, want) - } - if got, want := z.Err(), ErrBufferExceeded; got != want { - t.Errorf("error type: got: %v want: %v", got, want) - } - if got, want := string(z.Raw()), " 0 { - result.Write(z.Text()) - } - case StartTagToken, EndTagToken: - tn, _ := z.TagName() - if len(tn) == 1 && tn[0] == 'a' { - if tt == StartTagToken { - depth++ - } else { - depth-- - } - } - } - } - u := "14567" - v := string(result.Bytes()) - if u != v { - t.Errorf("TestBufAPI: want %q got %q", u, v) - } -} - -func TestConvertNewlines(t *testing.T) { - testCases := map[string]string{ - "Mac\rDOS\r\nUnix\n": "Mac\nDOS\nUnix\n", - "Unix\nMac\rDOS\r\n": "Unix\nMac\nDOS\n", - "DOS\r\nDOS\r\nDOS\r\n": "DOS\nDOS\nDOS\n", - "": "", - "\n": "\n", - "\n\r": "\n\n", - "\r": "\n", - "\r\n": "\n", - "\r\n\n": "\n\n", - "\r\n\r": "\n\n", - "\r\n\r\n": "\n\n", - "\r\r": "\n\n", - "\r\r\n": "\n\n", - "\r\r\n\n": "\n\n\n", - "\r\r\r\n": "\n\n\n", - "\r \n": "\n \n", - "xyz": "xyz", - } - for in, want := range testCases { - if got := string(convertNewlines([]byte(in))); got != want { - t.Errorf("input %q: got %q, want %q", in, got, want) - } - } -} - -func TestReaderEdgeCases(t *testing.T) { - const s = "

An io.Reader can return (0, nil) or (n, io.EOF).

" - testCases := []io.Reader{ - &zeroOneByteReader{s: s}, - &eofStringsReader{s: s}, - &stuckReader{}, - } - for i, tc := range testCases { - got := []TokenType{} - z := NewTokenizer(tc) - for { - tt := z.Next() - if tt == ErrorToken { - break - } - got = append(got, tt) - } - if err := z.Err(); err != nil && err != io.EOF { - if err != io.ErrNoProgress { - t.Errorf("i=%d: %v", i, err) - } - continue - } - want := []TokenType{ - StartTagToken, - TextToken, - EndTagToken, - } - if !reflect.DeepEqual(got, want) { - t.Errorf("i=%d: got %v, want %v", i, got, want) - continue - } - } -} - -// zeroOneByteReader is like a strings.Reader that alternates between -// returning 0 bytes and 1 byte at a time. -type zeroOneByteReader struct { - s string - n int -} - -func (r *zeroOneByteReader) Read(p []byte) (int, error) { - if len(p) == 0 { - return 0, nil - } - if len(r.s) == 0 { - return 0, io.EOF - } - r.n++ - if r.n%2 != 0 { - return 0, nil - } - p[0], r.s = r.s[0], r.s[1:] - return 1, nil -} - -// eofStringsReader is like a strings.Reader but can return an (n, err) where -// n > 0 && err != nil. -type eofStringsReader struct { - s string -} - -func (r *eofStringsReader) Read(p []byte) (int, error) { - n := copy(p, r.s) - r.s = r.s[n:] - if r.s != "" { - return n, nil - } - return n, io.EOF -} - -// stuckReader is an io.Reader that always returns no data and no error. -type stuckReader struct{} - -func (*stuckReader) Read(p []byte) (int, error) { - return 0, nil -} - -const ( - rawLevel = iota - lowLevel - highLevel -) - -func benchmarkTokenizer(b *testing.B, level int) { - buf, err := ioutil.ReadFile("testdata/go1.html") - if err != nil { - b.Fatalf("could not read testdata/go1.html: %v", err) - } - b.SetBytes(int64(len(buf))) - runtime.GC() - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - z := NewTokenizer(bytes.NewBuffer(buf)) - for { - tt := z.Next() - if tt == ErrorToken { - if err := z.Err(); err != nil && err != io.EOF { - b.Fatalf("tokenizer error: %v", err) - } - break - } - switch level { - case rawLevel: - // Calling z.Raw just returns the raw bytes of the token. It does - // not unescape < to <, or lower-case tag names and attribute keys. - z.Raw() - case lowLevel: - // Caling z.Text, z.TagName and z.TagAttr returns []byte values - // whose contents may change on the next call to z.Next. - switch tt { - case TextToken, CommentToken, DoctypeToken: - z.Text() - case StartTagToken, SelfClosingTagToken: - _, more := z.TagName() - for more { - _, _, more = z.TagAttr() - } - case EndTagToken: - z.TagName() - } - case highLevel: - // Calling z.Token converts []byte values to strings whose validity - // extend beyond the next call to z.Next. - z.Token() - } - } - } -} - -func BenchmarkRawLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, rawLevel) } -func BenchmarkLowLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, lowLevel) } -func BenchmarkHighLevelTokenizer(b *testing.B) { benchmarkTokenizer(b, highLevel) } diff --git a/_third_party/golang.org/x/text/cldr/base.go b/_third_party/golang.org/x/text/cldr/base.go deleted file mode 100644 index 21821791..00000000 --- a/_third_party/golang.org/x/text/cldr/base.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cldr provides a parser for LDML and related XML formats. -// This package is inteded to be used by the table generation tools -// for the various internationalization-related packages. -// As the XML types are generated from the CLDR DTD, and as the CLDR standard -// is periodically amended, this package may change considerably over time. -// This mostly means that data may appear and disappear between versions. -// That is, old code should keep compiling for newer versions, but data -// may have moved or changed. -// CLDR version 22 is the first version supported by this package. -// Older versions may not work. -package cldr - -import ( - "encoding/xml" - "regexp" - "strconv" -) - -// Elem is implemented by every XML element. -type Elem interface { - setEnclosing(Elem) - setName(string) - enclosing() Elem - - GetCommon() *Common -} - -type hidden struct { - CharData string `xml:",chardata"` - Alias *struct { - Common - Source string `xml:"source,attr"` - Path string `xml:"path,attr"` - } `xml:"alias"` - Def *struct { - Common - Choice string `xml:"choice,attr,omitempty"` - Type string `xml:"type,attr,omitempty"` - } `xml:"default"` -} - -// Common holds several of the most common attributes and sub elements -// of an XML element. -type Common struct { - XMLName xml.Name - name string - enclElem Elem - Type string `xml:"type,attr,omitempty"` - Reference string `xml:"reference,attr,omitempty"` - Alt string `xml:"alt,attr,omitempty"` - ValidSubLocales string `xml:"validSubLocales,attr,omitempty"` - Draft string `xml:"draft,attr,omitempty"` - hidden -} - -// Default returns the default type to select from the enclosed list -// or "" if no default value is specified. -func (e *Common) Default() string { - if e.Def == nil { - return "" - } - if e.Def.Choice != "" { - return e.Def.Choice - } else if e.Def.Type != "" { - // Type is still used by the default element in collation. - return e.Def.Type - } - return "" -} - -// GetCommon returns e. It is provided such that Common implements Elem. -func (e *Common) GetCommon() *Common { - return e -} - -// Data returns the character data accumulated for this element. -func (e *Common) Data() string { - e.CharData = charRe.ReplaceAllStringFunc(e.CharData, replaceUnicode) - return e.CharData -} - -func (e *Common) setName(s string) { - e.name = s -} - -func (e *Common) enclosing() Elem { - return e.enclElem -} - -func (e *Common) setEnclosing(en Elem) { - e.enclElem = en -} - -// Escape characters that can be escaped without further escaping the string. -var charRe = regexp.MustCompile(`&#x[0-9a-fA-F]*;|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\[abtnvfr]`) - -// replaceUnicode converts hexadecimal Unicode codepoint notations to a one-rune string. -// It assumes the input string is correctly formatted. -func replaceUnicode(s string) string { - if s[1] == '#' { - r, _ := strconv.ParseInt(s[3:len(s)-1], 16, 32) - return string(r) - } - r, _, _, _ := strconv.UnquoteChar(s, 0) - return string(r) -} diff --git a/_third_party/golang.org/x/text/cldr/cldr.go b/_third_party/golang.org/x/text/cldr/cldr.go deleted file mode 100644 index f5221161..00000000 --- a/_third_party/golang.org/x/text/cldr/cldr.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run makexml.go -output xml.go - -// Package cldr provides a parser for LDML and related XML formats. -// This package is inteded to be used by the table generation tools -// for the various internationalization-related packages. -// As the XML types are generated from the CLDR DTD, and as the CLDR standard -// is periodically amended, this package may change considerably over time. -// This mostly means that data may appear and disappear between versions. -// That is, old code should keep compiling for newer versions, but data -// may have moved or changed. -// CLDR version 22 is the first version supported by this package. -// Older versions may not work. -package cldr // import "github.com/mjibson/goread/_third_party/golang.org/x/text/cldr" - -import ( - "fmt" - "sort" -) - -// CLDR provides access to parsed data of the Unicode Common Locale Data Repository. -type CLDR struct { - parent map[string][]string - locale map[string]*LDML - resolved map[string]*LDML - bcp47 *LDMLBCP47 - supp *SupplementalData -} - -func makeCLDR() *CLDR { - return &CLDR{ - parent: make(map[string][]string), - locale: make(map[string]*LDML), - resolved: make(map[string]*LDML), - bcp47: &LDMLBCP47{}, - supp: &SupplementalData{}, - } -} - -// BCP47 returns the parsed BCP47 LDML data. If no such data was parsed, nil is returned. -func (cldr *CLDR) BCP47() *LDMLBCP47 { - return nil -} - -// Draft indicates the draft level of an element. -type Draft int - -const ( - Approved Draft = iota - Contributed - Provisional - Unconfirmed -) - -var drafts = []string{"unconfirmed", "provisional", "contributed", "approved", ""} - -// ParseDraft returns the Draft value corresponding to the given string. The -// empty string corresponds to Approved. -func ParseDraft(level string) (Draft, error) { - if level == "" { - return Approved, nil - } - for i, s := range drafts { - if level == s { - return Unconfirmed - Draft(i), nil - } - } - return Approved, fmt.Errorf("cldr: unknown draft level %q", level) -} - -func (d Draft) String() string { - return drafts[len(drafts)-1-int(d)] -} - -// SetDraftLevel sets which draft levels to include in the evaluated LDML. -// Any draft element for which the draft level is higher than lev will be excluded. -// If multiple draft levels are available for a single element, the one with the -// lowest draft level will be selected, unless preferDraft is true, in which case -// the highest draft will be chosen. -// It is assumed that the underlying LDML is canonicalized. -func (cldr *CLDR) SetDraftLevel(lev Draft, preferDraft bool) { - // TODO: implement - cldr.resolved = make(map[string]*LDML) -} - -// RawLDML returns the LDML XML for id in unresolved form. -// id must be one of the strings returned by Locales. -func (cldr *CLDR) RawLDML(loc string) *LDML { - return cldr.locale[loc] -} - -// LDML returns the fully resolved LDML XML for loc, which must be one of -// the strings returned by Locales. -func (cldr *CLDR) LDML(loc string) (*LDML, error) { - return cldr.resolve(loc) -} - -// Supplemental returns the parsed supplemental data. If no such data was parsed, -// nil is returned. -func (cldr *CLDR) Supplemental() *SupplementalData { - return cldr.supp -} - -// Locales returns the locales for which there exist files. -// Valid sublocales for which there is no file are not included. -func (cldr *CLDR) Locales() []string { - loc := []string{} - for l, _ := range cldr.locale { - loc = append(loc, l) - } - sort.Strings(loc) - return loc -} - -// Get fills in the fields of x based on the XPath path. -func Get(e Elem, path string) (res Elem, err error) { - return walkXPath(e, path) -} diff --git a/_third_party/golang.org/x/text/cldr/cldr_test.go b/_third_party/golang.org/x/text/cldr/cldr_test.go deleted file mode 100644 index 951028d7..00000000 --- a/_third_party/golang.org/x/text/cldr/cldr_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cldr - -import "testing" - -func TestParseDraft(t *testing.T) { - tests := []struct { - in string - draft Draft - err bool - }{ - {"unconfirmed", Unconfirmed, false}, - {"provisional", Provisional, false}, - {"contributed", Contributed, false}, - {"approved", Approved, false}, - {"", Approved, false}, - {"foo", Approved, true}, - } - for _, tt := range tests { - if d, err := ParseDraft(tt.in); d != tt.draft || (err != nil) != tt.err { - t.Errorf("%q: was %v, %v; want %v, %v", tt.in, d, err != nil, tt.draft, tt.err) - } - } -} diff --git a/_third_party/golang.org/x/text/cldr/collate.go b/_third_party/golang.org/x/text/cldr/collate.go deleted file mode 100644 index 80ee28d7..00000000 --- a/_third_party/golang.org/x/text/cldr/collate.go +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cldr - -import ( - "bufio" - "encoding/xml" - "errors" - "fmt" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -// RuleProcessor can be passed to Collator's Process method, which -// parses the rules and calls the respective method for each rule found. -type RuleProcessor interface { - Reset(anchor string, before int) error - Insert(level int, str, context, extend string) error - Index(id string) -} - -const ( - // cldrIndex is a Unicode-reserved sentinel value used to mark the start - // of a grouping within an index. - // We ignore any rule that starts with this rune. - // See http://unicode.org/reports/tr35/#Collation_Elements for details. - cldrIndex = "\uFDD0" - - // specialAnchor is the format in which to represent logical reset positions, - // such as "first tertiary ignorable". - specialAnchor = "<%s/>" -) - -// Process parses the rules for the tailorings of this collation -// and calls the respective methods of p for each rule found. -func (c Collation) Process(p RuleProcessor) (err error) { - if len(c.Cr) > 0 { - if len(c.Cr) > 1 { - return fmt.Errorf("multiple cr elements, want 0 or 1") - } - return processRules(p, c.Cr[0].Data()) - } - if c.Rules.Any != nil { - return c.processXML(p) - } - return errors.New("no tailoring data") -} - -// processRules parses rules in the Collation Rule Syntax defined in -// http://www.unicode.org/reports/tr35/tr35-collation.html#Collation_Tailorings. -func processRules(p RuleProcessor, s string) (err error) { - chk := func(s string, e error) string { - if err == nil { - err = e - } - return s - } - i := 0 // Save the line number for use after the loop. - scanner := bufio.NewScanner(strings.NewReader(s)) - for ; scanner.Scan() && err == nil; i++ { - for s := skipSpace(scanner.Text()); s != "" && s[0] != '#'; s = skipSpace(s) { - level := 5 - var ch byte - switch ch, s = s[0], s[1:]; ch { - case '&': // followed by or '[' ']' - if s = skipSpace(s); consume(&s, '[') { - s = chk(parseSpecialAnchor(p, s)) - } else { - s = chk(parseAnchor(p, 0, s)) - } - case '<': // sort relation '<'{1,4}, optionally followed by '*'. - for level = 1; consume(&s, '<'); level++ { - } - if level > 4 { - err = fmt.Errorf("level %d > 4", level) - } - fallthrough - case '=': // identity relation, optionally followed by *. - if consume(&s, '*') { - s = chk(parseSequence(p, level, s)) - } else { - s = chk(parseOrder(p, level, s)) - } - default: - chk("", fmt.Errorf("illegal operator %q", ch)) - break - } - } - } - if chk("", scanner.Err()); err != nil { - return fmt.Errorf("%d: %v", i, err) - } - return nil -} - -// parseSpecialAnchor parses the anchor syntax which is either of the form -// ['before' ] -// or -// [